def put(local: str, remote: str, preserve_mode: bool = True) -> Result: """ Закачать файл на сервер <http://docs.fabfile.org/en/2.5/api/transfer.html#fabric.transfer.Transfer.put> :param local: путь до локального файла :param remote: путь куда сохранить на сервере :param preserve_mode: сохранить права """ t = Transfer(global_context.conn) return t.put(local=local, remote=remote, preserve_mode=preserve_mode)
def requires_connection(self): # Transfer() -> explodes try: Transfer() except TypeError: pass else: assert False, "Did not raise ArgumentError" # Transfer(Connection()) -> happy, exposes an attribute cxn = Connection('host') assert Transfer(cxn).connection is cxn
def get(remote: str, local: str, preserve_mode: bool = True) -> Result: """ Скачать файл с сервера <http://docs.fabfile.org/en/2.5/api/transfer.html#fabric.transfer.Transfer.get> :param remote: путь до файла на сервере :param local: путь куда сохранить файл :param preserve_mode: сохранить права """ t = Transfer(global_context.conn) return t.get(remote=remote, local=local, preserve_mode=preserve_mode)
def _gunicorn_service(ctx, con, env, e, app_path, app_name, conf): lines = conf.split('\n') service = os.getcwd() + '/{}.service'.format(app_name) for line in lines: with open(service, 'a+') as file: file.write(line.strip()) file.write('\n') gunicorn_service = '/etc/systemd/system/' transfer = Transfer(con) transfer.put(service, remote='/tmp', preserve_mode=True) sudorun(ctx, env, 'mv /tmp/' + app_name + '.service ' + gunicorn_service) os.remove(service)
def put_template(template_path: str, remote: str, **context: Any) -> Result: """ Отрендерить файл с помощью jinja-шаблонов и закачать на сервер См раздел templates. <http://docs.fabfile.org/en/2.5/api/transfer.html#fabric.transfer.Transfer.put> :param template_path: путь до локального файла jinja :param remote: путь куда сохранить на сервере :param context: контекс для рендеринга jinja2 """ filestr = render(template_path=template_path, **context) t = Transfer(global_context.conn) return t.put(local=BytesIO(filestr.encode()), remote=remote, preserve_mode=False)
def returns_rich_Result_object(self, transfer): cxn = Connection('host') result = Transfer(cxn).put('file') assert result.orig_remote is None assert result.remote == '/remote/file' assert result.orig_local == 'file' assert result.local == '/local/file' assert result.connection is cxn
def returns_rich_Result_object(self, transfer): cxn = Connection("host") result = Transfer(cxn).put("file") assert result.orig_remote is None assert result.remote == "/remote/file" assert result.orig_local == "file" assert result.local == "/local/file" assert result.connection is cxn
def returns_rich_Result_object(self, sftp_objs): transfer, client = sftp_objs cxn = Connection("host") result = Transfer(cxn).get("file") assert result.orig_remote == "file" assert result.remote == "/remote/file" assert result.orig_local is None assert result.local == "/local/file" assert result.connection is cxn
def returns_rich_Result_object(self, sftp_objs): transfer, client = sftp_objs cxn = Connection('host') result = Transfer(cxn).get('file') assert result.orig_remote == 'file' assert result.remote == '/remote/file' assert result.orig_local is None assert result.local == '/local/file' assert result.connection is cxn
def copy_file(server, source, target): """ Copy local file to remote server. Args: server (collection): Collection with server data source (string): File on local file system target (string): Desitination file on remote file system """ with setup_server_connection(server) as connection: Transfer(connection).put(local=source, remote=target)
def install_os_deps(self, conn, distro_info): distro_name = re.search(r"\nNAME=\"(.*)\"", distro_info, re.M).group(1) if "Ubuntu" in distro_name: distro_version = re.search(r"\nDISTRIB_RELEASE=(.*)", distro_info, re.M).group(1) conn.sudo("apt-get install python3-pip -y", hide=True) transfer = Transfer(conn) for file in os.listdir("machine_diagnostics_protocol"): if os.path.isdir(f"machine_diagnostics_protocol/{file}"): directoryname = file conn.run(f"mkdir -p {directoryname}") for sub_file in os.listdir( f"machine_diagnostics_protocol/{directoryname}"): transfer.put( f"machine_diagnostics_protocol/{directoryname}/{sub_file}", f"{directoryname}/") else: transfer.put(f"machine_diagnostics_protocol/{file}") if distro_version == "14.04": conn.sudo(f"cp /home/{self.user}/mdp.conf /etc/init", hide=True) conn.run( f"pip3 install -r /home/{self.user}/requirements.txt --user", hide=True) conn.sudo("initctl reload-configuration", hide=True) conn.sudo("service mdp restart", hide=True, pty=False) else: conn.sudo("") else: pass
def sftp(): """ Fixture allowing setup of a mocked remote SFTP session. Yields a 3-tuple of: Transfer() object, SFTPClient object, and mocked OS module. For many/most tests which only want the Transfer and/or SFTPClient objects, see `sftp_objs` and `transfer` which wrap this fixture. """ mock = MockSFTP(autostart=False) client, mock_os = mock.start() transfer = Transfer(Connection("host")) yield transfer, client, mock_os
def cli_copy_from_remote_to_local(host_ip: str, linux_user: str, linux_password: str, remote_source: str, local_destination: str) -> dict: """ CLI Run - Run a Linux command [Args] (str) host_ip: (str) linux_user: (str) linux_password: (str) cmd: [Returns] (dict) CLI Run response """ try: c = Connection(linux_user + "@" + host_ip, connect_kwargs={'password': linux_password}) t = Transfer(c) return t.get(remote=remote_source, local=local_destination, preserve_mode=True) except Exception as e: return {"Error": str(e)}
def __generate_file_command(self): """ file キーワードの解釈・コマンドのジェネレーター """ # file キーワードがなかった場合 # またはターゲットリストが空だった場合 # 何もせずに終了する if (not "file" in self.data) or len(self.__target_list) <= 0: return files = self.data["file"] # ファイル転送コマンドを構築する for send_file in files: dir_flag = False local_path = send_file["path"] remote_path = send_file["to"] # ディレクトリが指定された場合、プログラムで圧縮しファイルにする if Path(local_path).is_dir(): dir_flag = True local_path_t = Path(local_path).name output = Path(self.__worker_dir.name).joinpath(local_path_t) root_dir = Path(local_path).joinpath("..") base_dir = local_path_t local_path = shutil.make_archive(output, "tar", root_dir=root_dir, base_dir=base_dir) # 送信先のパスがファイルでなかった場合、末尾に送信ファイル名を追加する # fabric のファイル送信の仕様 if Path(remote_path).name != Path(local_path).name: remote_path = Path(remote_path) / Path(local_path).name # 送信先のパスを PosixPath に変換する remote_path = Path(remote_path).as_posix() # ターゲットリストの一覧全てに転送する for target in self.__target_list: connect = Transfer(target["target"]) # コマンドの構築 pool = { "type": "file", "target": target["target"].host, "run": connect.put, "local": local_path, "remote": remote_path } # コマンドプールへの積み込み self.__command_pool.append(pool) # ディレクトリが指定された場合、送信先で解凍する if dir_flag == True: connect = target["target"] remote_dir = Path(remote_path).parent.as_posix() remote_file = Path(remote_path).name command = "cd {} && tar -xf {} && rm -rf {}".format( remote_dir, remote_file, remote_file) # コマンドの構築 pool = { "type": "target", "target": target["target"].host, "run": connect.run, "command": command, "rollback": None } # コマンドプールへの積み込み self.__command_pool.append(pool)
def deploy(c): Transfer(c).put('docker-compose.yml', '/tmp') c.run(f'docker pull {image}') c.run(f'{all_env_cmd()} && ' + f'docker-compose -f /tmp/docker-compose.yml up -d')
def __generate_repo_command(self): """ repo キーワードの解釈・コマンドのジェネレーター """ # repo キーワードがなかった場合 # またはターゲットリストが空だった場合 # 何もせずに終了する if (not "repo" in self.data) or len(self.__target_list) <= 0: return try: from git import Repo except ImportError as e: import sys print("Please install Git command.", file=sys.stderr) exit(code=1) repos = self.data["repo"] # リポジトリ転送コマンドを構築する for repo in repos: # リポジトリのパス repo_path = repo["path"] # 転送先リモートパス remote_path = repo["to"] # TODO: Subversion 対応 # リポジトリのタイプ(Git or Subversion) repo_type = None with Path(repo_path) as p: if ".git" in p.suffix or "git@" in p.parts[0]: repo_type = "git" else: repo_type = "svn" if "type" in repo: repo_type = repo["type"] # リポジトリのブランチ branch = "master" if "branch" in repo: repo_branch = repo["branch"] # リポジトリのクローン # リポジトリ名のディレクトリを一時ディレクトリに作成しそこに clone する cloned = Repo.clone_from( repo_path, Path(self.__worker_dir.name).joinpath( Path(repo_path).name[:-len(Path(repo_path).suffix)]), branch=branch) # リポジトリのパスの取得 local_path = cloned.working_dir # プログラムで圧縮しファイルにする output = Path(self.__worker_dir.name).joinpath( Path(local_path).name) root_dir = Path(local_path).joinpath("..") base_dir = Path(local_path).name local_path = shutil.make_archive(output, "tar", root_dir=root_dir, base_dir=base_dir) # 送信先のパスがファイルでなかった場合、末尾に送信ファイル名を追加する # fabric のファイル送信の仕様 if Path(remote_path).name != Path(local_path).name: remote_path = Path(remote_path) / Path(local_path).name # 送信先のパスを PosixPath に変換する remote_path = Path(remote_path).as_posix() # ターゲットリストの一覧全てに転送する for target in self.__target_list: connect = Transfer(target["target"]) # コマンドの構築 pool = { "type": "file", "target": target["target"].host, "run": connect.put, "local": local_path, "remote": remote_path } # コマンドプールへの積み込み self.__command_pool.append(pool) # 送信先で解凍する connect = target["target"] remote_dir = Path(remote_path).parent.as_posix() remote_file = Path(remote_path).name command = "cd {} && tar -xf {} && rm -rf {}".format( remote_dir, remote_file, remote_file) # コマンドの構築 pool = { "type": "target", "target": target["target"].host, "run": connect.run, "command": command, "rollback": None } # コマンドプールへの積み込み self.__command_pool.append(pool)
def put(local: str, remote: str, preserve_mode: bool = True) -> Result: # http://docs.fabfile.org/en/2.5/api/transfer.html#fabric.transfer.Transfer.put t = Transfer(global_context.conn) return t.put(local=local, remote=remote, preserve_mode=preserve_mode)
def put_template(template_path: str, remote: str, **context) -> Result: filestr = render(template_path=template_path, **context) t = Transfer(global_context.conn) return t.put(local=StringIO(filestr), remote=remote, preserve_mode=False)