import os SUDO_REMOTE=True #SSH_ARGS='-C -o ControlMaster=auto -o ControlPersist=60s -o ControlPath=~/.ssh/controlmasters/%r@%h:%p -o PreferredAuthentications=publickey' SSH_ARGS='' def get_config(): config_path = os.environ.get('SSH_HELPER_HOST_LIST') config = {} with open(config_path, 'r') as f: for line in f: if line[0] not in ('#', ' ', '\n'): connection_name, host, user, port, *_ = line.split() config[connection_name] = { 'host': host, 'user': user, 'port': port } return config def parse_arg(s): # Парсим путь. Разделяем на 3 части: # хост - если не указан, то вызвращает local # work_path - рабочая директория # obj - обхект в рабочей директории if s.find(':') > -1: connection_name, path = s.split(':') else: connection_name = 'local' path = s if path == '': path = '/' if path[0] not in ('/', '~', '.'): if connection_name == 'local': path = './' + path else: path = '~/' + path last_slash = path.rfind('/') work_path = path[0:last_slash] if len(work_path) == 0: work_path = '/' obj = path[last_slash+1:] return { 'connection_name': connection_name, 'work_path': work_path, 'obj': obj } def make_pack_cmd(work_path, obj): assert obj is not None assert len(obj) > 0 cmd = f'tar -C {work_path} -c {obj}' return cmd def make_unpack_cmd(work_path, obj): if work_path == '/': work_path = '' cmd = f'tar -C {work_path}/{obj} -x' return cmd def add_sudo(s): res = 'sudo ' + s return res def make_ssh_cmd(host, port, user, cmd): res = f"/usr/bin/ssh {user}@{host} {SSH_ARGS} -p {port} '{cmd}'" return res def get_connection_config(con_name): # Получаем конфигурацию подключения по SSH config_path = os.environ.get('SSH_HELPER_HOST_LIST') res = None with open(config_path, 'r') as f: for line in f: if line[0] not in ('#', ' ', '\n'): connection_name, host, user, port, *_ = line.split() if connection_name == con_name: res = { 'connection_name': connection_name, 'host': host, 'user': user, 'port': port } break if res is None: raise Exception('Connection name not found') return res def get_path_config(path): # Объединяем конфигурацию пути и конфигурацию подключения, если подключение удаленное config = parse_arg(path) if config['connection_name'] != 'local': res_config = { **config, **get_connection_config( config['connection_name'] ) } else: res_config = config return res_config def make_full_cmd(config, tar_func): cmd = tar_func(config['work_path'], config['obj']) if SUDO_REMOTE and config['connection_name'] != 'local': cmd = add_sudo(cmd) if config['connection_name'] != 'local': cmd = make_ssh_cmd( config['host'], config['port'], config['user'], cmd ) return cmd