def RunSSHCommand(context, *cmd_list, **kwargs): """Runs an SSH command to an instance unpacking the sosreport context. Args: context: Structure created by the Sosreport command to contain the necessary information for executing an SSH command. Containts command args, instance data, etc. *cmd_list: List of arguments that will be bundled into a command array, similar to the args of subprocess.popen. Passed directly to RunSSHCommandToInstance. **kwargs: Configuration variables for the command and the underlying SSH helper function. Returns: The return code of the SSH command. Raises: ssh.CommandError: there was an error running a SSH command """ command = ' '.join(str(i) for i in cmd_list) log.out.Print('Running: "{command}"'.format(command=command)) return_code = external_helper.RunSSHCommandToInstance( command_list=cmd_list, instance=context['instance'], user=context['user'], args=context['args'], ssh_helper=context['ssh_helper'], explicit_output_file=kwargs.get('explicit_output_file'), explicit_error_file=kwargs.get('explicit_error_file'), dry_run=kwargs.get('dry_run')) return return_code
def ObtainSelfIp(self, instance, user, dry_run, resource_registry): """Returns the localhost ip as seen from the VM. Args: instance: Google Compute Engine VM. user: The user to use to SSH into the instance. dry_run: Whether to only print commands instead of running them. resource_registry: gcloud class used for obtaining data from the resources. Returns: A string containing the local ip, None if the obtaining was unsuccessful Raises: ssh.CommandError: there was an error running a SSH command """ instance_string = internal_helpers.GetInstanceNetworkTitleString( instance) log.out.write('Obtaining self ip from %s: ' % instance_string) # Sometimes this call will appear after the actual result log.out.flush() if dry_run: log.out.Print('<SELF-IP>') temp = tempfile.TemporaryFile() cmd = ['echo', '$SSH_CLIENT'] try: external_helper.RunSSHCommandToInstance( command_list=cmd, instance=instance, user=user, args=self._args, ssh_helper=self._ssh_helper, explicit_output_file=temp, dry_run=dry_run) except Exception as e: # pylint: disable=broad-exception log.out.write('\n') # Close the open print stmt log.out.flush() raise ssh.CommandError(' '.join(cmd), str(e)) temp.seek(0) who_am_i_str = temp.read() result = re.search(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', who_am_i_str) if result: res = result.group(1) log.out.Print(res) log.out.flush() return res return None
def CheckTraceroute(self, instance, user, dry_run, resource_registry): """Checks whether the instance has traceroute in PATH. Args: instance: Google Compute Engine VM. user: The user to use to SSH into the instance. dry_run: Whether to only print commands instead of running them. resource_registry: gcloud class used for obtaining data from the resources. Returns: True if the instance has traceroute in PATH, False otherwise Raises: ssh.CommandError: there was an error running a SSH command """ instance_string = internal_helpers.GetInstanceNetworkTitleString( instance) log.out.write('Checking traceroute for %s: ' % instance_string) if dry_run: log.out.Print('[DRY-RUN] No command executed.') log.out.flush() cmd = ['which', 'traceroute'] try: # This command is silent with open(os.devnull) as dev_null: return_code = external_helper.RunSSHCommandToInstance( command_list=cmd, instance=instance, user=user, args=self._args, ssh_helper=self._ssh_helper, explicit_output_file=dev_null, dry_run=dry_run) except Exception as e: log.out.write(str(e)) log.out.write('\n') # Close the open print stmt log.out.flush() raise ssh.CommandError(' '.join(cmd), str(e)) if return_code == 0: log.out.Print('Traceroute found in PATH') else: log.out.Print('Traceroute not found in PATH') log.out.flush() return return_code == 0
def ReverseTracerouteInstance(self, instance, user, external_route_ip, traceroute_args, dry_run, resource_registry): """Runs a traceroute from a GCE VM to localhost. Args: instance: Google Compute Engine VM. user: The user to use to SSH into the instance. external_route_ip: the ip to which traceroute from the VM traceroute_args: Additional traceroute args to be passed on. dry_run: Whether to only print commands instead of running them. resource_registry: gcloud class used for obtaining data from the resources. Raises: ssh.CommandError: there was an error running a SSH command """ instance_string = internal_helpers.GetInstanceNetworkTitleString( instance) log.out.Print('<<< Reverse tracerouting from %s' % instance_string) # Necessary because the order of commands in the output # would be wrong otherwise (the ssh command will output by its own) log.out.flush() if dry_run: external_route_ip = '<SELF-IP>' cmd = ['traceroute', external_route_ip] if traceroute_args: cmd += traceroute_args external_helper.RunSSHCommandToInstance(command_list=cmd, instance=instance, user=user, args=self._args, ssh_helper=self._ssh_helper, dry_run=dry_run) # This identifier is a simple delimiter of each traceroute run if not dry_run: log.out.Print('<<<')