Skip to content

Instantly share code, notes, and snippets.

@aruruka
Last active September 18, 2023 07:21
Show Gist options
  • Save aruruka/146d4f630780f08f4911703cb3d000d1 to your computer and use it in GitHub Desktop.
Save aruruka/146d4f630780f08f4911703cb3d000d1 to your computer and use it in GitHub Desktop.
Transfer specified files from local host to remote hosts.Usage: `python3 file_transferer_allower.py <files_to_be_transferred_dir> <included_files> <remote_servers>`.Example: `python3 file_transferer_allower.py '/opt/mapr/conf/ca/' './CaCerts.txt' './remote_servers.txt'`
#!/usr/bin/env python3
import os
import paramiko
import argparse
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"files_to_be_transferred_dir", help="Directory path of files to be transferred"
)
parser.add_argument(
"included_files",
help="Path of the file containing a list of files or folders to be included",
)
parser.add_argument(
"remote_servers", help="Path of the file containing a list of remote servers"
)
args = parser.parse_args()
with open(args.included_files) as inf:
included_files = set(line.strip() for line in inf if line.strip())
with open(args.remote_servers) as rs:
remote_servers = [line.strip() for line in rs if line.strip()]
for root, dirs, files in os.walk(args.files_to_be_transferred_dir):
for name in files:
file_path = os.path.join(root, name)
relative_path = os.path.relpath(file_path, args.files_to_be_transferred_dir)
if relative_path not in included_files:
continue
for server in remote_servers:
transfer_file(server, file_path, file_path)
def transfer_file(server, source_file, file_path):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(server)
sftp = ssh.open_sftp()
remote_path = os.path.join("/", file_path)
remote_dir = os.path.dirname(remote_path)
try:
sftp.stat(remote_dir)
except IOError:
print(f'Creating {remote_dir} on {server}')
ssh.exec_command(f"mkdir -p {remote_dir}")
print(f"Transferring {source_file} to {server}:{remote_path}")
sftp.put(source_file, remote_path)
local_file_stat = sftp.stat(source_file)
remote_file_stat = sftp.stat(remote_path)
remote_file_stat.st_uid = local_file_stat.st_uid
remote_file_stat.st_gid = local_file_stat.st_gid
remote_file_stat.st_mode = local_file_stat.st_mode
sftp.chattr(remote_path, remote_file_stat)
sftp.close()
ssh.close()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment