def save(self, arguments): """ Take a snapshot of the current state of the machine. Usage: mech snapshot save [options] <name> [<instance>] Notes: Take a snapshot of the current state of the machine. The snapshot can be restored via `mech snapshot restore` at any point in the future to get back to this exact machine state. Snapshots are useful for experimenting in a machine and being able to rollback quickly. Options: -f --force Replace snapshot without confirmation -h, --help Print this help """ name = arguments['<name>'] instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx, user=self.user, password=self.password) if vmrun.snapshot(name) is None: puts_err(colored.red("Cannot take snapshot")) else: puts_err(colored.green("Snapshot {} taken".format(name)))
def status(self, arguments): """ Outputs status of the mech machine. Usage: mech status [options] [<instance>] Options: -h, --help Print this help """ instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx) box_name = self.box_name ip = vmrun.getGuestIPAddress(wait=False, quiet=True) state = vmrun.checkToolsState(quiet=True) print("Current machine states:\n") if ip is None: ip = "poweroff" elif not ip: ip = "unknown" print("%s\t%s\t(VMware Tools %s)" % (box_name, ip, state)) if ip == "poweroff": print( "\nThe VM is powered off. To restart the VM, simply run `mech up`" ) elif ip == "unknown": print( "\nThe VM is on. but it has no IP to connect to, VMware Tools must be installed" ) elif state in ("installed", "running"): print("\nThe VM is ready. Connect to it using `mech ssh`")
def list(self, arguments): """ Lists all available boxes. Usage: mech list [options] Options: -h, --help Print this help """ for instance_name, instance in utils.instances().items(): path = instance.get('path') if path and os.path.exists(path): self.activate(instance_name) mech_path = os.path.join(path, '.mech') if os.path.exists(mech_path): vmrun = VMrun(self.vmx) ip = vmrun.getGuestIPAddress(wait=False, quiet=True) if ip is None: ip = "poweroff" elif not ip: ip = colored.green("running") else: ip = colored.green(ip) else: ip = "" print("{}\t{}\t{}\t{}\t{}".format( colored.green("%20s" % instance_name), "%15s" % ip, "%35s" % self.box_name, self.box_version, path, ))
def resume(self, arguments): """ Resume a paused/suspended Mech machine. Usage: mech resume [options] [<instance>] Options: --provision Enable provisioning -h, --help Print this help """ instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) utils.index_active_instance(instance_name) vmrun = VMrun(self.vmx, user=self.user, password=self.password) # Try to unpause if vmrun.unpause(quiet=True) is not None: time.sleep(1) puts_err(colored.blue("Getting IP address...")) lookup = self.get("enable_ip_lookup", False) ip = vmrun.getGuestIPAddress(lookup=lookup) if ip: puts_err(colored.green("VM resumed on {}".format(ip))) else: puts_err(colored.green("VM resumed on an unknown IP address")) # Otherwise try starting else: started = vmrun.start() if started is None: puts_err(colored.red("VM not started")) else: time.sleep(3) puts_err(colored.blue("Getting IP address...")) lookup = self.get("enable_ip_lookup", False) ip = vmrun.getGuestIPAddress(lookup=lookup) puts_err(colored.blue("Sharing current folder...")) vmrun.enableSharedFolders() vmrun.addSharedFolder('mech', os.getcwd(), quiet=True) if ip: if started: puts_err(colored.green("VM started on {}".format(ip))) else: puts_err( colored.yellow( "VM already was started on {}".format(ip))) else: if started: puts_err( colored.green( "VM started on an unknown IP address")) else: puts_err( colored.yellow( "VM already was started on an unknown IP address" ))
def global_status(self, arguments): """ Outputs mech environments status for this user. Usage: mech global-status [options] Options: --prune Prune invalid entries -h, --help Print this help """ vmrun = VMrun() print(vmrun.list())
def list(self, arguments): """ List all snapshots taken for a machine. Usage: mech snapshot list [options] [<instance>] Options: -h, --help Print this help """ instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx, user=self.user, password=self.password) print(vmrun.listSnapshots())
def ps(self, arguments): """ List running processes in Guest OS. Usage: mech ps [options] [<instance>] Options: -h, --help Print this help """ instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx, self.user, self.password) print(vmrun.listProcessesInGuest())
def provision(self, arguments): """ Provisions the Mech machine. Usage: mech provision [options] [<instance>] Options: -h, --help Print this help """ instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx, self.user, self.password) if not vmrun.installedTools(): puts_err(colored.red("Tools not installed")) return provisioned = 0 for i, provision in enumerate(self.get('provision', [])): if provision.get('type') == 'file': source = provision.get('source') destination = provision.get('destination') if utils.provision_file(vmrun, source, destination) is None: puts_err(colored.red("Not Provisioned")) return provisioned += 1 elif provision.get('type') == 'shell': inline = provision.get('inline') path = provision.get('path') args = provision.get('args') if not isinstance(args, list): args = [args] if utils.provision_shell(vmrun, inline, path, args) is None: puts_err(colored.red("Not Provisioned")) return provisioned += 1 else: puts_err(colored.red("Not Provisioned ({}".format(i))) return else: puts_err( colored.green("Provisioned {} entries".format(provisioned))) return puts_err(colored.red("Not Provisioned ({}".format(i)))
def up(self, arguments): """ Starts and provisions the mech environment. Usage: mech up [options] [<instance>] Options: --gui Start GUI --provision Enable provisioning --insecure Do not validate SSL certificates --cacert FILE CA certificate for SSL download --capath DIR CA certificate directory for SSL download --cert FILE A client SSL cert, if needed --checksum CHECKSUM Checksum for the box --checksum-type TYPE Checksum type (md5, sha1, sha256) --no-cache Do not save the downloaded box -h, --help Print this help """ gui = arguments['--gui'] save = not arguments['--no-cache'] requests_kwargs = utils.get_requests_kwargs(arguments) instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) utils.index_active_instance(instance_name) vmx = utils.init_box(self.box_name, self.box_version, requests_kwargs=requests_kwargs, save=save) vmrun = VMrun(vmx, user=self.user, password=self.password) puts_err(colored.blue("Bringing machine up...")) started = vmrun.start(gui=gui) if started is None: puts_err(colored.red("VM not started")) else: time.sleep(3) puts_err(colored.blue("Getting IP address...")) lookup = self.get("enable_ip_lookup", False) ip = vmrun.getGuestIPAddress(lookup=lookup) puts_err(colored.blue("Sharing current folder...")) vmrun.enableSharedFolders() vmrun.addSharedFolder('mech', os.getcwd(), quiet=True) if ip: if started: puts_err(colored.green("VM started on {}".format(ip))) else: puts_err( colored.yellow( "VM was already started on {}".format(ip))) else: if started: puts_err( colored.green("VM started on an unknown IP address")) else: puts_err( colored.yellow( "VM was already started on an unknown IP address"))
def suspend(self, arguments): """ Suspends the machine. Usage: mech suspend [options] [<instance>] Options: -h, --help Print this help """ instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx, user=self.user, password=self.password) if vmrun.suspend() is None: puts_err(colored.red("Not suspended", vmrun)) else: puts_err(colored.green("Suspended", vmrun))
def pause(self, arguments): """ Pauses the Mech machine. Usage: mech pause [options] [<instance>] Options: -h, --help Print this help """ instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx, user=self.user, password=self.password) if vmrun.pause() is None: puts_err(colored.red("Not paused", vmrun)) else: puts_err(colored.yellow("Paused", vmrun))
def list(self, arguments): """ Lists all available boxes. Usage: mech list [options] Options: -h, --help Print this help """ print("{}\t{}\t{}\t{}\t{}".format( 'NAME'.rjust(20), 'ADDRESS'.rjust(15), 'BOX'.rjust(35), 'VERSION'.rjust(12), 'PATH', )) for instance_name, instance in utils.instances().items(): path = instance.get('path') if path and os.path.exists(path): self.activate(instance_name) mech_path = os.path.join(path, '.mech') if os.path.exists(mech_path): vmrun = VMrun(self.vmx, user=self.user, password=self.password) lookup = self.get("enable_ip_lookup", False) ip = vmrun.getGuestIPAddress(wait=False, quiet=True, lookup=lookup) if ip is None: ip = colored.yellow("poweroff") elif not ip: ip = colored.green("running") else: ip = colored.green(ip) else: ip = "" box_name = self.box_name or "" box_version = self.box_version or "" print("{}\t{}\t{}\t{}\t{}".format( colored.green(instance_name.rjust(20)), ip.rjust(15), box_name.rjust(35), box_version.rjust(12), path, ))
def config_ssh(self): vmrun = VMrun(self.vmx, user=self.user, password=self.password) lookup = self.get("enable_ip_lookup", False) ip = vmrun.getGuestIPAddress( wait=False, lookup=lookup) if vmrun.installedTools() else None if not ip: puts_err( colored.red( textwrap.fill( "This Mech machine is reporting that it is not yet ready for SSH. " "Make sure your machine is created and running and try again. " "Additionally, check the output of `mech status` to verify " "that the machine is in the state that you expect."))) sys.exit(1) insecure_private_key = os.path.abspath( os.path.join(HOME, "insecure_private_key")) if not os.path.exists(insecure_private_key): with open(insecure_private_key, 'w') as f: f.write(INSECURE_PRIVATE_KEY) os.chmod(insecure_private_key, 0o400) config = { "Host": DEFAULT_HOST, "User": self.user, "Port": "22", "UserKnownHostsFile": "/dev/null", "StrictHostKeyChecking": "no", "PasswordAuthentication": "no", "IdentityFile": insecure_private_key, "IdentitiesOnly": "yes", "LogLevel": "FATAL", } for k, v in self.config.items(): k = re.sub(r'[ _]+', r' ', k) k = re.sub(r'(?<=[^_])([A-Z])', r' \1', k).lower() k = re.sub(r'^( *)(.*?)( *)$', r'\2', k) callback = lambda pat: pat.group(1).upper() k = re.sub(r' (\w)', callback, k) if k[0].islower(): k = k[0].upper() + k[1:] config[k] = v config.update({ "HostName": ip, }) return config
def ip(self, arguments): """ Outputs ip of the mech machine. Usage: mech ip [options] [<instance>] Options: -h, --help Print this help """ instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx) ip = vmrun.getGuestIPAddress() if ip: puts_err(colored.green(ip)) else: puts_err(colored.red("Unkown IP address"))
def ip(self, arguments): """ Outputs ip of the Mech machine. Usage: mech ip [options] [<instance>] Options: -h, --help Print this help """ instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx, user=self.user, password=self.password) lookup = self.get("enable_ip_lookup", False) ip = vmrun.getGuestIPAddress(lookup=lookup) if ip: puts_err(colored.green(ip)) else: puts_err(colored.red("Unknown IP address"))
def delete(self, arguments): """ Delete a snapshot taken previously with snapshot save. Usage: mech snapshot delete [options] <name> [<instance>] Options: -h, --help Print this help """ name = arguments['<name>'] instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx, user=self.user, password=self.password) if vmrun.deleteSnapshot(name) is None: puts_err(colored.red("Cannot delete name")) else: puts_err(colored.green("Snapshot {} deleted".format(name)))
def reload(self, arguments): """ Restarts Mech machine, loads new Mechfile configuration. Usage: mech reload [options] [<instance>] Options: --provision Enable provisioning -h, --help Print this help """ instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx, user=self.user, password=self.password) puts_err(colored.blue("Reloading machine...")) started = vmrun.reset() if started is None: puts_err(colored.red("VM not restarted")) else: time.sleep(3) puts_err(colored.blue("Getting IP address...")) lookup = self.get("enable_ip_lookup", False) ip = vmrun.getGuestIPAddress(lookup=lookup) if ip: if started: puts_err(colored.green("VM started on {}".format(ip))) else: puts_err( colored.yellow( "VM already was started on {}".format(ip))) else: if started: puts_err( colored.green("VM started on an unknown IP address")) else: puts_err( colored.yellow( "VM already was started on an unknown IP address"))
def port(self, arguments): """ Displays information about guest port mappings. Usage: mech port [options] [<instance>] Options: --guest PORT Output the host port that maps to the given guest port --machine-readable Display machine-readable output -h, --help Print this help """ instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx, user=self.user, password=self.password) for network in vmrun.listHostNetworks().split('\n'): network = network.split() if len(network) > 2 and network[2] == 'nat': print(vmrun.listPortForwardings(network[1])) break else: puts_err(colored.red("Cannot find a nat network"))
def destroy(self, arguments): """ Stops and deletes all traces of the mech machine. Usage: mech destroy [options] [<instance>] Options: -f, --force Destroy without confirmation. -h, --help Print this help """ force = arguments['--force'] instance_name = arguments['<instance>'] self.activate(instance_name) if instance_name: instance = utils.settle_instance(instance_name) path = instance['path'] else: path = os.getcwd() mech_path = os.path.join(path, '.mech') if os.path.exists(mech_path): if force or utils.confirm( "Are you sure you want to delete {instance_name} at {path}" .format(instance_name=instance_name, path=path), default='n'): puts_err(colored.green("Deleting...")) vmrun = VMrun(self.vmx) vmrun.stop(mode='hard', quiet=True) time.sleep(3) shutil.rmtree(mech_path) else: puts_err(colored.red("Deletion aborted")) else: puts_err(colored.red("The box hasn't been initialized."))
def down(self, arguments): """ Stops the Mech machine. Usage: mech down [options] [<instance>] Options: --force Force a hard stop -h, --help Print this help """ force = arguments['--force'] instance_name = arguments['<instance>'] instance_name = self.activate(instance_name) vmrun = VMrun(self.vmx, user=self.user, password=self.password) if not force and vmrun.installedTools(): stopped = vmrun.stop() else: stopped = vmrun.stop(mode='hard') if stopped is None: puts_err(colored.red("Not stopped", vmrun)) else: puts_err(colored.green("Stopped", vmrun))