예제 #1
0
    def _docker_expand_user(self, string, any_char=False):
        user_pos = string.find("~")
        if user_pos > -1:
            if self.home_dir is None:
                self.home_dir = self._run_shell(
                    with_docker_exec(["printenv HOME"],
                                     container_name=self.container_name,
                                     docker_cmd=self.docker_cmd)).strip()

            if any_char:
                return string.replace("~/", self.home_dir + "/")

            elif not any_char and user_pos == 0:
                return string.replace("~", self.home_dir, 1)

        return string
예제 #2
0
    def run_rsync_up(self, source, target, options=None):
        options = options or {}
        host_destination = os.path.join(
            self._get_docker_host_mount_location(
                self.ssh_command_runner.cluster_name),
            target.lstrip("/"),
        )

        host_mount_location = os.path.dirname(host_destination.rstrip("/"))
        self.ssh_command_runner.run(
            f"mkdir -p {host_mount_location} && chown -R "
            f"{self.ssh_command_runner.ssh_user} {host_mount_location}",
            silent=is_rsync_silent(),
        )

        self.ssh_command_runner.run_rsync_up(source,
                                             host_destination,
                                             options=options)
        if self._check_container_status() and not options.get(
                "docker_mount_if_possible", False):
            if os.path.isdir(source):
                # Adding a "." means that docker copies the *contents*
                # Without it, docker copies the source *into* the target
                host_destination += "/."

            # This path may not exist inside the container. This ensures
            # that the path is created!
            prefix = with_docker_exec(
                [
                    "mkdir -p {}".format(
                        os.path.dirname(self._docker_expand_user(target)))
                ],
                container_name=self.container_name,
                with_interactive=is_using_login_shells(),
                docker_cmd=self.docker_cmd,
            )[0]

            self.ssh_command_runner.run(
                "{} && rsync -e '{} exec -i' -avz {} {}:{}".format(
                    prefix,
                    self.docker_cmd,
                    host_destination,
                    self.container_name,
                    self._docker_expand_user(target),
                ),
                silent=is_rsync_silent(),
            )
예제 #3
0
 def run(
     self,
     cmd: str = None,
     timeout: int = 120,
     exit_on_fail: bool = False,
     port_forward: List[Tuple[int, int]] = None,
     with_output: bool = False,
     environment_variables: Dict[str, object] = None,
     run_env: str = "auto",
     ssh_options_override_ssh_key: str = "",
     shutdown_after_run: bool = False,
 ) -> str:
     prefix = with_docker_exec([cmd],
                               container_name=self.container_name,
                               with_interactive=False,
                               docker_cmd=self.docker_cmd)[0]
     return self._run_shell(prefix)
예제 #4
0
    def run(
        self,
        cmd,
        timeout=120,
        exit_on_fail=False,
        port_forward=None,
        with_output=False,
        environment_variables: Dict[str, object] = None,
        run_env="auto",
        ssh_options_override_ssh_key="",
        shutdown_after_run=False,
    ):
        if run_env == "auto":
            run_env = (
                "host"
                if (not bool(cmd) or cmd.find(self.docker_cmd) == 0)
                else self.docker_cmd
            )

        if environment_variables:
            cmd = _with_environment_variables(cmd, environment_variables)

        if run_env == "docker":
            cmd = self._docker_expand_user(cmd, any_char=True)
            if is_using_login_shells():
                cmd = " ".join(_with_interactive(cmd))
            cmd = with_docker_exec(
                [cmd],
                container_name=self.container_name,
                with_interactive=is_using_login_shells(),
                docker_cmd=self.docker_cmd,
            )[0]

        if shutdown_after_run:
            # sudo shutdown should run after `with_docker_exec` command above
            cmd += "; sudo shutdown -h now"
        # Do not pass shutdown_after_run argument to ssh_command_runner.run()
        # since it is handled above.
        return self.ssh_command_runner.run(
            cmd,
            timeout=timeout,
            exit_on_fail=exit_on_fail,
            port_forward=port_forward,
            with_output=with_output,
            ssh_options_override_ssh_key=ssh_options_override_ssh_key,
        )