def RemoteHostCopy(self, file_path, remote_path='', copy_to=True): """Copies a file to or from the VM. Args: file_path: Local path to file. remote_path: Optional path of where to copy file on remote host. copy_to: True to copy to vm, False to copy from vm. Raises: RemoteCommandError: If there was a problem copying the file. """ if vm_util.RunningOnWindows(): if ':' in file_path: # scp doesn't like colons in paths. file_path = file_path.split(':', 1)[1] # Replace the last instance of '\' with '/' to make scp happy. file_path = '/'.join(file_path.rsplit('\\', 1)) remote_location = '%s@%s:%s' % (self.user_name, self.ip_address, remote_path) scp_cmd = ['scp', '-P', str(self.ssh_port), '-pr'] scp_cmd.extend(vm_util.GetSshOptions(self.ssh_private_key)) if copy_to: scp_cmd.extend([file_path, remote_location]) else: scp_cmd.extend([remote_location, file_path]) stdout, stderr, retcode = vm_util.IssueCommand(scp_cmd, timeout=None) if retcode: full_cmd = ' '.join(scp_cmd) error_text = ('Got non-zero return code (%s) executing %s\n' 'STDOUT: %sSTDERR: %s' % (retcode, full_cmd, stdout, stderr)) raise errors.VirtualMachine.RemoteCommandError(error_text)
def RemoteCopy(self, file_path, remote_path='', copy_to=True, remote_port=22): """Copies a file to or from the VM. Args: file_path: Local path to file. remote_path: Optional path of where to copy file on remote host. copy_to: True to copy to vm, False to copy from vm. remote_port: Ssh port on the VM. Raises: SshConnectionError: If there was a problem copying the file. """ remote_location = '%s@%s:%s' % (self.user_name, self.ip_address, remote_path) scp_cmd = ['/usr/bin/scp', '-P', str(remote_port), '-pr'] scp_cmd.extend(vm_util.GetSshOptions(self.ssh_private_key)) if copy_to: scp_cmd.extend([file_path, remote_location]) else: scp_cmd.extend([remote_location, file_path]) stdout, stderr, retcode = vm_util.IssueCommand(scp_cmd) if retcode: full_cmd = ' '.join(scp_cmd) error_text = ('Got non-zero return code (%s) executing %s\n' 'STDOUT: %sSTDERR: %s' % (retcode, full_cmd, stdout, stderr)) raise errors.VmUtil.SshConnectionError(error_text)
def RemoteCommand(self, command, remote_port=22, should_log=False, retries=SSH_RETRIES, ignore_failure=False, login_shell=False): """Runs a command on the VM. Args: command: A valid bash command. remote_port: Ssh port on the VM. should_log: A boolean indicating whether the command result should be logged at the info level. Even if it is false, the results will still be logged at the debug level. retries: The maximum number of times RemoteCommand should retry SSHing when it receives a 255 return code. ignore_failure: Ignore any failure if set to true. login_shell: Run command in a login shell. Returns: A tuple of stdout and stderr from running the command. Raises: SshConnectionError: If there was a problem establishing the connection. """ user_host = '%s@%s' % (self.user_name, self.ip_address) ssh_cmd = ['/usr/bin/ssh', '-A', '-p', str(remote_port), user_host] ssh_cmd.extend(vm_util.GetSshOptions(self.ssh_private_key)) try: if login_shell: ssh_cmd.extend(['-t', '-t', 'bash -l -c "%s"' % command]) self.pseudo_tty_lock.acquire() else: ssh_cmd.append(command) for _ in range(retries): stdout, stderr, retcode = vm_util.IssueCommand( ssh_cmd, should_log=should_log) if retcode != 255: # Retry on 255 because this indicates an SSH failure break finally: if login_shell: self.pseudo_tty_lock.release() if retcode: full_cmd = ' '.join(ssh_cmd) error_text = ('Got non-zero return code (%s) executing %s\n' 'Full command: %s\nSTDOUT: %sSTDERR: %s' % (retcode, command, full_cmd, stdout, stderr)) if not ignore_failure: raise errors.VmUtil.SshConnectionError(error_text) return stdout, stderr
def RemoteHostCommand(self, command, should_log=False, retries=SSH_RETRIES, ignore_failure=False, login_shell=False, suppress_warning=False, timeout=None): """Runs a command on the VM. This is guaranteed to run on the host VM, whereas RemoteCommand might run within i.e. a container in the host VM. Args: command: A valid bash command. should_log: A boolean indicating whether the command result should be logged at the info level. Even if it is false, the results will still be logged at the debug level. retries: The maximum number of times RemoteCommand should retry SSHing when it receives a 255 return code. ignore_failure: Ignore any failure if set to true. login_shell: Run command in a login shell. suppress_warning: Suppress the result logging from IssueCommand when the return code is non-zero. Returns: A tuple of stdout and stderr from running the command. Raises: RemoteCommandError: If there was a problem establishing the connection. """ if vm_util.RunningOnWindows(): # Multi-line commands passed to ssh won't work on Windows unless the # newlines are escaped. command = command.replace('\n', '\\n') user_host = '%s@%s' % (self.user_name, self.ip_address) ssh_cmd = ['ssh', '-A', '-p', str(self.ssh_port), user_host] ssh_cmd.extend(vm_util.GetSshOptions(self.ssh_private_key)) try: if login_shell: ssh_cmd.extend(['-t', '-t', 'bash -l -c "%s"' % command]) self._pseudo_tty_lock.acquire() else: ssh_cmd.append(command) for _ in range(retries): stdout, stderr, retcode = vm_util.IssueCommand( ssh_cmd, force_info_log=should_log, suppress_warning=suppress_warning, timeout=timeout) if retcode != 255: # Retry on 255 because this indicates an SSH failure break finally: if login_shell: self._pseudo_tty_lock.release() if retcode: full_cmd = ' '.join(ssh_cmd) error_text = ('Got non-zero return code (%s) executing %s\n' 'Full command: %s\nSTDOUT: %sSTDERR: %s' % (retcode, command, full_cmd, stdout, stderr)) if not ignore_failure: raise errors.VirtualMachine.RemoteCommandError(error_text) return stdout, stderr