def main(self): for minion_name, minion_path in self.parent.config.get('minions', {}).items(): vagrant = Vagrant(minion_path) vagrant_status = vagrant.status()[0].state salt_status = self.parent.client.get_minion_status(minion_name) puts("%s:" % minion_name) with indent(4): puts("vagrant status: %s" % vagrant_status) puts("saltstack status: %s" % salt_status)
class RbxProjectRunAction(object): vagrantfile = 'Vagrantfile' configfile = 'rbx.sh' @property def package_path(self): if not hasattr(self, '_package_path'): self._package_path = os.path.abspath( os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) return self._package_path @property def user_path(self): if not hasattr(self, '_user_path'): if self.params.location: self._user_path = os.path.abspath(self.params.location) else: self._user_path = os.path.abspath(os.getcwd()) return self._user_path def write_config(self, commands, config): with open(os.path.join(self.user_path, self.configfile), 'w') as fd: fd.writelines('\n'.join(commands)) for forwarded in config['ports']: fd.write('\n#RBX_PORT:{0}'.format(forwarded)) for src, dest in config['volumes']: fd.write('\n#RBX_VOLUME:{0}:{1}'.format(src, dest)) def _is_vagrant(self): return not self.params.host def do_action_run(self): if self._is_vagrant: self.copy_vagrantfile() self.vagrant = Vagrant(self.user_path) if self.params.stop: self._project_stop() elif self.params.restart: self._project_restart() elif self.params.suspend: self._project_suspend() elif self.params.reset: self._project_reset() else: self._project_start() def _project_start(self): if self._is_vagrant(): status = self.vagrant.status() if status.get('default') != Vagrant.RUNNING: commands, config = self.build() self.write_config(commands, config) self.vagrant.up(False, capture_output=False) self.vagrant.provision(capture_output=False) else: self.out('Sorry, not implemented yet!') def _project_stop(self): if self._is_vagrant(): status = self.vagrant.status() if status.get('default') == Vagrant.RUNNING: self.vagrant.halt(capture_output=False) else: self.out('Option no available for physical machine') def _project_restart(self): if self._is_vagrant(): self._project_stop() self._project_start() else: self.out('Option no available for physical machine') def _project_suspend(self): if self._is_vagrant(): status = self.vagrant.status() if status.get('default') == Vagrant.RUNNING: self.vagrant.suspend(capture_output=False) else: self.out('Sorry, not implemented yet!') def _project_reset(self): if self._is_vagrant(): status = self.vagrant.status() if status.get('default') == Vagrant.RUNNING: commands, config = self.build() self.write_config(commands, config) self.vagrant.provision(capture_output=False) else: self._project_start() else: self.out('Sorry, not implemented yet!') def copy_vagrantfile(self): copy(os.path.join(self.package_path, self.vagrantfile), os.path.join(self.user_path, self.vagrantfile)) def retrieve_components(self): self.components = {} for component in self.project['components']: self.components[component['name']] = self.query('get', '/component/{0}'.format(component['name'])) def build(self): self.project = self.query_resource('get') self.retrieve_components() self.docker_command = [] names = [] commands = [] ports = [] volumes = [] for component in self.project['components']: conf = self.components[component['name']] commands.append(('echo "[rbx] Deploying component \'{0}\'"; '.format(component['name']) + '[ "x$(docker ps | grep {0})" != "x" ] && docker stop -t=3 {0} &> /dev/null; ' + '[ "x$(docker ps -a | grep {0})" != "x" ] && docker rm {0} &> /dev/null; ' + 'docker run -d -name {0} {1} {2} {3} {4} {5} &> /dev/null').format( self._docker_name(component['name']), self._docker_links(names), self._docker_ports(component['port']), self._docker_volumes(component['volume']), conf['image'], subprocess.list2cmdline(conf['command']))) if component['port']: for port in component['port']: ports.append(port['forwarded']) if component['volume']: for volume in component['volume']: _vol = (volume['mounted'], volume['path']) if _vol in volumes: continue volumes.append(_vol) names.append(component['name']) return commands, {'ports': ports, 'volumes': volumes} def _volume_path(self, conf): if self.params.host: return conf['mounted'] return conf['path'] def _docker_name(self, name): return '{0}_{1}'.format(self.project['name'], name) def _docker_links(self, names): return ' '.join(['-link {0}:{1}'.format(self._docker_name(n), n) for n in names]) def _docker_ports(self, ports): return ' '.join(['-p {0}:{1}'.format(p['forwarded'], p['number']) for p in ports]) def _docker_volumes(self, volumes): return ' '.join(['-v {0}:{1}:ro'.format(self._volume_path(v), v['path']) for v in volumes])
class VagrantTestCase(TestCase): """ TestCase class to control vagrant boxes during testing vagrant_boxes: An iterable of vagrant boxes. If empty or None, all boxes will be used. Defaults to [] vagrant_root: The root directory that holds a Vagrantfile for configuration. Defaults to the working directory restart_boxes: If True, the boxes will be restored to their initial states between each test, otherwise the boxes will remain up. Defaults to False """ vagrant_boxes = [] vagrant_root = None restart_boxes = False __initial_box_statuses = {} __cleanup_actions = { Vagrant.NOT_CREATED: 'destroy', Vagrant.POWEROFF: 'halt', Vagrant.SAVED: 'suspend', } def __init__(self, *args, **kwargs): """Check that the vagrant_boxes attribute is not left empty, and is populated by all boxes if left blank""" self.vagrant = Vagrant(self.vagrant_root) if not self.vagrant_boxes: boxes = [s.name for s in self.vagrant.status()] if len(boxes) == 1: self.vagrant_boxes = ['default'] else: self.vagrant_boxes = boxes super(VagrantTestCase, self).__init__(*args, **kwargs) def assertBoxStatus(self, box, status): """Assertion for a box status""" box_status = [s.state for s in self.vagrant.status() if s.name == box][0] if box_status != status: self.failureException('{} has status {}, not {}'.format(box, box_status, status)) def assertBoxUp(self, box): """Assertion for a box being up""" self.assertBoxStatus(box, Vagrant.RUNNING) def assertBoxSuspended(self, box): """Assertion for a box being up""" self.assertBoxStatus(box, Vagrant.SAVED) def assertBoxHalted(self, box): """Assertion for a box being up""" self.assertBoxStatus(box, Vagrant.POWEROFF) def assertBoxNotCreated(self, box): """Assertion for a box being up""" self.assertBoxStatus(box, Vagrant.NOT_CREATED) def run(self, result=None): """Override run to have provide a hook into an alternative to tearDownClass with a reference to self""" self.setUpOnce() run = super(VagrantTestCase, self).run(result) self.tearDownOnce() return run def setUpOnce(self): """Collect the box states before starting""" for box_name in self.vagrant_boxes: box_state = [s.state for s in self.vagrant.status() if s.name == box_name][0] self.__initial_box_statuses[box_name] = box_state def tearDownOnce(self): """Restore all boxes to their initial states after running all tests, unless tearDown handled it already""" if not self.restart_boxes: self.restore_box_states() def restore_box_states(self): """Restores all boxes to their original states""" for box_name in self.vagrant_boxes: action = self.__cleanup_actions.get(self.__initial_box_statuses[box_name]) if action: getattr(self.vagrant, action)(vm_name=box_name) def setUp(self): """Starts all boxes before running tests""" for box_name in self.vagrant_boxes: self.vagrant.up(vm_name=box_name) super(VagrantTestCase, self).setUp() def tearDown(self): """Returns boxes to their initial status after each test if self.restart_boxes is True""" if self.restart_boxes: self.restore_box_states() super(VagrantTestCase, self).tearDown()
class SystemVM(object): def __init__(self, host='default', vagrantDir=None, controlVagrant=True): global _defaultVagrantDir self.host = host self._controlVagrant = controlVagrant if vagrantDir is None: vagrantDir = _defaultVagrantDir self._vagrant = Vagrant(root=vagrantDir) self._startedVagrant = False self._sshClient = None self._sshConfigStr = None self._sshConfig = None self._sshHostConfig = None def maybeUp(self): if not self._controlVagrant: return state = self._vagrant.status(vm_name=self.host)[0].state if state == Vagrant.NOT_CREATED: self._vagrant.up(vm_name=self.host) self._startedVagrant = True elif state in [Vagrant.POWEROFF, Vagrant.SAVED, Vagrant.ABORTED]: raise Exception( "SystemVM testing does not support resume(), do not use vagrant suspend/halt" ) elif state == Vagrant.RUNNING: self._startedVagrant = False else: raise Exception("Unrecognized vagrant state %s" % state) def maybeDestroy(self): if not self._controlVagrant or not self._startedVagrant: return self._vagrant.destroy(vm_name=self.host) if self._sshClient is not None: self._sshClient.close() def loadSshConfig(self): if self._sshConfig is None: self._sshConfigStr = self._vagrant.ssh_config(vm_name=self.host) configObj = StringIO(self._sshConfigStr) self._sshConfig = SSHConfig() # noinspection PyTypeChecker self._sshConfig.parse(configObj) self._sshHostConfig = self._sshConfig.lookup(self.host) @property def sshConfig(self): if self._sshConfig is None: self.loadSshConfig() return self._sshConfig @property def sshConfigStr(self): if self._sshConfigStr is None: self.loadSshConfig() return self._sshConfigStr @property def sshClient(self): if self._sshClient is None: self.loadSshConfig() self._sshClient = SSHClient() self._sshClient.set_missing_host_key_policy(AutoAddPolicy()) self._sshClient.connect(self.hostname, self.sshPort, self.sshUser, key_filename=self.sshKey, timeout=10) return self._sshClient @property def hostname(self): return self._sshHostConfig.get('hostname', self.host) @property def sshPort(self): return int(self._sshHostConfig.get('port', 22)) @property def sshUser(self): return self._sshHostConfig.get('user', 'root') @property def sshKey(self): return self._sshHostConfig.get('identityfile', '~/.ssh/id_rsa')
class VagrantTestCase(TestCase): """ TestCase class to control vagrant boxes during testing vagrant_boxes: An iterable of vagrant boxes. If empty or None, all boxes will be used. Defaults to [] vagrant_root: The root directory that holds a Vagrantfile for configuration. Defaults to the working directory restart_boxes: If True, the boxes will be restored to their initial states between each test, otherwise the boxes will remain up. Defaults to False """ vagrant_boxes = [] vagrant_root = None restart_boxes = False __initial_box_statuses = {} __cleanup_actions = { Vagrant.NOT_CREATED: 'destroy', Vagrant.POWEROFF: 'halt', Vagrant.SAVED: 'suspend', } def __init__(self, *args, **kwargs): """Check that the vagrant_boxes attribute is not left empty, and is populated by all boxes if left blank""" self.vagrant = Vagrant(self.vagrant_root) if not self.vagrant_boxes: boxes = self.vagrant.status().keys() if len(boxes) == 1: self.vagrant_boxes = ['default'] else: self.vagrant_boxes = boxes super(VagrantTestCase, self).__init__(*args, **kwargs) def assertBoxStatus(self, box, status): """Assertion for a box status""" box_status = self.vagrant.status()[box] if box_status != status: self.failureException('{} has status {}, not {}'.format( box, box_status, status)) def assertBoxUp(self, box): """Assertion for a box being up""" self.assertBoxStatus(box, Vagrant.RUNNING) def assertBoxSuspended(self, box): """Assertion for a box being up""" self.assertBoxStatus(box, Vagrant.SAVED) def assertBoxHalted(self, box): """Assertion for a box being up""" self.assertBoxStatus(box, Vagrant.POWEROFF) def assertBoxNotCreated(self, box): """Assertion for a box being up""" self.assertBoxStatus(box, Vagrant.NOT_CREATED) def run(self, result=None): """Override run to have provide a hook into an alternative to tearDownClass with a reference to self""" self.setUpOnce() run = super(VagrantTestCase, self).run(result) self.tearDownOnce() return run def setUpOnce(self): """Collect the box states before starting""" for box_name in self.vagrant_boxes: self.__initial_box_statuses[box_name] = self.vagrant.status( )[box_name] def tearDownOnce(self): """Restore all boxes to their initial states after running all tests, unless tearDown handled it already""" if not self.restart_boxes: self.restore_box_states() def restore_box_states(self): """Restores all boxes to their original states""" for box_name in self.vagrant_boxes: action = self.__cleanup_actions.get( self.__initial_box_statuses[box_name]) if action: getattr(self.vagrant, action)(vm_name=box_name) def setUp(self): """Starts all boxes before running tests""" for box_name in self.vagrant_boxes: self.vagrant.up(vm_name=box_name) super(VagrantTestCase, self).setUp() def tearDown(self): """Returns boxes to their initial status after each test if self.restart_boxes is True""" if self.restart_boxes: self.restore_box_states() super(VagrantTestCase, self).tearDown()
def stop(self): self._stop.set() def stopped(self): return self._stop.isSet() class RestartWorker(StoppableThread): def run(self): global checked_in while not self.stopped(): vms = [x for x in get_alive_vms() if x.name != checked_out] if len(checked_in) > 0: vm = checked_in[0] stop(vm) checked_in = checked_in[1:] elif len(vms) < minimum_standby_vms and len(get_dead_vms()) > 0: for x in get_dead_vms()[0:(minimum_standby_vms - len(vms))]: start(x.name) else: time.sleep(5) if __name__ == "__main__": print(vagrant.status()) restart_thread = RestartWorker() restart_thread.start() app.run() print "done" restart_thread.stop()
class SystemVM(object): def __init__(self, host="default", vagrantDir=None, controlVagrant=True): global _defaultVagrantDir self.host = host self._controlVagrant = controlVagrant if vagrantDir is None: vagrantDir = _defaultVagrantDir self._vagrant = Vagrant(root=vagrantDir) self._startedVagrant = False self._sshClient = None self._sshConfigStr = None self._sshConfig = None self._sshHostConfig = None def maybeUp(self): if not self._controlVagrant: return state = self._vagrant.status(vm_name=self.host)[0].state if state == Vagrant.NOT_CREATED: self._vagrant.up(vm_name=self.host) self._startedVagrant = True elif state in [Vagrant.POWEROFF, Vagrant.SAVED, Vagrant.ABORTED]: raise Exception("SystemVM testing does not support resume(), do not use vagrant suspend/halt") elif state == Vagrant.RUNNING: self._startedVagrant = False else: raise Exception("Unrecognized vagrant state %s" % state) def maybeDestroy(self): if not self._controlVagrant or not self._startedVagrant: return self._vagrant.destroy(vm_name=self.host) if self._sshClient is not None: self._sshClient.close() def loadSshConfig(self): if self._sshConfig is None: self._sshConfigStr = self._vagrant.ssh_config(vm_name=self.host) configObj = StringIO(self._sshConfigStr) self._sshConfig = SSHConfig() # noinspection PyTypeChecker self._sshConfig.parse(configObj) self._sshHostConfig = self._sshConfig.lookup(self.host) @property def sshConfig(self): if self._sshConfig is None: self.loadSshConfig() return self._sshConfig @property def sshConfigStr(self): if self._sshConfigStr is None: self.loadSshConfig() return self._sshConfigStr @property def sshClient(self): if self._sshClient is None: self.loadSshConfig() self._sshClient = SSHClient() self._sshClient.set_missing_host_key_policy(AutoAddPolicy()) self._sshClient.connect(self.hostname, self.sshPort, self.sshUser, key_filename=self.sshKey, timeout=10) return self._sshClient @property def hostname(self): return self._sshHostConfig.get("hostname", self.host) @property def sshPort(self): return int(self._sshHostConfig.get("port", 22)) @property def sshUser(self): return self._sshHostConfig.get("user", "root") @property def sshKey(self): return self._sshHostConfig.get("identityfile", "~/.ssh/id_rsa")
def status(): """ Return the status of this vm instance :return: the output of vagrant status in machine readable format """ return Vagrant.status()