class SingularityVM(object): def __init__(self, path_to_build): self.path_to_build = path_to_build def __enter__(self): # We want to start with a clean environment every time. if os.path.exists(SINGULARITY_VM_INPUT_DIR): rmtree(SINGULARITY_VM_INPUT_DIR) if os.path.exists(SINGULARITY_VM_OUTPUT_DIR): rmtree(SINGULARITY_VM_OUTPUT_DIR) makedirs(SINGULARITY_VM_OUTPUT_DIR) copytree(self.path_to_build, SINGULARITY_VM_INPUT_DIR, symlinks=True) self.vm = Vagrant(root=SINGULARITY_VM, quiet_stdout=False, quiet_stderr=False) return self def __exit__(self, exc_type, exc_val, exc_tb): self.vm.destroy() rmtree(SINGULARITY_VM_INPUT_DIR) rmtree(SINGULARITY_VM_OUTPUT_DIR) def run(self): try: self.vm.up() return SINGULARITY_VM_IMAGE except CalledProcessError: return None def store_logs(self, log_path, err_path): copy(SINGULARITY_VM_STDOUT, log_path) copy(SINGULARITY_VM_STDERR, err_path)
def destroy_box(box_id): box = Device.query.filter(Device.id == box_id).first() box_path = str("%s/boxes/%s" % (dirname(dirname(dirname(dirname(__file__)))), box.hostname)) vagrant_instance = Vagrant(root=box_path) vagrant_instance.destroy() os.chdir(box_path) os.chdir("../") shutil.rmtree(box.hostname) db.session.delete(box) db.session.commit() return redirect(url_for("index"))
class VagrantWrapper(object): def __init__(self, root_dir, env): self.instance = Vagrant(root=root_dir) self.env = env self.target = GuestOS(env[:-2], env[-2:]) def up(self): return self.instance.up(vm_name=self.env) def destroy(self): return self.instance.destroy(vm_name=self.env) def reboot(self, timeout=120): try: with self.ssh() as ssh: ssh.execute('sudo reboot', no_stderr_expected=False) except: # SSH can be broken on reboot - ignore this error pass # waiting for reboot to take place # TODO remove this spleep sleep(2) self.up() wait_for_ssh(self, timeout) def __get_ssh_params(self): return self.instance.user_hostname_port(vm_name=self.env), self.instance.keyfile(vm_name=self.env) def ssh(self) -> SSHClient: return ssh_connect(*self.__get_ssh_params())
def stop(self, challenge_id): """Function to stop a vagrant box in current dir. Stops the VM Args: challenge_id (str): the challengeId retrived during create command """ _challengeID = challenge_id if not os.path.exists("./data/challenges/" + _challengeID): self.out['error'] = True self.out[ 'message'] = 'unable to stop %s, as it doesn\'t exist' % _challengeID else: challenge_path = "./data/challenges/" + _challengeID # get the box ID with open(challenge_path + '/.status', 'r') as cStatus: try: boxId = json.loads(cStatus.readline())['boxId'] cStatus.close() # Update basebox status with open("./data/boxes/" + boxId + "/.status", 'r+') as bStatus: baseboxStatus = json.loads(bStatus.readline()) baseboxStatus['active'] -= 1 bStatus.seek(0) bStatus.write(json.dumps(baseboxStatus)) bStatus.truncate() except Exception: print("Couldn't destroy challenge") Vagrant.destroy(challenge_id) # delete the challenegeID Dir shutil.rmtree(challenge_path) self.out['message'] = _challengeID + ' deleted successfully' self.out['data'] = {} self.out['data']['challenegeId'] = _challengeID
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 test_vagrant(temp_repo_func, destroy=False): if os.environ.get("TRAVIS", False): pytest.skip("Vagrant doesn't work on Travis") backend = VagrantBackend(verbosity=2, use_registry_name="docker.io/mikicz/arca-test", keep_vm_running=True) arca = Arca(backend=backend, base_dir=BASE_DIR) if destroy: vagrant_location = backend.get_vm_location() if vagrant_location.exists(): vagrant = Vagrant(vagrant_location) vagrant.destroy() shutil.rmtree(vagrant_location) # master branch - return colorama version temp_repo_func.file_path.write_text(RETURN_COLORAMA_VERSION_FUNCTION) requirements_path = temp_repo_func.repo_path / backend.requirements_location requirements_path.write_text("colorama==0.3.9") temp_repo_func.repo.index.add( [str(temp_repo_func.file_path), str(requirements_path)]) temp_repo_func.repo.index.commit("Initial") # branch branch - return unicode temp_repo_func.repo.create_head("branch") temp_repo_func.repo.branches.branch.checkout() temp_repo_func.file_path.write_text(SECOND_RETURN_STR_FUNCTION) temp_repo_func.repo.index.add([str(temp_repo_func.file_path)]) temp_repo_func.repo.index.commit("Test unicode on a separate branch") task = Task("test_file:return_str_function") assert arca.run(temp_repo_func.url, temp_repo_func.branch, task).output == "0.3.9" # halt the VM, checks that the VM can be booted when stopped with the vagrant attribute set backend.stop_vm() assert arca.run(temp_repo_func.url, temp_repo_func.branch, task).output == "0.3.9" # halt the vm and create a new instance of the backend, to check that the vagrant attribute can be set from existing backend.stop_vm() backend = VagrantBackend(verbosity=2, use_registry_name="docker.io/mikicz/arca-test", keep_vm_running=True) arca = Arca(backend=backend, base_dir=BASE_DIR) assert arca.run(temp_repo_func.url, temp_repo_func.branch, task).output == "0.3.9" # test that two branches can work next to each other assert arca.run(temp_repo_func.url, temp_repo_func.branch, task).output == "0.3.9" assert arca.run(temp_repo_func.url, "branch", task).output == TEST_UNICODE # test timeout temp_repo_func.repo.branches.master.checkout() temp_repo_func.file_path.write_text(WAITING_FUNCTION) temp_repo_func.repo.index.add([str(temp_repo_func.file_path)]) temp_repo_func.repo.index.commit("Waiting function") task_1_second = Task("test_file:return_str_function", timeout=1) task_3_seconds = Task("test_file:return_str_function", timeout=3) with pytest.raises(BuildTimeoutError): assert arca.run(temp_repo_func.url, temp_repo_func.branch, task_1_second).output == "Some string" assert arca.run(temp_repo_func.url, temp_repo_func.branch, task_3_seconds).output == "Some string" backend.stop_vm() if destroy: backend.destroy = True backend.stop_vm()
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")