portacode 1.4.15.dev19__py3-none-any.whl → 1.4.15.dev21__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.
portacode/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '1.4.15.dev19'
32
- __version_tuple__ = version_tuple = (1, 4, 15, 'dev19')
31
+ __version__ = version = '1.4.15.dev21'
32
+ __version_tuple__ = version_tuple = (1, 4, 15, 'dev21')
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -608,20 +608,28 @@ def _build_bootstrap_steps(
608
608
  steps.extend(
609
609
  [
610
610
  {"name": "user_exists", "cmd": f"id -u {user} >/dev/null 2>&1 || adduser --disabled-password --gecos '' {user}", "retries": 0},
611
- {
612
- "name": "add_sudo",
613
- "cmd": (
614
- f"if command -v usermod >/dev/null 2>&1; then "
615
- f"usermod -aG sudo {user}; "
616
- "else "
617
- " addgroup wheel >/dev/null 2>&1 || true; "
618
- " addgroup sudo >/dev/null 2>&1 || true; "
619
- f" addgroup {user} wheel >/dev/null 2>&1 || true; "
620
- f" addgroup {user} sudo >/dev/null 2>&1 || true; "
621
- "fi"
622
- ),
623
- "retries": 0,
624
- },
611
+ {
612
+ "name": "add_sudo",
613
+ "cmd": (
614
+ f"if command -v usermod >/dev/null 2>&1; then "
615
+ " if ! getent group sudo >/dev/null 2>&1; then "
616
+ " if command -v groupadd >/dev/null 2>&1; then "
617
+ " groupadd sudo >/dev/null 2>&1 || true; "
618
+ " fi; "
619
+ " fi; "
620
+ f" usermod -aG sudo {user}; "
621
+ "else "
622
+ " for grp in wheel sudo; do "
623
+ " if ! getent group \"$grp\" >/dev/null 2>&1 && command -v groupadd >/dev/null 2>&1; then "
624
+ " groupadd \"$grp\" >/dev/null 2>&1 || true; "
625
+ " fi; "
626
+ " addgroup \"$grp\" >/dev/null 2>&1 || true; "
627
+ f" addgroup {user} \"$grp\" >/dev/null 2>&1 || true; "
628
+ " done; "
629
+ "fi"
630
+ ),
631
+ "retries": 0,
632
+ },
625
633
  ]
626
634
  )
627
635
  if password:
@@ -884,6 +892,10 @@ def _run_pct(vmid: int, cmd: str, input_text: Optional[str] = None) -> Dict[str,
884
892
  }
885
893
 
886
894
 
895
+ def _su_command(user: str, command: str) -> str:
896
+ return f"su - {user} -s /bin/sh -c {shlex.quote(command)}"
897
+
898
+
887
899
  def _run_pct_check(vmid: int, cmd: str) -> Dict[str, Any]:
888
900
  res = _run_pct(vmid, cmd)
889
901
  if res["returncode"] != 0:
@@ -943,7 +955,7 @@ def _push_bytes_to_container(
943
955
 
944
956
 
945
957
  def _resolve_portacode_key_dir(vmid: int, user: str) -> str:
946
- data_dir_cmd = f"su - {user} -c 'echo -n ${{XDG_DATA_HOME:-$HOME/.local/share}}'"
958
+ data_dir_cmd = _su_command(user, "echo -n ${XDG_DATA_HOME:-$HOME/.local/share}")
947
959
  data_home = _run_pct_check(vmid, data_dir_cmd)["stdout"].strip()
948
960
  portacode_dir = f"{data_home}/portacode"
949
961
  _run_pct_exec_check(vmid, ["mkdir", "-p", portacode_dir])
@@ -960,18 +972,19 @@ def _deploy_device_keypair(vmid: int, user: str, private_key: str, public_key: s
960
972
 
961
973
 
962
974
  def _portacode_connect_and_read_key(vmid: int, user: str, timeout_s: int = 10) -> Dict[str, Any]:
963
- cmd = ["pct", "exec", str(vmid), "--", "bash", "-lc", f"su - {user} -c 'portacode connect'"]
975
+ su_connect_cmd = _su_command(user, "portacode connect")
976
+ cmd = ["pct", "exec", str(vmid), "--", "/bin/sh", "-c", su_connect_cmd]
964
977
  proc = subprocess.Popen(cmd, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
965
978
  start = time.time()
966
979
 
967
- data_dir_cmd = f"su - {user} -c 'echo -n ${{XDG_DATA_HOME:-$HOME/.local/share}}'"
980
+ data_dir_cmd = _su_command(user, "echo -n ${XDG_DATA_HOME:-$HOME/.local/share}")
968
981
  data_dir = _run_pct_check(vmid, data_dir_cmd)["stdout"].strip()
969
982
  key_dir = f"{data_dir}/portacode/keys"
970
983
  pub_path = f"{key_dir}/id_portacode.pub"
971
984
  priv_path = f"{key_dir}/id_portacode"
972
985
 
973
986
  def file_size(path: str) -> Optional[int]:
974
- stat_cmd = f"su - {user} -c 'test -s {path} && stat -c %s {path}'"
987
+ stat_cmd = _su_command(user, f"test -s {path} && stat -c %s {path}")
975
988
  res = _run_pct(vmid, stat_cmd)
976
989
  if res["returncode"] != 0:
977
990
  return None
@@ -1029,7 +1042,7 @@ def _portacode_connect_and_read_key(vmid: int, user: str, timeout_s: int = 10) -
1029
1042
  final_pub = file_size(pub_path)
1030
1043
  final_priv = file_size(priv_path)
1031
1044
  if final_pub and final_priv:
1032
- key_res = _run_pct(vmid, f"su - {user} -c 'cat {pub_path}'")
1045
+ key_res = _run_pct(vmid, _su_command(user, f"cat {pub_path}"))
1033
1046
  if not process_exited:
1034
1047
  proc.terminate()
1035
1048
  try:
@@ -1069,7 +1082,7 @@ def _portacode_connect_and_read_key(vmid: int, user: str, timeout_s: int = 10) -
1069
1082
  except subprocess.TimeoutExpired:
1070
1083
  proc.kill()
1071
1084
 
1072
- key_res = _run_pct(vmid, f"su - {user} -c 'cat {pub_path}'")
1085
+ key_res = _run_pct(vmid, _su_command(user, f"cat {pub_path}"))
1073
1086
  return {
1074
1087
  "ok": True,
1075
1088
  "public_key": key_res["stdout"].strip(),
@@ -1612,7 +1625,7 @@ class CreateProxmoxContainerHandler(SyncHandler):
1612
1625
  on_behalf_of_device=device_id,
1613
1626
  )
1614
1627
 
1615
- cmd = f"su - {payload['username']} -c 'sudo -S portacode service install'"
1628
+ cmd = _su_command(payload["username"], "sudo -S portacode service install")
1616
1629
  res = _run_pct(vmid, cmd, input_text=payload["password"] + "\n")
1617
1630
 
1618
1631
  if res["returncode"] != 0:
@@ -1744,7 +1757,7 @@ class StartPortacodeServiceHandler(SyncHandler):
1744
1757
  on_behalf_of_device=on_behalf_of_device,
1745
1758
  )
1746
1759
 
1747
- cmd = f"su - {user} -c 'sudo -S portacode service install'"
1760
+ cmd = _su_command(user, "sudo -S portacode service install")
1748
1761
  res = _run_pct(vmid, cmd, input_text=password + "\n")
1749
1762
 
1750
1763
  if res["returncode"] != 0:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: portacode
3
- Version: 1.4.15.dev19
3
+ Version: 1.4.15.dev21
4
4
  Summary: Portacode CLI client and SDK
5
5
  Home-page: https://github.com/portacode/portacode
6
6
  Author: Meena Erian
@@ -1,7 +1,7 @@
1
1
  portacode/README.md,sha256=4dKtpvR8LNgZPVz37GmkQCMWIr_u25Ao63iW56s7Ke4,775
2
2
  portacode/__init__.py,sha256=oB3sV1wXr-um-RXio73UG8E5Xx6cF2ZVJveqjNmC-vQ,1086
3
3
  portacode/__main__.py,sha256=jmHTGC1hzmo9iKJLv-SSYe9BSIbPPZ2IOpecI03PlTs,296
4
- portacode/_version.py,sha256=SHpiSRJiC6Gyo_LZbcMuMheGquhQYp8kpipHfjZ1VCs,721
4
+ portacode/_version.py,sha256=U9P73QDPcoNTjwvbpqz9ybWnBOiKr03eV2nhMcRk5Xo,721
5
5
  portacode/cli.py,sha256=mGLKoZ-T2FBF7IA9wUq0zyG0X9__-A1ao7gajjcVRH8,21828
6
6
  portacode/data.py,sha256=5-s291bv8J354myaHm1Y7CQZTZyRzMU3TGe5U4hb-FA,1591
7
7
  portacode/keypair.py,sha256=0OO4vHDcF1XMxCDqce61xFTlFwlTcmqe5HyGsXFEt7s,5838
@@ -22,7 +22,7 @@ portacode/connection/handlers/diff_handlers.py,sha256=iYTIRCcpEQ03vIPKZCsMTE5aZb
22
22
  portacode/connection/handlers/file_handlers.py,sha256=nAJH8nXnX07xxD28ngLpgIUzcTuRwZBNpEGEKdRqohw,39507
23
23
  portacode/connection/handlers/project_aware_file_handlers.py,sha256=AqgMnDqX2893T2NsrvUSCwjN5VKj4Pb2TN0S_SuboOE,9803
24
24
  portacode/connection/handlers/project_state_handlers.py,sha256=v6ZefGW9i7n1aZLq2jOGumJIjYb6aHlPI4m1jkYewm8,1686
25
- portacode/connection/handlers/proxmox_infra.py,sha256=6ILb0nSisU44UziVkONaVsYJSHjkvIMNP8x0oxAUgYo,70249
25
+ portacode/connection/handlers/proxmox_infra.py,sha256=xm2utGUde1wZjH_ltMJHTL1Ibvxh_LYgeHmfFi4zUIw,70766
26
26
  portacode/connection/handlers/registry.py,sha256=qXGE60sYEWg6ZtVQzFcZ5YI2XWR6lMgw4hAL9x5qR1I,6181
27
27
  portacode/connection/handlers/session.py,sha256=uNGfiO_1B9-_yjJKkpvmbiJhIl6b-UXlT86UTfd6WYE,42219
28
28
  portacode/connection/handlers/system_handlers.py,sha256=fr12QpOr_Z8KYGUU-AYrTQwRPAcrLK85hvj3SEq1Kw8,14757
@@ -65,7 +65,7 @@ portacode/utils/__init__.py,sha256=NgBlWTuNJESfIYJzP_3adI1yJQJR0XJLRpSdVNaBAN0,3
65
65
  portacode/utils/diff_apply.py,sha256=4Oi7ft3VUCKmiUE4VM-OeqO7Gk6H7PF3WnN4WHXtjxI,15157
66
66
  portacode/utils/diff_renderer.py,sha256=S76StnQ2DLfsz4Gg0m07UwPfRp8270PuzbNaQq-rmYk,13850
67
67
  portacode/utils/ntp_clock.py,sha256=VqCnWCTehCufE43W23oB-WUdAZGeCcLxkmIOPwInYHc,2499
68
- portacode-1.4.15.dev19.dist-info/licenses/LICENSE,sha256=2FGbCnUDgRYuQTkB1O1dUUpu5CVAjK1j4_p6ack9Z54,1066
68
+ portacode-1.4.15.dev21.dist-info/licenses/LICENSE,sha256=2FGbCnUDgRYuQTkB1O1dUUpu5CVAjK1j4_p6ack9Z54,1066
69
69
  test_modules/README.md,sha256=Do_agkm9WhSzueXjRAkV_xEj6Emy5zB3N3VKY5Roce8,9274
70
70
  test_modules/__init__.py,sha256=1LcbHodIHsB0g-g4NGjSn6AMuCoGbymvXPYLOb6Z7F0,53
71
71
  test_modules/test_device_online.py,sha256=QtYq0Dq9vME8Gp2O4fGSheqVf8LUtpsSKosXXk56gGM,1654
@@ -91,8 +91,8 @@ testing_framework/core/playwright_manager.py,sha256=Tw46qwxIhOFkS48C2IWIQHHNpEe-
91
91
  testing_framework/core/runner.py,sha256=j2QwNJmAxVBmJvcbVS7DgPJUKPNzqfLmt_4NNdaKmZU,19297
92
92
  testing_framework/core/shared_cli_manager.py,sha256=BESSNtyQb7BOlaOvZmm04T8Uezjms4KCBs2MzTxvzYQ,8790
93
93
  testing_framework/core/test_discovery.py,sha256=2FZ9fJ8Dp5dloA-fkgXoJ_gCMC_nYPBnA3Hs2xlagzM,4928
94
- portacode-1.4.15.dev19.dist-info/METADATA,sha256=JJoI5trJDjoXJyfMRfg2wL9S0EqmMalHzgYahQnyehc,13052
95
- portacode-1.4.15.dev19.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
96
- portacode-1.4.15.dev19.dist-info/entry_points.txt,sha256=lLUUL-BM6_wwe44Xv0__5NQ1BnAz6jWjSMFvZdWW3zU,48
97
- portacode-1.4.15.dev19.dist-info/top_level.txt,sha256=TGhTYUxfW8SyVZc_zGgzjzc24gGT7nSw8Qf73liVRKM,41
98
- portacode-1.4.15.dev19.dist-info/RECORD,,
94
+ portacode-1.4.15.dev21.dist-info/METADATA,sha256=e65XngiIyI4jPmQqu43qYc3XVYJfYwzQJQAlftfm2ww,13052
95
+ portacode-1.4.15.dev21.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
96
+ portacode-1.4.15.dev21.dist-info/entry_points.txt,sha256=lLUUL-BM6_wwe44Xv0__5NQ1BnAz6jWjSMFvZdWW3zU,48
97
+ portacode-1.4.15.dev21.dist-info/top_level.txt,sha256=TGhTYUxfW8SyVZc_zGgzjzc24gGT7nSw8Qf73liVRKM,41
98
+ portacode-1.4.15.dev21.dist-info/RECORD,,