addftool 0.1.3__py3-none-any.whl → 0.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,35 @@
1
+ import argparse
2
+
3
+ from .ssh_server import add_deploy_ssh_server_args, deploy_ssh_server_main
4
+ from .azure import add_deploy_azure_args, deploy_azure_main
5
+
6
+
7
+ def add_deploy_args(subparsers: argparse._SubParsersAction):
8
+ """
9
+ Add deploy arguments to the parser.
10
+ Args:
11
+ subparsers (argparse._SubParsersAction): The subparsers object to add the arguments to.
12
+ """
13
+ deploy_parsers = subparsers.add_parser('deploy', help='deploy/install software, script, tools, etc.')
14
+ deploy_subparsers = deploy_parsers.add_subparsers(dest='deploy_type', help='Deploy options')
15
+
16
+ ssh_server_parser = deploy_subparsers.add_parser('ssh-server', help='SSH options')
17
+ add_deploy_ssh_server_args(ssh_server_parser)
18
+
19
+ azure_parser = deploy_subparsers.add_parser('azure', help='Azure options')
20
+ add_deploy_azure_args(azure_parser)
21
+
22
+
23
+ def deploy_main(args):
24
+ """
25
+ Main function for deploy.
26
+ Args:
27
+ args (argparse.Namespace): The parsed arguments.
28
+ """
29
+ if args.deploy_type == 'ssh-server':
30
+ deploy_ssh_server_main(args)
31
+ elif args.deploy_type == 'azure':
32
+ deploy_azure_main(args)
33
+ else:
34
+ print("Unknown deploy type")
35
+ print("Deploy type: ", args.deploy_type)
@@ -0,0 +1,39 @@
1
+ from addftool.util import need_sudo, execute_command, get_ubuntu_version, install_packages
2
+
3
+
4
+ def deploy_azure(packages):
5
+ ubuntu_version = get_ubuntu_version()
6
+ print("Get ubuntu version: ", ubuntu_version)
7
+
8
+ command = f"wget https://packages.microsoft.com/config/ubuntu/{ubuntu_version}/packages-microsoft-prod.deb -O /tmp/packages-microsoft-prod.deb"
9
+ print("Install packages-microsoft-prod.deb")
10
+ execute_command(command)
11
+ command_prefix = "sudo " if need_sudo() else ""
12
+ command = "dpkg -i /tmp/packages-microsoft-prod.deb"
13
+ execute_command(command_prefix + command)
14
+
15
+ install_packages(packages)
16
+
17
+
18
+ def add_deploy_azure_args(parser):
19
+ """
20
+ Add Azure deployment arguments to the parser.
21
+ Args:
22
+ parser (argparse.ArgumentParser): The argument parser to add the arguments to.
23
+ """
24
+ parser.add_argument("packages", help="packages", default=['fuse3', 'blobfuse2', 'azcopy'], nargs="*")
25
+
26
+ def deploy_azure_main(args):
27
+ # print(args.packages)
28
+ deploy_azure(args.packages)
29
+
30
+
31
+ if __name__ == "__main__":
32
+ import argparse
33
+
34
+ parser = argparse.ArgumentParser(description="Azure deployment arguments")
35
+ add_deploy_azure_args(parser)
36
+
37
+ args = parser.parse_args()
38
+
39
+ deploy_azure_main(args)
@@ -0,0 +1,137 @@
1
+ import subprocess
2
+ import argparse
3
+ import os
4
+ from addftool.util import need_sudo, execute_command, is_running_in_docker
5
+
6
+
7
+ def convert_ssh2_to_openssh(ssh2_public_key_content):
8
+ lines = ssh2_public_key_content.strip().split('\n')
9
+ encoded_key = ""
10
+ start_found = False
11
+ for line in lines:
12
+ line = line.strip()
13
+ if line == "---- BEGIN SSH2 PUBLIC KEY ----":
14
+ start_found = True
15
+ continue
16
+ elif line == "---- END SSH2 PUBLIC KEY ----":
17
+ break
18
+ elif start_found and line.startswith("Comment:"):
19
+ comment = line.split(":", 1)[1].strip().strip('"')
20
+ elif start_found:
21
+ encoded_key += line
22
+
23
+ if encoded_key:
24
+ # Assuming it's an RSA key based on the comment
25
+ openssh_key = f"ssh-rsa {encoded_key} \"{comment}\""
26
+ return openssh_key
27
+ else:
28
+ return None
29
+
30
+
31
+ def parse_key_from_file(file_path):
32
+ """
33
+ 解析 SSH 公钥文件,支持 SSH2 和 OpenSSH 格式
34
+ :param file_path: 公钥文件路径
35
+ :return: 公钥内容
36
+ """
37
+ with open(file_path, "r") as f:
38
+ content = f.read()
39
+ if "---- BEGIN SSH2 PUBLIC KEY ----" in content:
40
+ return convert_ssh2_to_openssh(content)
41
+ else:
42
+ return content.strip()
43
+
44
+
45
+ def configure_ssh_on_ubuntu(port, username, ssh_public_key="", password=""):
46
+ if not is_running_in_docker():
47
+ print("This script is not running in a Docker container. Exiting...")
48
+ return
49
+ print(f"deploy ssh server on port: {port}, username: {username}, ssh_public_key: {ssh_public_key}, password: {password is not None}")
50
+ if not(len(ssh_public_key) > 0 or len(password) > 0):
51
+ print("ssh_public_key or password must be provided.")
52
+ return
53
+ command_prefix = "sudo " if need_sudo() else ""
54
+ try:
55
+ need_install_ssh = True
56
+ try:
57
+ # execute_command(["which", "sshd"])
58
+ response = execute_command("which sshd", only_stdout=False)
59
+ if response["returncode"] == 0:
60
+ print("SSH server is already installed.")
61
+ need_install_ssh = False
62
+ except subprocess.CalledProcessError:
63
+ pass
64
+ if need_install_ssh:
65
+ print("SSH server is not installed. Installing...")
66
+ execute_command(command_prefix + "apt-get update")
67
+ execute_command(command_prefix + "apt-get install -y openssh-server")
68
+
69
+ print("Modifying SSH configuration...")
70
+ execute_command(command_prefix + f'sed -i "s/#Port 22/Port {port}/" /etc/ssh/sshd_config')
71
+ execute_command(command_prefix + 'sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/" /etc/ssh/sshd_config')
72
+
73
+ if not os.path.exists("/etc/ssh/ssh_host_rsa_key"):
74
+ print("SSH host keys not found. Generating new keys...")
75
+ execute_command(command_prefix + 'ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ""')
76
+
77
+ print(f'Creating user {username} and configuring SSH key...')
78
+ try:
79
+ # run_command(["id", "-u", username])
80
+ execute_command(command_prefix + f"id -u {username}")
81
+ except subprocess.CalledProcessError:
82
+ print(f"User {username} does not exist. Creating user...")
83
+ execute_command(command_prefix + f"useradd -m -s /bin/bash {username}")
84
+
85
+ ssh_dir = f"/home/{username}/.ssh" if username != "root" else "/root/.ssh"
86
+ authorized_keys_file = f"{ssh_dir}/authorized_keys"
87
+
88
+
89
+ execute_command(command_prefix + f"mkdir -p {ssh_dir}")
90
+ execute_command(command_prefix + f"chmod 700 {ssh_dir}")
91
+
92
+ if ssh_public_key:
93
+ key_content = parse_key_from_file(ssh_public_key)
94
+ execute_command(command_prefix + f"bash -c 'echo \"{key_content}\" >> {authorized_keys_file}'", hide=True)
95
+ execute_command(command_prefix + f"chmod 600 {authorized_keys_file}")
96
+ execute_command(command_prefix + f"chown -R {username}:{username} {ssh_dir}")
97
+
98
+ if password:
99
+ execute_command(command_prefix + f"echo '{username}:{password}' | chpasswd", hide=True)
100
+
101
+ print("Restarting SSH service...")
102
+ # run_command(["sudo", "systemctl", "restart", "ssh"])
103
+ execute_command("/etc/init.d/ssh restart")
104
+
105
+ print(f"ssh is configured! You can connect using the following command: ssh -p {port} {username}@<host_ip>")
106
+
107
+ except subprocess.CalledProcessError as e:
108
+ print(f"Command called process error: {e}")
109
+ except FileNotFoundError as e:
110
+ print(f"File not found error: {e}")
111
+ except Exception as e:
112
+ print(f"An error occurred: {e}")
113
+
114
+ def add_deploy_ssh_server_args(parser):
115
+ """添加 SSH 配置参数"""
116
+ parser.add_argument("--port", type=int, required=True, help="SSH server port")
117
+ parser.add_argument("--username", required=True, help="SSH username")
118
+ parser.add_argument("--password", help="SSH password", type=str, default="")
119
+ parser.add_argument("--ssh-public-key", help="SSH public key", type=str, default="")
120
+
121
+
122
+
123
+ def deploy_ssh_server_main(args):
124
+ """
125
+ 部署 SSH 服务器
126
+ :param args: 命令行参数
127
+ """
128
+ configure_ssh_on_ubuntu(args.port, args.username, args.ssh_public_key, args.password)
129
+
130
+
131
+ if __name__ == "__main__":
132
+ parser = argparse.ArgumentParser(description="在 Ubuntu 系统中配置 SSH")
133
+ add_deploy_ssh_server_args(parser)
134
+
135
+ args = parser.parse_args()
136
+
137
+ deploy_ssh_server_main(args)
@@ -7,8 +7,7 @@ from .utils import get_processes, get_process_using_rocm, get_process_using_cuda
7
7
  def add_killer_args(subparsers):
8
8
  process_killer_parser = subparsers.add_parser('kill', help='process kill')
9
9
 
10
- process_killer_parser.add_argument("--prefix", help="prefix of command", default=None)
11
- process_killer_parser.add_argument("--contains", help="contains of command", default=None)
10
+ process_killer_parser.add_argument("-c", "--contains", help="contains of command", action='store_true', default=False)
12
11
  process_killer_parser.add_argument("--timeout", help="timeout of command", default=5, type=int)
13
12
  process_killer_parser.add_argument("--try_count", help="try count of command", default=3, type=int)
14
13
 
@@ -17,6 +16,8 @@ def add_killer_args(subparsers):
17
16
 
18
17
  process_killer_parser.add_argument("-v", "--view", help="view process", action='store_true', default=False)
19
18
 
19
+ process_killer_parser.add_argument("name", nargs='?', help="name of process", type=str, default="")
20
+
20
21
 
21
22
  def kill_process(processes, timeout=5, try_count=3):
22
23
  for process in processes:
@@ -57,8 +58,8 @@ def kill_process(processes, timeout=5, try_count=3):
57
58
  exit(1)
58
59
 
59
60
 
60
- def find_and_kill_process(prefix=None, contains=None, use_rocm=False, use_cuda=False, timeout=5, try_count=3, only_view=False):
61
- do_not_do_anything = prefix is None and contains is None
61
+ def find_and_kill_process(command="", contains=False, use_rocm=False, use_cuda=False, timeout=5, try_count=3, only_view=False):
62
+ do_not_do_anything = command is None or len(command) == 0
62
63
  if use_rocm:
63
64
  processes = get_process_using_rocm()
64
65
  elif use_cuda:
@@ -67,7 +68,7 @@ def find_and_kill_process(prefix=None, contains=None, use_rocm=False, use_cuda=F
67
68
  print("Use top or htop to find the process you want to kill")
68
69
  return
69
70
  else:
70
- processes = get_processes(command_prefix=prefix, prefix_contains=contains)
71
+ processes = get_processes(command=command, contains=contains)
71
72
 
72
73
  if only_view:
73
74
  print(f"Found {len(processes)} processes")
@@ -82,6 +83,6 @@ def find_and_kill_process(prefix=None, contains=None, use_rocm=False, use_cuda=F
82
83
 
83
84
  def killer_main(args):
84
85
  find_and_kill_process(
85
- args.prefix, args.contains, use_rocm=args.rocm, use_cuda=args.cuda,
86
+ args.name, args.contains, use_rocm=args.rocm, use_cuda=args.cuda,
86
87
  timeout=args.timeout, try_count=args.try_count, only_view=args.view,
87
88
  )
addftool/process/utils.py CHANGED
@@ -2,7 +2,7 @@ import psutil
2
2
  import subprocess
3
3
 
4
4
 
5
- def get_processes(command_prefix=None, prefix_contains=None, pids=None):
5
+ def get_processes(command="", contains=False, pids=None):
6
6
  """获取进程的PID和命令"""
7
7
 
8
8
  processes = []
@@ -14,10 +14,11 @@ def get_processes(command_prefix=None, prefix_contains=None, pids=None):
14
14
  continue
15
15
  if pids is not None and pid not in pids:
16
16
  continue
17
- if command_prefix and not cmdline[0] == command_prefix:
18
- continue
19
- if prefix_contains and prefix_contains not in cmdline[0]:
20
- continue
17
+ if len(command) > 0:
18
+ if contains and command not in cmdline[0]:
19
+ continue
20
+ if not contains and command != cmdline[0]:
21
+ continue
21
22
  if len(cmdline) > 1 and cmdline[1].endswith('addf'):
22
23
  continue
23
24
  processes.append({'pid': pid, 'command': cmdline})
File without changes
@@ -0,0 +1,42 @@
1
+ import os
2
+
3
+
4
+ def add_sync_args(subparsers):
5
+ process_killer_parser = subparsers.add_parser('sync', help='download and sync folder from master node to other nodes')
6
+
7
+ process_killer_parser.add_argument("--from_blob_url", help="download from blob url to master node before sync", type=str, default="")
8
+ process_killer_parser.add_argument("--sas_token", help="sas token for blob url", type=str, default="")
9
+ process_killer_parser.add_argument("--tool", help="tool name", type=str, default="torch_nccl", choices=["torch_nccl", "rsync"])
10
+ process_killer_parser.add_argument("--hostfile", help="host file, sync file from node-0 to others", type=str, default="")
11
+
12
+ # distributed downloader from blob
13
+ process_killer_parser.add_argument("--donwload_nodes", help="download nodes, default is node-0", type=int, default=1)
14
+
15
+ process_killer_parser.add_argument("folder", nargs='?', help="the folder need to sync", type=str, default="")
16
+
17
+
18
+ def sync_main(args):
19
+ print(args)
20
+ exit(0)
21
+ if args.source == "" or args.target == "":
22
+ print("Please provide source and target folder")
23
+ return
24
+
25
+ # check if source is a folder
26
+ if not os.path.isdir(args.source):
27
+ print(f"Source {args.source} is not a folder")
28
+ return
29
+
30
+ # check if target is a folder
31
+ if not os.path.isdir(args.target):
32
+ print(f"Target {args.target} is not a folder")
33
+ return
34
+
35
+ # check if source and target are the same
36
+ if os.path.abspath(args.source) == os.path.abspath(args.target):
37
+ print(f"Source and target are the same")
38
+ return
39
+
40
+ # sync source to target
41
+ command = f"rsync -avz --delete {args.source} {args.target}"
42
+ os.system(command)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: addftool
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Requires-Dist: cryptography
5
5
  Requires-Dist: requests
6
6
  Requires-Dist: PyYAML
@@ -0,0 +1,17 @@
1
+ addftool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ addftool/addf_portal.py,sha256=U52TdNcwWOEvv_C5r-guWYxn3ntzwYI2eBzJIE7IdcY,493
3
+ addftool/blob.py,sha256=NZOItDyFUIdV1tfhJZJJBEzGy296CE5NCictTzP4OPc,8282
4
+ addftool/tool.py,sha256=EuKQ2t2InN7yB-_oYLcdsA7vRqzRGTunwIxplUSqEG0,2054
5
+ addftool/util.py,sha256=Q3A68vJDxgfeNiEFmk54HuMuworVndocXpSbVpvGMfc,362
6
+ addftool/deploy/__init__.py,sha256=tpyoTh3SqAQojPizsJDvQohu1Pcb3-w-DP5sO4-5lBM,1220
7
+ addftool/deploy/azure.py,sha256=UQR1hOEYUtsm2fbWBczsnEB_mh7yUuN2NDv3sgMMsac,1246
8
+ addftool/deploy/ssh_server.py,sha256=f2T8fgwACVljPfdcimMywUjsFnLCWRde7iWPAILpRz8,5463
9
+ addftool/process/__init__.py,sha256=OB-cZXP1jK7l8uN8nKfhg_bCX6Slz6DeeBpEodt-IK4,3515
10
+ addftool/process/utils.py,sha256=me4HqMz5OgRcQMUJmVhKdTJh4SW5BB-pd_lq7g8-UwE,2252
11
+ addftool/ssh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ addftool/sync/__init__.py,sha256=wOqFCOA51rFUttBjOO44W3Fc66mhX5ir2R89lsO6gR0,1702
13
+ addftool-0.1.5.dist-info/METADATA,sha256=8fCVZ1r4rS685bprhRuQE5Le7MV3gu8dbNRkvFfo05w,148
14
+ addftool-0.1.5.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
15
+ addftool-0.1.5.dist-info/entry_points.txt,sha256=9lkmuWMInwUAtev8w8poNkNd7iML9Bjd5CBCFVxg2b8,111
16
+ addftool-0.1.5.dist-info/top_level.txt,sha256=jqj56-plrBbyzY0tIxB6wPzjAA8kte4hUlajyyQygN4,9
17
+ addftool-0.1.5.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- addftool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- addftool/addf_portal.py,sha256=U52TdNcwWOEvv_C5r-guWYxn3ntzwYI2eBzJIE7IdcY,493
3
- addftool/blob.py,sha256=NZOItDyFUIdV1tfhJZJJBEzGy296CE5NCictTzP4OPc,8282
4
- addftool/tool.py,sha256=EuKQ2t2InN7yB-_oYLcdsA7vRqzRGTunwIxplUSqEG0,2054
5
- addftool/util.py,sha256=Q3A68vJDxgfeNiEFmk54HuMuworVndocXpSbVpvGMfc,362
6
- addftool/process/__init__.py,sha256=EFJ90RcF04M4imGm5NLgb9rmpwxBslZUL_4LKA52uv8,3487
7
- addftool/process/utils.py,sha256=kS1bYYiWymB1_SObqQLfGiVbZdCJqd57SO6DrwN5H1s,2246
8
- addftool-0.1.3.dist-info/METADATA,sha256=YwSmBYP8v9T_PnVr-3WM-V2KkCcPg17IwMKllfp-pc0,148
9
- addftool-0.1.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
10
- addftool-0.1.3.dist-info/entry_points.txt,sha256=9lkmuWMInwUAtev8w8poNkNd7iML9Bjd5CBCFVxg2b8,111
11
- addftool-0.1.3.dist-info/top_level.txt,sha256=jqj56-plrBbyzY0tIxB6wPzjAA8kte4hUlajyyQygN4,9
12
- addftool-0.1.3.dist-info/RECORD,,