• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 - The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15
16class SshFormatter(object):
17    """Handles formatting ssh commands.
18
19    Handler for formatting chunks of the ssh command to run.
20    """
21
22    def format_ssh_executable(self, settings):
23        """Format the executable name.
24
25        Formats the executable name as a string.
26
27        Args:
28            settings: The ssh settings being used.
29
30        Returns:
31            A string for the ssh executable name.
32        """
33        return settings.executable
34
35    def format_host_name(self, settings):
36        """Format hostname.
37
38        Formats the hostname to connect to.
39
40        Args:
41            settings: The ssh settings being used.
42
43        Returns:
44            A string of the connection host name to connect to.
45        """
46        return '%s@%s' % (settings.username, settings.hostname)
47
48    def format_value(self, value):
49        """Formats a command line value.
50
51        Takes in a value and formats it so it can be safely used in the
52        command line.
53
54        Args:
55            value: The value to format.
56
57        Returns:
58            A string representation of the formatted value.
59        """
60        if isinstance(value, bool):
61            return 'yes' if value else 'no'
62
63        return str(value)
64
65    def format_options_list(self, options):
66        """Format the option list.
67
68        Formats a dictionary of options into a list of strings to be used
69        on the command line.
70
71        Args:
72            options: A dictionary of options.
73
74        Returns:
75            An iterator of strings that should go on the command line.
76        """
77        for option_name in options:
78            option = options[option_name]
79
80            yield '-o'
81            yield '%s=%s' % (option_name, self.format_value(option))
82
83    def format_flag_list(self, flags):
84        """Format the flags list.
85
86        Formats a dictionary of flags into a list of strings to be used
87        on the command line.
88
89        Args:
90            flags: A dictonary of options.
91
92        Returns:
93            An iterator of strings that should be used on the command line.
94        """
95        for flag_name in flags:
96            flag = flags[flag_name]
97
98            yield flag_name
99            if flag is not None:
100                yield self.format_value(flag)
101
102    def format_ssh_local_command(self,
103                                 settings,
104                                 extra_flags={},
105                                 extra_options={}):
106        """Formats the local part of the ssh command.
107
108        Formats the local section of the ssh command. This is the part of the
109        command that will actual launch ssh on our local machine with the
110        specified settings.
111
112        Args:
113            settings: The ssh settings.
114            extra_flags: Extra flags to inlcude.
115            extra_options: Extra options to include.
116
117        Returns:
118            An array of strings that make up the command and its local
119            arguments.
120        """
121        options = settings.construct_ssh_options()
122        for extra_option_name in extra_options:
123            options[extra_option_name] = extra_options[extra_option_name]
124        options_list = list(self.format_options_list(options))
125
126        flags = settings.construct_ssh_flags()
127        for extra_flag_name in extra_flags:
128            flags[extra_flag_name] = extra_flags[extra_flag_name]
129        flags_list = list(self.format_flag_list(flags))
130
131        all_options = options_list + flags_list
132        host_name = self.format_host_name(settings)
133        executable = self.format_ssh_executable(settings)
134
135        base_command = [executable] + all_options + [host_name]
136
137        return base_command
138
139    def format_ssh_command(self,
140                           remote_command,
141                           settings,
142                           extra_flags={},
143                           extra_options={}):
144        """Formats the full ssh command.
145
146        Creates the full format for an ssh command.
147
148        Args:
149            remote_command: A string that represents the remote command to
150                            execute.
151            settings: The ssh settings to use.
152            extra_flags: Extra flags to include in the settings.
153            extra_options: Extra options to include in the settings.
154
155        Returns:
156            A list of strings that make up the total ssh command.
157        """
158        local_command = self.format_ssh_local_command(settings, extra_flags,
159                                                      extra_options)
160
161        local_command.append(remote_command)
162        return local_command
163
164    def format_remote_command(self, command, env):
165        """Formats the remote part of the ssh command.
166
167        Formatts the command that will run on the remote machine.
168
169        Args:
170            command: string, The command to be executed.
171            env: Enviroment variables to add to the remote envirment.
172
173        Returns:
174            A string that represents the command line to execute on the remote
175            machine.
176        """
177        if not env:
178            env_str = ''
179        else:
180            env_str = 'export '
181            for name in env:
182                value = env[name]
183                env_str += '%s=%s ' % (name, str(value))
184            env_str += ';'
185
186        execution_line = '%s %s;' % (env_str, command)
187        return execution_line
188
189    def format_command(self,
190                       command,
191                       env,
192                       settings,
193                       extra_flags={},
194                       extra_options={}):
195        """Formats a full command.
196
197        Formats the full command to run in order to run a command on a remote
198        machine.
199
200        Args:
201            command: The command to run on the remote machine. Can either be
202                     a string or a list.
203            env: The enviroment variables to include on the remote machine.
204            settings: The ssh settings to use.
205            extra_flags: Extra flags to include with the settings.
206            extra_options: Extra options to include with the settings.
207        """
208        remote_command = self.format_remote_command(command, env)
209        return self.format_ssh_command(remote_command, settings, extra_flags,
210                                       extra_options)
211