def test_cmd_error(dvc): config = {} cmd = "sed 'hello'" ret = "1" err = "sed: expression #1, char 2: extra characters after command" with mock.patch.object( BaseRemoteTree, "remove", side_effect=RemoteCmdError("base", cmd, ret, err), ): with pytest.raises(RemoteCmdError): BaseRemoteTree(dvc, config).remove("file")
def test(self): repo = None config = {} cmd = "sed 'hello'" ret = "1" err = "sed: expression #1, char 2: extra characters after command" with mock.patch.object( self.REMOTE_CLS, "remove", side_effect=RemoteCmdError("base", cmd, ret, err), ): with self.assertRaises(RemoteCmdError): self.REMOTE_CLS(repo, config).remove("file")
def execute(self, cmd): stdin, stdout, stderr = self._ssh.exec_command(cmd) channel = stdout.channel stdin.close() channel.shutdown_write() stdout_chunks = [] stderr_chunks = [] while ( not channel.closed or channel.recv_ready() or channel.recv_stderr_ready() ): import select got_chunk = False readq, _, _ = select.select([stdout.channel], [], [], self.timeout) for c in readq: if c.recv_ready(): stdout_chunks.append(stdout.channel.recv(len(c.in_buffer))) got_chunk = True if c.recv_stderr_ready(): stderr_len = len(c.in_stderr_buffer) s = stderr.channel.recv_stderr(stderr_len) stderr_chunks.append(s) got_chunk = True if ( not got_chunk and stdout.channel.exit_status_ready() and not stderr.channel.recv_stderr_ready() and not stdout.channel.recv_ready() ): stdout.channel.shutdown_read() stdout.channel.close() break stdout.close() stderr.close() ret = stdout.channel.recv_exit_status() if ret != 0: err = b"".join(stderr_chunks).decode("utf-8") raise RemoteCmdError("ssh", cmd, ret, err) return b"".join(stdout_chunks).decode("utf-8")
def execute(self, cmd): stdin, stdout, stderr = self._ssh.exec_command(cmd) channel = stdout.channel stdin.close() channel.shutdown_write() stdout_chunks = [] stderr_chunks = [] while (not channel.closed or channel.recv_ready() or channel.recv_stderr_ready()): import selectors selector = selectors.DefaultSelector() selector.register(stdout.channel, selectors.EVENT_READ) got_chunk = False events = selector.select(self.timeout) for key, _ in events: c = key.fileobj if c.recv_ready(): stdout_chunks.append(stdout.channel.recv(len(c.in_buffer))) got_chunk = True if c.recv_stderr_ready(): stderr_len = len(c.in_stderr_buffer) s = stderr.channel.recv_stderr(stderr_len) stderr_chunks.append(s) got_chunk = True if (not got_chunk and stdout.channel.exit_status_ready() and not stderr.channel.recv_stderr_ready() and not stdout.channel.recv_ready()): stdout.channel.shutdown_read() stdout.channel.close() break stdout.close() stderr.close() ret = stdout.channel.recv_exit_status() if ret != 0: err = b"".join(stderr_chunks).decode("utf-8") raise RemoteCmdError("ssh", cmd, ret, err) return b"".join(stdout_chunks).decode("utf-8")
def test(self): for remote_class in [RemoteSSH, RemoteHDFS]: project = None config = {} remote_name = remote_class.scheme cmd = "sed 'hello'" ret = "1" err = "sed: expression #1, char 2: extra characters after command" with mock.patch.object( remote_class, "remove", side_effect=RemoteCmdError(remote_name, cmd, ret, err), ): with self.assertRaises(RemoteCmdError): remote_class(project, config).remove("file")
def shell_command(self, cmd, user=None): # NOTE: close_fds doesn't work with redirected stdin/stdout/stderr. # See https://github.com/iterative/dvc/issues/1197. close_fds = os.name != "nt" executable = os.getenv("SHELL") if os.name != "nt" else None p = Popen( cmd, shell=True, close_fds=close_fds, executable=executable, env=fix_env(os.environ), stdin=PIPE, stdout=PIPE, stderr=PIPE, ) out, err = p.communicate() if p.returncode != 0: raise RemoteCmdError(self.scheme, cmd, p.returncode, err) return out.decode("utf-8")