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
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(), )
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)
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, )