Package modules :: Package machinery :: Module vmware
[hide private]
[frames] | no frames]

Source Code for Module modules.machinery.vmware

  1  # Copyright (C) 2010-2014 Cuckoo Foundation. 
  2  # This file was originally produced by Mike Tu. 
  3  # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 
  4  # See the file 'docs/LICENSE' for copying permission. 
  5   
  6  import logging 
  7  import subprocess 
  8  import os.path 
  9  import time 
 10   
 11  from lib.cuckoo.common.abstracts import Machinery 
 12  from lib.cuckoo.common.exceptions import CuckooMachineError 
 13   
 14  log = logging.getLogger(__name__) 
 15   
16 -class VMware(Machinery):
17 """Virtualization layer for VMware Workstation using vmrun utility.""" 18
19 - def _initialize_check(self):
20 """Check for configuration file and vmware setup. 21 @raise CuckooMachineError: if configuration is missing or wrong. 22 """ 23 if not self.options.vmware.path: 24 raise CuckooMachineError("VMware vmrun path missing, " 25 "please add it to vmware.conf") 26 if not os.path.exists(self.options.vmware.path): 27 raise CuckooMachineError("VMware vmrun not found in " 28 "specified path %s" % 29 self.options.vmware.path) 30 # Consistency checks. 31 for machine in self.machines(): 32 host, snapshot = self._get_host_and_snapshot(machine.label) 33 self._check_vmx(host) 34 self._check_snapshot(host, snapshot) 35 # Base checks. 36 super(VMware, self)._initialize_check()
37
38 - def _check_vmx(self, host):
39 """Checks a vmx file 40 @param host: file path 41 @raise CuckooMachineError: if file not found or not ending with .vmx 42 """ 43 if not host.endswith(".vmx"): 44 raise CuckooMachineError("Wrong configuration: vm path not " 45 "ending with .vmx: %s)" % host) 46 if not os.path.exists(self.options.vmware.path): 47 raise CuckooMachineError("Vm file %s not found" % host)
48
49 - def _check_snapshot(self, host, snapshot):
50 """Checks snapshot existance. 51 @param host: file path 52 @param snapshot: snapshot name 53 @raise CuckooMachineError: if snapshot not found 54 """ 55 try: 56 p = subprocess.Popen([self.options.vmware.path, 57 "listSnapshots", host], 58 stdout=subprocess.PIPE, 59 stderr=subprocess.PIPE) 60 output, error = p.communicate() 61 if output: 62 if snapshot in output: 63 return True 64 else: 65 return False 66 else: 67 raise CuckooMachineError("Unable to get snapshot list for %s. " 68 "No output from " 69 "`vmrun listSnapshots`" % host) 70 except OSError as e: 71 raise CuckooMachineError("Unable to get snapshot list for %s. " 72 "Reason: %s" % (host, e))
73
74 - def start(self, label):
75 """Start a virtual machine. 76 @param label: virtual machine identifier: path to vmx file. 77 @raise CuckooMachineError: if unable to start. 78 """ 79 host, snapshot = self._get_host_and_snapshot(label) 80 81 # Preventive check 82 if self._is_running(host): 83 raise CuckooMachineError("Machine %s is already running" % host) 84 85 self._revert(host, snapshot) 86 87 time.sleep(3) 88 89 log.debug("Starting vm %s" % host) 90 try: 91 p = subprocess.Popen([self.options.vmware.path, 92 "start", host, self.options.vmware.mode], 93 stdout=subprocess.PIPE, 94 stderr=subprocess.PIPE) 95 if self.options.vmware.mode.lower() == "gui": 96 output, error = p.communicate() 97 if output: 98 raise CuckooMachineError("Unable to start machine " 99 "%s: %s" % (host, output)) 100 except OSError as e: 101 mode = self.options.vmware.mode.upper() 102 raise CuckooMachineError("Unable to start machine %s in %s " 103 "mode: %s" % (host, mode, e))
104
105 - def stop(self, label):
106 """Stops a virtual machine. 107 @param label: virtual machine identifier: path to vmx file 108 (in older configurations it also includes current snapshot name). 109 @raise CuckooMachineError: if unable to stop. 110 """ 111 host, snapshot = self._get_host_and_snapshot(label) 112 113 log.debug("Stopping vm %s" % host) 114 if self._is_running(host): 115 try: 116 if subprocess.call([self.options.vmware.path, 117 "stop", 118 host, 119 "hard"], # Machete never wait. 120 stdout=subprocess.PIPE, 121 stderr=subprocess.PIPE): 122 raise CuckooMachineError("Error shutting down " 123 "machine %s" % host) 124 except OSError as e: 125 raise CuckooMachineError("Error shutting down machine " 126 "%s: %s" % (host, e)) 127 else: 128 log.warning("Trying to stop an already stopped machine: %s" % host)
129
130 - def _revert(self, host, snapshot):
131 """Revets machine to snapshot. 132 @param host: file path 133 @param snapshot: snapshot name 134 @raise CuckooMachineError: if unable to revert 135 """ 136 log.debug("Revert snapshot for vm %s" % host) 137 try: 138 if subprocess.call([self.options.vmware.path, 139 "revertToSnapshot", 140 host, 141 snapshot], 142 stdout=subprocess.PIPE, 143 stderr=subprocess.PIPE): 144 raise CuckooMachineError("Unable to revert snapshot for " 145 "machine %s: vmrun exited with " 146 "error" % host) 147 except OSError as e: 148 raise CuckooMachineError("Unable to revert snapshot for " 149 "machine %s: %s" % (host, e))
150
151 - def _is_running(self, host):
152 """Checks if host is running. 153 @param host: file path 154 @return: running status 155 """ 156 try: 157 p = subprocess.Popen([self.options.vmware.path, "list"], 158 stdout=subprocess.PIPE, 159 stderr=subprocess.PIPE) 160 output, error = p.communicate() 161 if output: 162 if host in output: 163 return True 164 else: 165 return False 166 else: 167 raise CuckooMachineError("Unable to check running status " 168 "for %s. No output from " 169 "`vmrun list`" % host) 170 except OSError as e: 171 raise CuckooMachineError("Unable to check running status for %s. " 172 "Reason: %s" % (host, e))
173
174 - def _parse_label(self, label):
175 """Parse configuration file label. 176 @param label: configuration option from config file 177 @return: tuple of host file path and snapshot name 178 """ 179 opts = label.strip().split(",") 180 if len(opts) != 2: 181 raise CuckooMachineError("Wrong label syntax for %s in " 182 "vmware.conf: %s" % label) 183 label = opts[0].strip() 184 snapshot = opts[1].strip() 185 return label, snapshot
186
187 - def _get_host_and_snapshot(self, label):
188 """Get host and snapshot for a given label 189 New configuration files have a specific 'snapshot' option, while 190 older configuration files have a label in the format: 191 'file.vmx,Snapshot'. 192 @param label: configuration option from config file 193 """ 194 vm_info = self.db.view_machine_by_label(label) 195 196 if vm_info.snapshot: 197 host = label.split(',')[0] 198 # Make sure to exclude any snapshot name from older conf files 199 # if you also have the new option parameter 200 snapshot = vm_info.snapshot 201 else: 202 # Keep support for older conf files 203 host, snapshot = self._parse_label(label) 204 log.warning("Deprecation warning: your vmware configuartion " 205 "file is using old snaphost syntax, please use the " 206 "option 'snapshot' instead.") 207 208 return host, snapshot
209