def _run_ssh_command(entries, username, idfile, command, tunnel, parallel=False): """ Runs the given command over SSH in parallel on all hosts in `entries`. :param entries: The host entries the hostnames from. :type entries: ``list`` of :py:class:`HostEntry` :param username: To use a specific username. :type username: ``str`` or ``NoneType`` :param idfile: The SSH identity file to use, or none. :type idfile: ``str`` or ``NoneType`` :param command: The command to run. :type command: ``str`` :param parallel: If true, commands will be run in parallel. :type parallel: ``bool`` """ if len(entries) == 0: print('(No hosts to run command on)') return 1 if command.strip() == '' or command is None: raise ValueError('No command given') print('Running command {0} on {1} matching hosts' .format(green(repr(command)), len(entries))) shell_cmds = [] for entry in entries: hname = entry.hostname or entry.public_ip cmd = _build_ssh_command(hname, username, idfile, command, tunnel) shell_cmds.append({ 'command': cmd, 'description': entry.display() }) stream_commands(shell_cmds, parallel=parallel) print(green('All commands finished'))
def _copy_to(entries, remote_path, local_path, profile): """ Performs an SCP command where the remote_path is the target and the local_path is the source. :param entries: A list of entries. :type entries: ``list`` of :py:class:`HostEntry` :param remote_path: The target path on the remote machine(s). :type remote_path: ``str`` :param local_path: The source path on the local machine. :type local_path: ``str`` :param profile: The profile, holding username/idfile info, etc. :type profile: :py:class:`Profile` """ commands = [] for entry in entries: hname = entry.hostname or entry.public_ip cmd = _build_scp_command(hname, profile.username, profile.identity_file, is_get=False, local_path=local_path, remote_path=remote_path) print('Command:', cmd) commands.append({ 'command': cmd, 'description': entry.display() }) stream_commands(commands) print(green('Finished copying'))
def _copy_from(entries, remote_path, local_path, profile): """ Performs an SCP command where the remote_path is the source and the local_path is a format string, formatted individually for each host being copied from so as to create one or more distinct paths on the local system. :param entries: A list of entries. :type entries: ``list`` of :py:class:`HostEntry` :param remote_path: The source path on the remote machine(s). :type remote_path: ``str`` :param local_path: A format string for the path on the local machine. :type local_path: ``str`` :param profile: The profile, holding username/idfile info, etc. :type profile: :py:class:`Profile` """ commands = [] paths = set() for entry in entries: hname = entry.hostname or entry.public_ip _local_path = entry.format_string(local_path) if _local_path in paths: raise ValueError('Duplicate local paths: one or more paths ' 'had value {} after formatting.' .format(local_path)) paths.add(_local_path) # If the path references a folder, create the folder if it doesn't # exist. _folder = os.path.split(_local_path)[0] if len(_folder) > 0: if not os.path.exists(_folder): print('Creating directory ' + _folder) os.makedirs(_folder) cmd = _build_scp_command(hname, profile.username, profile.identity_file, is_get=True, local_path=_local_path, remote_path=remote_path) print('Command:', cmd) commands.append({ 'command': cmd, 'description': entry.display() }) stream_commands(commands) print(green('Finished copying'))