def run(self, comp: Composition, workflow: Workflow) -> None: ui.progress( f"waiting for {self._host}:{self._port}", "C", ) for remaining in ui.timeout_loop(self._timeout_secs): cmd = f"docker run --rm -t --network {comp.name}_default ubuntu:bionic-20200403".split( ) cmd.extend([ "timeout", str(self._timeout_secs), "bash", "-c", f"cat < /dev/null > /dev/tcp/{self._host}/{self._port}", ]) try: spawn.capture(cmd, unicode=True, stderr_too=True) except subprocess.CalledProcessError as e: ui.log_in_automation( "wait-for-tcp ({}:{}): error running {}: {}, stdout:\n{}\nstderr:\n{}" .format( self._host, self._port, ui.shell_quote(cmd), e, e.stdout, e.stderr, )) ui.progress(" {}".format(int(remaining))) else: ui.progress(" success!", finish=True) return raise Failed(f"Unable to connect to {self._host}:{self._port}")
def run(self, workflow: Workflow) -> None: try: workflow.run_compose([ "run", *(["--service-ports"] if self._service_ports else []), *self._command, ]) except subprocess.CalledProcessError: raise errors.Failed("giving up: {}".format( ui.shell_quote(self._command)))
def runv( args: Sequence[Union[Path, str]], cwd: Optional[Path] = None, stdin: Union[None, int, IO[bytes], bytes] = None, stdout: Union[None, int, IO[bytes], TextIO] = None, capture_output: bool = False, env: Optional[Dict[str, str]] = None, stderr: Union[None, int, IO[bytes], TextIO] = None, print_to: TextIO = sys.stdout, ) -> subprocess.CompletedProcess: """Verbosely run a subprocess. A description of the subprocess will be written to stdout before the subprocess is executed. Args: args: A list of strings or paths describing the program to run and the arguments to pass to it. cwd: An optional directory to change into before executing the process. stdin: An optional IO handle or byte string to use as the process's stdin stream. stdout: An optional IO handle to use as the process's stdout stream. capture_output: Whether to prevent the process from streaming output the parent process's stdin/stdout handles. If true, the output will be captured and made available as the `stdout` and `stderr` fields on the returned `subprocess.CompletedProcess`. Note that setting this parameter to true will override the behavior of the `stdout` parameter. env: If present, overwrite the environment with this dict Raises: OSError: The process cannot be executed, e.g. because the specified program does not exist. CalledProcessError: The process exited with a non-zero exit status. """ print("$", ui.shell_quote(args), file=print_to) if capture_output: stdout = subprocess.PIPE stderr = subprocess.PIPE # Work around https://bugs.python.org/issue34886. stdin_args = {"stdin": stdin} if isinstance(stdin, bytes): stdin_args = {"input": stdin} return subprocess.run( # type: ignore args, cwd=cwd, stdout=stdout, stderr=stderr, check=True, env=env, **stdin_args, )
def docker_inspect(self, format: str, container_id: str) -> str: try: cmd = f"docker inspect -f '{format}' {container_id}".split() output = spawn.capture(cmd, unicode=True, stderr_too=True).splitlines()[0] except subprocess.CalledProcessError as e: ui.log_in_automation( "docker inspect ({}): error running {}: {}, stdout:\n{}\nstderr:\n{}" .format(container_id, ui.shell_quote(cmd), e, e.stdout, e.stderr)) raise errors.Failed(f"failed to inspect Docker container: {e}") else: return output
def runv( args: Sequence[Union[Path, str]], *, cwd: Optional[Path] = None, env: Optional[Dict[str, str]] = None, stdin: Union[None, int, IO[bytes], bytes] = None, stdout: Union[None, int, IO[bytes]] = None, stderr: Union[None, int, IO[bytes]] = None, ) -> subprocess.CompletedProcess: """Verbosely run a subprocess. A description of the subprocess will be written to stdout before the subprocess is executed. Args: args: A list of strings or paths describing the program to run and the arguments to pass to it. cwd: An optional directory to change into before executing the process. env: A replacement environment with which to launch the process. If unspecified, the current process's environment is used. Replacement occurs wholesale, so use a construction like `env=dict(os.environ, KEY=VAL, ...)` to instead amend the existing environment. stdin: An optional IO handle or byte string to use as the process's stdin stream. stdout: An optional IO handle to use as the process's stdout stream. stderr: An optional IO handle to use as the process's stderr stream. Raises: OSError: The process cannot be executed, e.g. because the specified program does not exist. CalledProcessError: The process exited with a non-zero exit status. """ print("$", ui.shell_quote(args), file=sys.stderr) input = None if isinstance(stdin, bytes): input = stdin stdin = None return subprocess.run( args, cwd=cwd, env=env, input=input, stdin=stdin, stdout=stdout, stderr=stderr, check=True, )
def runv( args: Sequence[Union[Path, str]], cwd: Optional[Path] = None, stdin: Union[None, int, IO[bytes]] = None, stdout: Union[None, int, IO[bytes]] = None, capture_output: bool = False, ) -> subprocess.CompletedProcess: """Verbosely run a subprocess. A description of the subprocess will be written to stdout before the subprocess is executed. Args: args: A list of strings or paths describing the program to run and the arguments to pass to it. cwd: An optional directory to change into before executing the process. stdin: An optional IO handle to use as the process's stdin stream. stdout: An optional IO handle to use as the process's stdout stream. capture_output: Whether to prevent the process from streaming output the parent process's stdin/stdout handles. If true, the output will be captured and made available as the `stdout` and `stderr` fields on the returned `subprocess.CompletedProcess`. Note that setting this parameter to true will override the behavior of the `stdout` parameter. Raises: OSError: The process cannot be executed, e.g. because the specified program does not exist. CalledProcessError: The process exited with a non-zero exit status. """ print("$", ui.shell_quote(args)) stderr = None if capture_output: stdout = subprocess.PIPE stderr = subprocess.PIPE return subprocess.run(args, cwd=cwd, stdin=stdin, stdout=stdout, stderr=stderr, check=True)
def _check_tcp(cmd: List[str], host: str, port: int, timeout_secs: int, kind: str = "") -> List[str]: cmd.extend([ "timeout", str(timeout_secs), "bash", "-c", f"until [ cat < /dev/null > /dev/tcp/{host}/{port} ] ; do sleep 0.1 ; done", ]) try: spawn.capture(cmd, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: ui.log_in_automation( "wait-for-tcp ({}{}:{}): error running {}: {}, stdout:\n{}\nstderr:\n{}" .format(kind, host, port, ui.shell_quote(cmd), e, e.stdout, e.stderr)) raise return cmd
def run(self, comp: Composition, workflow: Workflow) -> None: try: workflow.mzcompose_run(self._command) except subprocess.CalledProcessError: raise Failed("giving up: {}".format(ui.shell_quote(self._command)))