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)
Exemple #2
0
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')
Exemple #6
0
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()
Exemple #7
0
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")