machineconfig 7.55__py3-none-any.whl → 7.57__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.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/jobs/installer/installer_data.json +8 -8
- machineconfig/scripts/python/croshell.py +4 -4
- machineconfig/scripts/python/env_manager/path_manager_tui.py +1 -1
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +18 -8
- machineconfig/scripts/python/helpers_devops/cli_self.py +3 -3
- machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +7 -2
- machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +1 -1
- machineconfig/scripts/python/helpers_utils/path.py +1 -1
- machineconfig/scripts/python/interactive.py +1 -1
- machineconfig/scripts/python/nw/devops_add_ssh_key.py +21 -5
- machineconfig/scripts/windows/mounts/mount_ssh.ps1 +1 -1
- machineconfig/settings/shells/wezterm/wezterm.lua +1 -1
- machineconfig/setup_linux/web_shortcuts/interactive.sh +10 -10
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +10 -10
- machineconfig/utils/installer_utils/installer_class.py +4 -0
- machineconfig/utils/path_extended.py +38 -17
- machineconfig/utils/ssh.py +1 -1
- {machineconfig-7.55.dist-info → machineconfig-7.57.dist-info}/METADATA +39 -5
- {machineconfig-7.55.dist-info → machineconfig-7.57.dist-info}/RECORD +22 -23
- machineconfig/scripts/python/nw/add_ssh_key.py +0 -148
- {machineconfig-7.55.dist-info → machineconfig-7.57.dist-info}/WHEEL +0 -0
- {machineconfig-7.55.dist-info → machineconfig-7.57.dist-info}/entry_points.txt +0 -0
- {machineconfig-7.55.dist-info → machineconfig-7.57.dist-info}/top_level.txt +0 -0
|
@@ -1844,12 +1844,12 @@
|
|
|
1844
1844
|
"fileNamePattern": {
|
|
1845
1845
|
"amd64": {
|
|
1846
1846
|
"linux": "miniserve-{version}-x86_64-unknown-linux-musl",
|
|
1847
|
-
"
|
|
1847
|
+
"macos": "miniserve-{version}-x86_64-apple-darwin",
|
|
1848
1848
|
"windows": "miniserve-{version}-x86_64-pc-windows-msvc.exe"
|
|
1849
1849
|
},
|
|
1850
1850
|
"arm64": {
|
|
1851
1851
|
"linux": "miniserve-{version}-aarch64-unknown-linux-musl",
|
|
1852
|
-
"
|
|
1852
|
+
"macos": "miniserve-{version}-aarch64-apple-darwin",
|
|
1853
1853
|
"windows": "miniserve-{version}-aarch64-pc-windows-msvc.exe"
|
|
1854
1854
|
}
|
|
1855
1855
|
}
|
|
@@ -2200,14 +2200,14 @@
|
|
|
2200
2200
|
"doc": "🖥️ Text-based desktop environment inside your terminal",
|
|
2201
2201
|
"fileNamePattern": {
|
|
2202
2202
|
"amd64": {
|
|
2203
|
-
"linux":
|
|
2204
|
-
"macos":
|
|
2205
|
-
"windows":
|
|
2203
|
+
"linux": "vtm_linux_x86_64.tar.7z",
|
|
2204
|
+
"macos": "vtm_macos_any.tar.7z",
|
|
2205
|
+
"windows": "vtm_windows_x86_64.7z"
|
|
2206
2206
|
},
|
|
2207
2207
|
"arm64": {
|
|
2208
|
-
"linux":
|
|
2209
|
-
"macos":
|
|
2210
|
-
"windows":
|
|
2208
|
+
"linux": "vtm_linux_arm64.tar.7z",
|
|
2209
|
+
"macos": "vtm_macos_any.tar.7z",
|
|
2210
|
+
"windows": "vtm_windows_arm64.7z"
|
|
2211
2211
|
}
|
|
2212
2212
|
}
|
|
2213
2213
|
},
|
|
@@ -107,7 +107,7 @@ def croshell(
|
|
|
107
107
|
fire_line = f"uv run --python 3.14 --with visidata,pyarrow vd {str(file_obj)}"
|
|
108
108
|
elif marimo:
|
|
109
109
|
if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""--with marimo --project "{str(Path.home().joinpath("code/machineconfig"))}" """
|
|
110
|
-
else: requirements = """--python 3.14 --with "marimo,cowsay,machineconfig[plot]>=7.
|
|
110
|
+
else: requirements = """--python 3.14 --with "marimo,cowsay,machineconfig[plot]>=7.57" """
|
|
111
111
|
fire_line = f"""
|
|
112
112
|
cd {str(pyfile.parent)}
|
|
113
113
|
uv run --python 3.14 --with "marimo" marimo convert {pyfile.name} -o marimo_nb.py
|
|
@@ -115,14 +115,14 @@ uv run {requirements} marimo edit --host 0.0.0.0 marimo_nb.py
|
|
|
115
115
|
"""
|
|
116
116
|
elif jupyter:
|
|
117
117
|
if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" --with jupyterlab """
|
|
118
|
-
else: requirements = """--with "cowsay,machineconfig[plot]>=7.
|
|
118
|
+
else: requirements = """--with "cowsay,machineconfig[plot]>=7.57" """
|
|
119
119
|
fire_line = f"uv run {requirements} jupyter-lab {str(nb_target)}"
|
|
120
120
|
elif vscode:
|
|
121
121
|
fire_line = f"""
|
|
122
122
|
cd {str(pyfile.parent)}
|
|
123
123
|
uv init --python 3.14
|
|
124
124
|
uv venv
|
|
125
|
-
uv add "cowsay,machineconfig[plot]>=7.
|
|
125
|
+
uv add "cowsay,machineconfig[plot]>=7.57"
|
|
126
126
|
# code serve-web
|
|
127
127
|
code --new-window {str(pyfile)}
|
|
128
128
|
"""
|
|
@@ -130,7 +130,7 @@ code --new-window {str(pyfile)}
|
|
|
130
130
|
if interpreter == "ipython": profile = f" --profile {ipython_profile} --no-banner"
|
|
131
131
|
else: profile = ""
|
|
132
132
|
if Path.home().joinpath("code/machineconfig").exists(): ve_line = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" """
|
|
133
|
-
else: ve_line = """--python 3.14 --with "cowsay,machineconfig[plot]>=7.
|
|
133
|
+
else: ve_line = """--python 3.14 --with "cowsay,machineconfig[plot]>=7.57" """
|
|
134
134
|
# ve_path_maybe, ipython_profile_maybe = get_ve_path_and_ipython_profile(Path.cwd())
|
|
135
135
|
# --python 3.14
|
|
136
136
|
fire_line = f"uv run {ve_line} {interpreter} {interactivity} {profile} {str(pyfile)}"
|
|
@@ -12,7 +12,9 @@ def main(
|
|
|
12
12
|
method: Annotated[Literal["symlink", "s", "copy", "c"], typer.Option(..., "--method", "-m", help="Method to use for linking files")] = "copy",
|
|
13
13
|
on_conflict: Annotated[ON_CONFLICT_LOOSE, typer.Option(..., "--on-conflict", "-o", help="Action to take on conflict")] = "throw-error",
|
|
14
14
|
sensitivity: Annotated[Literal["private", "v", "public", "b"], typer.Option(..., "--sensitivity", "-s", help="Sensitivity of the config file.")] = "private",
|
|
15
|
-
destination: Annotated[str, typer.Option("--destination", "-d", help="destination folder (override the default, use at your own risk)")] = "",
|
|
15
|
+
destination: Annotated[str, typer.Option("--destination", "-d", help="destination folder (override the default, use at your own risk)")] = "",
|
|
16
|
+
shared: Annotated[bool, typer.Option("--shared", "-sh", help="Whether the config file is shared across destinations directory.")] = False,
|
|
17
|
+
) -> None:
|
|
16
18
|
from rich.console import Console
|
|
17
19
|
from rich.panel import Panel
|
|
18
20
|
from machineconfig.utils.links import symlink_map, copy_map
|
|
@@ -27,14 +29,22 @@ def main(
|
|
|
27
29
|
console = Console()
|
|
28
30
|
orig_path = Path(file).expanduser().absolute()
|
|
29
31
|
if destination == "":
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
if shared:
|
|
33
|
+
new_path = backup_root.joinpath("shared").joinpath(orig_path.name)
|
|
34
|
+
new_path.parent.mkdir(parents=True, exist_ok=True)
|
|
35
|
+
else:
|
|
36
|
+
new_path = backup_root.joinpath(orig_path.relative_to(Path.home()))
|
|
37
|
+
new_path.parent.mkdir(parents=True, exist_ok=True)
|
|
32
38
|
else:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
if shared:
|
|
40
|
+
dest_path = Path(destination).expanduser().absolute()
|
|
41
|
+
dest_path.mkdir(parents=True, exist_ok=True)
|
|
42
|
+
new_path = dest_path.joinpath("shared").joinpath(orig_path.name)
|
|
43
|
+
new_path.parent.mkdir(parents=True, exist_ok=True)
|
|
44
|
+
else:
|
|
45
|
+
dest_path = Path(destination).expanduser().absolute()
|
|
46
|
+
dest_path.mkdir(parents=True, exist_ok=True)
|
|
47
|
+
new_path = dest_path.joinpath(orig_path.name)
|
|
38
48
|
from machineconfig.utils.path_extended import PathExtended
|
|
39
49
|
match method:
|
|
40
50
|
case "copy" | "c":
|
|
@@ -52,9 +52,9 @@ def install(no_copy_assets: Annotated[bool, typer.Option("--no-assets-copy", "-n
|
|
|
52
52
|
else:
|
|
53
53
|
import platform
|
|
54
54
|
if platform.system() == "Windows":
|
|
55
|
-
run_shell_script(r"""& "$HOME\.local\bin\uv.exe" tool install --upgrade "machineconfig>=7.
|
|
55
|
+
run_shell_script(r"""& "$HOME\.local\bin\uv.exe" tool install --upgrade "machineconfig>=7.57" """)
|
|
56
56
|
else:
|
|
57
|
-
run_shell_script("""$HOME/.local/bin/uv tool install --upgrade "machineconfig>=7.
|
|
57
|
+
run_shell_script("""$HOME/.local/bin/uv tool install --upgrade "machineconfig>=7.57" """)
|
|
58
58
|
from machineconfig.profile.create_shell_profile import create_default_shell_profile
|
|
59
59
|
if not no_copy_assets:
|
|
60
60
|
create_default_shell_profile() # involves copying assets too
|
|
@@ -79,7 +79,7 @@ def navigate():
|
|
|
79
79
|
path = Path(navigator.__file__).resolve().parent.joinpath("devops_navigator.py")
|
|
80
80
|
from machineconfig.utils.code import run_shell_script
|
|
81
81
|
if Path.home().joinpath("code/machineconfig").exists(): executable = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" --with textual"""
|
|
82
|
-
else: executable = """--with "machineconfig>=7.
|
|
82
|
+
else: executable = """--with "machineconfig>=7.57,textual" """
|
|
83
83
|
run_shell_script(f"""uv run {executable} {path}""")
|
|
84
84
|
|
|
85
85
|
|
|
@@ -54,7 +54,12 @@ def main(
|
|
|
54
54
|
else:
|
|
55
55
|
cloud_resolved = cloud
|
|
56
56
|
repo_local_root = PathExtended.cwd() if repo is None else PathExtended(repo).expanduser().absolute()
|
|
57
|
-
|
|
57
|
+
try:
|
|
58
|
+
repo_local_obj = git.Repo(repo_local_root, search_parent_directories=True)
|
|
59
|
+
except git.InvalidGitRepositoryError:
|
|
60
|
+
typer.echo(f"[red]Error:[/] The specified path '{repo_local_root}' is not a valid git repository.")
|
|
61
|
+
typer.Exit(code=1)
|
|
62
|
+
return ""
|
|
58
63
|
repo_local_root = PathExtended(repo_local_obj.working_dir) # cwd might have been in a sub directory of repo_root, so its better to redefine it.
|
|
59
64
|
PathExtended(CONFIG_ROOT).joinpath("remote").mkdir(parents=True, exist_ok=True)
|
|
60
65
|
repo_remote_root = PathExtended(CONFIG_ROOT).joinpath("remote", repo_local_root.rel2home())
|
|
@@ -99,7 +104,7 @@ git pull originEnc master
|
|
|
99
104
|
uv_project_dir = f"""{str(Path.home().joinpath("code/machineconfig"))}"""
|
|
100
105
|
uv_with = None
|
|
101
106
|
else:
|
|
102
|
-
uv_with = ["machineconfig>=7.
|
|
107
|
+
uv_with = ["machineconfig>=7.57"]
|
|
103
108
|
uv_project_dir = None
|
|
104
109
|
|
|
105
110
|
import tempfile
|
|
@@ -8,7 +8,7 @@ def analyze_repo_development(repo_path: Annotated[str, typer.Argument(..., help=
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
count_lines_path = Path(count_lines.__file__)
|
|
10
10
|
# --project $HOME/code/ machineconfig --group plot
|
|
11
|
-
cmd = f"""uv run --python 3.14 --with "machineconfig[plot]>=7.
|
|
11
|
+
cmd = f"""uv run --python 3.14 --with "machineconfig[plot]>=7.57" {count_lines_path} analyze-over-time {repo_path}"""
|
|
12
12
|
from machineconfig.utils.code import run_shell_script
|
|
13
13
|
run_shell_script(cmd)
|
|
14
14
|
|
|
@@ -17,7 +17,7 @@ def path():
|
|
|
17
17
|
uv_with = ["textual"]
|
|
18
18
|
uv_project_dir = None
|
|
19
19
|
if not Path.home().joinpath("code/machineconfig").exists():
|
|
20
|
-
uv_with.append("machineconfig>=7.
|
|
20
|
+
uv_with.append("machineconfig>=7.57")
|
|
21
21
|
else:
|
|
22
22
|
uv_project_dir = str(Path.home().joinpath("code/machineconfig"))
|
|
23
23
|
run_shell_script(get_uv_command_executing_python_script(python_script=path.read_text(encoding="utf-8"), uv_with=uv_with, uv_project_dir=uv_project_dir)[0])
|
|
@@ -95,7 +95,7 @@ def get_installation_choices() -> list[str]:
|
|
|
95
95
|
choices = [
|
|
96
96
|
Choice(value="install_machineconfig", title="🐍 Install machineconfig cli.", checked=False),
|
|
97
97
|
Choice(value="sysabc", title="📥 Install System Package Manager (Needed for other apps to be installed).", checked=False),
|
|
98
|
-
Choice(value="termabc", title="⚡ Install Terminal CLI apps essentials", checked=False),
|
|
98
|
+
Choice(value="termabc", title="⚡ Install Terminal CLI apps essentials (group `termabc`)", checked=False),
|
|
99
99
|
Choice(value="install_shell_profile", title="🐚 Configure Shell Profile And Map Other Configs.", checked=False),
|
|
100
100
|
Choice(value="install_ssh_server", title="🔒 [ADVANCED] Configure SSH Server", checked=False),
|
|
101
101
|
Choice(value="retrieve_repositories", title="📚 [ADVANCED] Retrieve Repositories", checked=False),
|
|
@@ -13,9 +13,9 @@ import typer
|
|
|
13
13
|
console = Console()
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
def get_add_ssh_key_script(path_to_key: PathExtended):
|
|
16
|
+
def get_add_ssh_key_script(path_to_key: PathExtended) -> str:
|
|
17
17
|
console.print(Panel("🔑 SSH KEY CONFIGURATION", title="[bold blue]SSH Setup[/bold blue]"))
|
|
18
|
-
if system() == "Linux":
|
|
18
|
+
if system() == "Linux" or system() == "Darwin":
|
|
19
19
|
authorized_keys = PathExtended.home().joinpath(".ssh/authorized_keys")
|
|
20
20
|
console.print(Panel(f"🐧 Linux SSH configuration\n📄 Authorized keys file: {authorized_keys}", title="[bold blue]System Info[/bold blue]"))
|
|
21
21
|
elif system() == "Windows":
|
|
@@ -35,7 +35,7 @@ def get_add_ssh_key_script(path_to_key: PathExtended):
|
|
|
35
35
|
program = ""
|
|
36
36
|
else:
|
|
37
37
|
console.print(Panel(f"➕ Adding new SSH key to authorized keys\n🔑 Key file: {path_to_key.name}", title="[bold blue]Action[/bold blue]"))
|
|
38
|
-
if system() == "Linux":
|
|
38
|
+
if system() == "Linux" or system() == "Darwin":
|
|
39
39
|
program = f"cat {path_to_key} >> ~/.ssh/authorized_keys"
|
|
40
40
|
elif system() == "Windows":
|
|
41
41
|
program_path = LIBRARY_ROOT.joinpath("setup_windows/add-sshkey.ps1")
|
|
@@ -48,14 +48,14 @@ def get_add_ssh_key_script(path_to_key: PathExtended):
|
|
|
48
48
|
raise NotImplementedError
|
|
49
49
|
else:
|
|
50
50
|
console.print(Panel(f"📝 Creating new authorized_keys file\n🔑 Using key: {path_to_key.name}", title="[bold blue]Action[/bold blue]"))
|
|
51
|
-
if system() == "Linux":
|
|
51
|
+
if system() == "Linux" or system() == "Darwin":
|
|
52
52
|
program = f"cat {path_to_key} > ~/.ssh/authorized_keys"
|
|
53
53
|
else:
|
|
54
54
|
program_path = LIBRARY_ROOT.joinpath("setup_windows/openssh-server_add-sshkey.ps1")
|
|
55
55
|
program = PathExtended(program_path).expanduser().read_text(encoding="utf-8").replace('$sshfile=""', f'$sshfile="{path_to_key}"')
|
|
56
56
|
console.print(Panel("🔧 Configured PowerShell script for Windows\n📝 Set key path in script", title="[bold blue]Configuration[/bold blue]"))
|
|
57
57
|
|
|
58
|
-
if system() == "Linux":
|
|
58
|
+
if system() == "Linux" or system() == "Darwin":
|
|
59
59
|
program += """
|
|
60
60
|
sudo chmod 700 ~/.ssh
|
|
61
61
|
sudo chmod 644 ~/.ssh/authorized_keys
|
|
@@ -66,6 +66,16 @@ sudo service ssh --full-restart
|
|
|
66
66
|
return program
|
|
67
67
|
|
|
68
68
|
|
|
69
|
+
"""
|
|
70
|
+
Common pitfalls:
|
|
71
|
+
🚫 Wrong line endings (LF/CRLF) in config files
|
|
72
|
+
🌐 Network port conflicts (try 2222 -> 2223) between WSL and Windows
|
|
73
|
+
sudo service ssh restart
|
|
74
|
+
sudo service ssh status
|
|
75
|
+
sudo nano /etc/ssh/sshd_config
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
|
|
69
79
|
def main(pub_path: Annotated[Optional[str], typer.Argument(..., help="Path to the public key file")] = None,
|
|
70
80
|
pub_choose: Annotated[bool, typer.Option(..., "--choose", "-c", help="Choose from available public keys in ~/.ssh")] = False,
|
|
71
81
|
pub_val: Annotated[bool, typer.Option(..., "--paste", "-p", help="Paste the public key content manually")] = False,
|
|
@@ -127,6 +137,12 @@ def main(pub_path: Annotated[Optional[str], typer.Argument(..., help="Path to th
|
|
|
127
137
|
console.print(Panel("🚀 SSH KEY AUTHORIZATION READY\nRun the generated script to apply changes", box=box.DOUBLE_EDGE, title_align="left"))
|
|
128
138
|
from machineconfig.utils.code import run_shell_script
|
|
129
139
|
run_shell_script(script=program)
|
|
140
|
+
import socket
|
|
141
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
142
|
+
s.connect(('8.8.8.8', 80))
|
|
143
|
+
local_ip_v4 = s.getsockname()[0]
|
|
144
|
+
s.close()
|
|
145
|
+
console.print(Panel(f"🌐 This computer is accessible at: {local_ip_v4}", title="[bold green]Network Info[/bold green]", border_style="green"))
|
|
130
146
|
console.print(Panel("✅ SSH KEY AUTHORIZATION COMPLETED", box=box.DOUBLE_EDGE, title_align="left"))
|
|
131
147
|
|
|
132
148
|
|
|
@@ -7,7 +7,7 @@ $user = ''
|
|
|
7
7
|
$sharePath = ''
|
|
8
8
|
$driveLetter = ''
|
|
9
9
|
|
|
10
|
-
uv run --python 3.14 --with "machineconfig>=7.
|
|
10
|
+
uv run --python 3.14 --with "machineconfig>=7.57" python -m machineconfig.scripts.python.mount_ssh
|
|
11
11
|
|
|
12
12
|
net use T: \\sshfs.kr\$user@$host.local
|
|
13
13
|
# this worked: net use T: \\sshfs\alex@alex-p51s-5.local
|
|
@@ -190,6 +190,6 @@ end
|
|
|
190
190
|
|
|
191
191
|
|
|
192
192
|
-- and finally, return the configuration to wezterm
|
|
193
|
-
config.enable_osc133 = false -- to silence: P>|WezTerm 20240203-110809-5046fc22\
|
|
193
|
+
-- config.enable_osc133 = false -- to silence: P>|WezTerm 20240203-110809-5046fc22\
|
|
194
194
|
|
|
195
195
|
return config
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
. <( curl -sSL "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/uv.sh")
|
|
3
3
|
. <( curl -sSL "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/scripts/linux/wrap_mcfg")
|
|
4
4
|
|
|
5
|
-
alias devops='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.
|
|
6
|
-
alias cloud='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.
|
|
7
|
-
alias agents='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.
|
|
8
|
-
alias sessions='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.
|
|
9
|
-
alias ftpx='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.
|
|
10
|
-
alias fire='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.
|
|
11
|
-
alias croshell='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.
|
|
12
|
-
alias utils='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.
|
|
13
|
-
alias terminal='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.
|
|
14
|
-
alias msearch='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.
|
|
5
|
+
alias devops='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.57" devops'
|
|
6
|
+
alias cloud='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.57" cloud'
|
|
7
|
+
alias agents='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.57" agents'
|
|
8
|
+
alias sessions='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.57" sessions'
|
|
9
|
+
alias ftpx='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.57" ftpx'
|
|
10
|
+
alias fire='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.57" fire'
|
|
11
|
+
alias croshell='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.57" croshell'
|
|
12
|
+
alias utils='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.57" utils'
|
|
13
|
+
alias terminal='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.57" terminal'
|
|
14
|
+
alias msearch='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.57" msearch'
|
|
15
15
|
|
|
16
16
|
alias d='wrap_in_shell_script devops'
|
|
17
17
|
alias c='wrap_in_shell_script cloud'
|
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
iex (iwr "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_windows/uv.ps1").Content
|
|
4
4
|
iex (iwr "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/scripts/windows/wrap_mcfg.ps1").Content
|
|
5
5
|
|
|
6
|
-
function devops { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.
|
|
7
|
-
function cloud { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.
|
|
8
|
-
function agents { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.
|
|
9
|
-
function sessions { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.
|
|
10
|
-
function ftpx { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.
|
|
11
|
-
function fire { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.
|
|
12
|
-
function croshell { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.
|
|
13
|
-
function utils { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.
|
|
14
|
-
function terminal { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.
|
|
15
|
-
function msearch { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.
|
|
6
|
+
function devops { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.57" devops $args }
|
|
7
|
+
function cloud { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.57" cloud $args }
|
|
8
|
+
function agents { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.57" agents $args }
|
|
9
|
+
function sessions { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.57" sessions $args }
|
|
10
|
+
function ftpx { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.57" ftpx $args }
|
|
11
|
+
function fire { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.57" fire $args }
|
|
12
|
+
function croshell { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.57" croshell $args }
|
|
13
|
+
function utils { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.57" utils $args }
|
|
14
|
+
function terminal { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.57" terminal $args }
|
|
15
|
+
function msearch { & "$HOME\.local\bin\uvx.exe" --python 3.14 --from "machineconfig>=7.57" msearch $args }
|
|
16
16
|
|
|
17
17
|
function d { wrap_in_shell_script devops @args }
|
|
18
18
|
function c { wrap_in_shell_script cloud @args }
|
|
@@ -200,6 +200,10 @@ class Installer:
|
|
|
200
200
|
assert download_link is not None, "download_link must be set"
|
|
201
201
|
assert version_to_be_installed is not None, "version_to_be_installed must be set"
|
|
202
202
|
downloaded = PathExtended(download_link).download(folder=INSTALL_TMP_DIR).decompress()
|
|
203
|
+
if downloaded.is_dir() and len(downloaded.search("*", r=True)) == 1:
|
|
204
|
+
only_file_in = next(downloaded.glob("*"))
|
|
205
|
+
if only_file_in.is_file() and only_file_in.suffix in [".7z", ".zip", ".tar.gz", ".tar"]: # further decompress
|
|
206
|
+
downloaded = only_file_in.decompress()
|
|
203
207
|
return downloaded, version_to_be_installed
|
|
204
208
|
|
|
205
209
|
# --------------------------- Arch / template helpers ---------------------------
|
|
@@ -480,9 +480,6 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
480
480
|
**kwargs: Any,
|
|
481
481
|
) -> "PathExtended":
|
|
482
482
|
path_resolved, slf = self._resolve_path(folder, name, path, self.name).expanduser().resolve(), self.expanduser().resolve()
|
|
483
|
-
# if use_7z: # benefits over regular zip and encrypt: can handle very large files with low memory footprint
|
|
484
|
-
# path_resolved = path_resolved + '.7z' if not path_resolved.suffix == '.7z' else path_resolved
|
|
485
|
-
# with install_n_import("py7zr").SevenZipFile(file=path_resolved, mode=mode, password=pwd) as archive: archive.writeall(path=str(slf), arcname=None)
|
|
486
483
|
arcname_obj = PathExtended(arcname or slf.name)
|
|
487
484
|
if arcname_obj.name != slf.name:
|
|
488
485
|
arcname_obj /= slf.name # arcname has to start from somewhere and end with filename
|
|
@@ -555,15 +552,6 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
555
552
|
folder = folder if not content else folder.parent
|
|
556
553
|
if slf.suffix == ".7z":
|
|
557
554
|
raise NotImplementedError("I have not implemented this yet")
|
|
558
|
-
# if overwrite: P(folder).delete(sure=True)
|
|
559
|
-
# result = folder
|
|
560
|
-
# import py7zr
|
|
561
|
-
# with py7zr.SevenZipFile(file=slf, mode='r', password=pwd) as archive:
|
|
562
|
-
# if pattern is not None:
|
|
563
|
-
# import re
|
|
564
|
-
# pat = re.compile(pattern)
|
|
565
|
-
# archive.extract(path=folder, targets=[f for f in archive.getnames() if pat.match(f)])
|
|
566
|
-
# else: archive.extractall(path=folder)
|
|
567
555
|
else:
|
|
568
556
|
if overwrite:
|
|
569
557
|
if not content:
|
|
@@ -698,19 +686,52 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
698
686
|
return ret
|
|
699
687
|
|
|
700
688
|
def decompress(self, folder: OPLike = None, name: Optional[str] = None, path: OPLike = None, inplace: bool = False, orig: bool = False, verbose: bool = True) -> "PathExtended":
|
|
701
|
-
if ".tar.gz"
|
|
689
|
+
if str(self).endswith(".tar.gz") or str(self).endswith(".tgz"):
|
|
702
690
|
# res = self.ungz_untar(folder=folder, path=path, name=name, inplace=inplace, verbose=verbose, orig=orig)
|
|
703
691
|
return self.ungz(name=f"tmp_{randstr()}.tar", inplace=inplace).untar(folder=folder, name=name, path=path, inplace=True, orig=orig, verbose=verbose) # this works for .tgz suffix as well as .tar.gz
|
|
704
|
-
elif
|
|
692
|
+
elif str(self).endswith(".tar"):
|
|
693
|
+
res = self.untar(folder=folder, name=name, path=path, inplace=inplace, orig=orig, verbose=verbose)
|
|
694
|
+
elif str(self).endswith(".gz"):
|
|
705
695
|
res = self.ungz(folder=folder, path=path, name=name, inplace=inplace, verbose=verbose, orig=orig)
|
|
706
|
-
elif ".tar.bz"
|
|
696
|
+
elif str(self).endswith(".tar.bz") or str(self).endswith(".tbz"):
|
|
707
697
|
res = self.unbz(name=f"tmp_{randstr()}.tar", inplace=inplace)
|
|
708
698
|
return res.untar(folder=folder, name=name, path=path, inplace=True, orig=orig, verbose=verbose)
|
|
709
|
-
elif ".tar.xz"
|
|
699
|
+
elif str(self).endswith(".tar.xz"):
|
|
710
700
|
# res = self.unxz_untar(folder=folder, path=path, name=name, inplace=inplace, verbose=verbose, orig=orig)
|
|
711
701
|
res = self.unxz(inplace=inplace).untar(folder=folder, name=name, path=path, inplace=True, orig=orig, verbose=verbose)
|
|
712
|
-
elif ".zip"
|
|
702
|
+
elif str(self).endswith(".zip"):
|
|
713
703
|
res = self.unzip(folder=folder, path=path, name=name, inplace=inplace, verbose=verbose, orig=orig)
|
|
704
|
+
elif str(self).endswith(".7z"):
|
|
705
|
+
def unzip_7z(archive_path: str, dest_dir: Optional[str] = None) -> Path:
|
|
706
|
+
"""
|
|
707
|
+
Uncompresses a .7z archive to a directory and returns the Path to the extraction directory.
|
|
708
|
+
|
|
709
|
+
:param archive_path: path to the .7z archive file
|
|
710
|
+
:param dest_dir: optional path to directory to extract into; if None a temporary dir will be created
|
|
711
|
+
:return: pathlib.Path pointing to the destination directory where contents were extracted
|
|
712
|
+
:raises: FileNotFoundError if archive does not exist; py7zr.Bad7zFile or other error if extraction fails
|
|
713
|
+
"""
|
|
714
|
+
import py7zr
|
|
715
|
+
import tempfile
|
|
716
|
+
from pathlib import Path
|
|
717
|
+
archive_path_obj = Path(archive_path)
|
|
718
|
+
if not archive_path_obj.is_file():
|
|
719
|
+
raise FileNotFoundError(f"Archive file not found: {archive_path_obj!r}")
|
|
720
|
+
if dest_dir is None:
|
|
721
|
+
# create a temporary directory
|
|
722
|
+
dest = Path(tempfile.mkdtemp(prefix=f"unzip7z_{archive_path_obj.stem}_"))
|
|
723
|
+
else:
|
|
724
|
+
dest = Path(dest_dir)
|
|
725
|
+
dest.mkdir(parents=True, exist_ok=True)
|
|
726
|
+
# Perform extraction
|
|
727
|
+
with py7zr.SevenZipFile(str(archive_path_obj), mode='r') as archive:
|
|
728
|
+
archive.extractall(path=str(dest))
|
|
729
|
+
# Return the extraction directory path
|
|
730
|
+
return dest
|
|
731
|
+
from machineconfig.utils.code import run_lambda_function
|
|
732
|
+
destination_dir = str(self.expanduser().resolve()).replace(".7z", "")
|
|
733
|
+
run_lambda_function(lambda: unzip_7z(archive_path=str(self), dest_dir=destination_dir), uv_project_dir=None, uv_with=["py7zr"])
|
|
734
|
+
res = PathExtended(destination_dir)
|
|
714
735
|
else:
|
|
715
736
|
res = self
|
|
716
737
|
return res
|
machineconfig/utils/ssh.py
CHANGED
|
@@ -8,7 +8,7 @@ from machineconfig.utils.terminal import Response
|
|
|
8
8
|
from machineconfig.utils.accessories import pprint, randstr
|
|
9
9
|
from machineconfig.utils.meta import lambda_to_python_script
|
|
10
10
|
UV_RUN_CMD = "$HOME/.local/bin/uv run" if platform.system() != "Windows" else """& "$env:USERPROFILE/.local/bin/uv" run"""
|
|
11
|
-
MACHINECONFIG_VERSION = "machineconfig>=7.
|
|
11
|
+
MACHINECONFIG_VERSION = "machineconfig>=7.57"
|
|
12
12
|
DEFAULT_PICKLE_SUBDIR = "tmp_results/tmp_scripts/ssh"
|
|
13
13
|
|
|
14
14
|
class SSH:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: machineconfig
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.57
|
|
4
4
|
Summary: Dotfiles management package
|
|
5
5
|
Author-email: Alex Al-Saffar <programmer@usa.com>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -51,10 +51,43 @@ Requires-Dist: python-magic>=0.4.27; extra == "plot"
|
|
|
51
51
|
</p>
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
# Welcome to
|
|
54
|
+
# 🧠 Welcome to **Machineconfig**
|
|
55
|
+
|
|
56
|
+
**Machineconfig** is a cli-based **Digital Life Manager** — It's called so because no existing category of software fully captures its scope. At the same time, it is a *Package Manager*, *Configuration Manager*, *Automation Tool*, *Dotfiles Manager*, *Data Solution*, and *Code Manager*, among other functionalities covered, all rolled into one seamless experience.
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## 💡 Motivation
|
|
60
|
+
|
|
61
|
+
But why do we need such a tool to combine all those functionalities?? Because you need one tool to manager your stack and dev-environment, put it together and maintain it.
|
|
62
|
+
Consider this concrete scenario: When setting up a new machine, VM, or Docker container, you often face dependency chains like this:
|
|
63
|
+
|
|
64
|
+
```mermaid
|
|
65
|
+
flowchart TD
|
|
66
|
+
A["Need to setup my [dev] environment"] --> B["need my tool x, e.g.: yadm"]
|
|
67
|
+
B --> C["Requires git"]
|
|
68
|
+
C --> D["Requires package manager, e.g. brew"]
|
|
69
|
+
D --> E["Requires curl"]
|
|
70
|
+
E --> F["Requires network setup / system update"]
|
|
71
|
+
F --> G["Requires system configuration access"]
|
|
72
|
+
G --> H["Finally ready to start setup the tool x."]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Machineconfig builds on shoulder of giants. A suite of best-in-class stack of projects on github are used, the most starred, active and written in Rust tools are used when possible. The goal is to provide a seamless experience that abstracts away the complexity of setting up and maintaining your digital environment. The goal of machineconfig is to replicate your setup, config, code, data and secrets on any machine, any os, in 5 minutes, using minimal user input. Then, from that point, machineconfig will help you maintain, update, backup and sync your digital life across all your devices, automatically.
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
## ⚙️ Functional Overview
|
|
79
|
+
|
|
80
|
+
| Category | Comparable Tools | Description |
|
|
81
|
+
|------------------------|----------------------------------------------|-----------------------------------------------------------|
|
|
82
|
+
| **Package Manager** | `winget`, `apt`, `brew`, `nix` | Installs and manages software packages across systems. |
|
|
83
|
+
| **Configuration Manager** | `Ansible`, `Chef`, `Puppet` | Configures and maintains system‐level preferences. |
|
|
84
|
+
| **Automation Tool** | `Airflow`, `Prefect`, `Dagster`, `Celery` | Automates repetitive tasks, pipelines, orchestration. |
|
|
85
|
+
| **Dotfiles Manager** | `chezmoi`, `yadm`, `rcm`, `GNU Stow` | Synchronises dotfiles & personal configs across systems. |
|
|
86
|
+
| **Data Solution** | `rclone`, `rsync` | Handles backups, mirroring and secure file sync. |
|
|
87
|
+
| **Code Manager** | `strong‐box`, `Vault` | Manages and protects code snippets, secrets and creds. |
|
|
88
|
+
|
|
89
|
+
---
|
|
55
90
|
|
|
56
|
-
Machineconfig is a package for managing configuration files (aka dotfiles). The idea is to collect those critical, time-consuming-files-to-setup in one directory and reference them via symbolic links from their original locations. Thus, when a new machine is to be setup, all that is required is to clone the repo in that machine and create the symbolic links.
|
|
57
|
-
Dotfiles are divided into private and public. Examples of private ones are, `~/.gitconfig`, `~/.ssh`, etc. Whereas public config files are ones like `lfrc`. The private dotfiles are placed @ `~/dotfiles`. The files therein are encrypted before backedup.
|
|
58
91
|
|
|
59
92
|
# Install On Windows:
|
|
60
93
|
|
|
@@ -68,10 +101,11 @@ iex (iwr bit.ly/cfgwindows).Content # Or, if UV is installed: iex (uvx machinec
|
|
|
68
101
|
iex (iwr bit.ly/cfgwq).Content
|
|
69
102
|
```
|
|
70
103
|
|
|
104
|
+
|
|
71
105
|
# Install On Linux and MacOS
|
|
72
106
|
|
|
73
107
|
```bash
|
|
74
|
-
# install
|
|
108
|
+
# install the tool only:
|
|
75
109
|
curl -LsSf https://astral.sh/uv/install.sh | sh # Skip if UV is already installed
|
|
76
110
|
uv tool install --upgrade --python 3.14 machineconfig
|
|
77
111
|
# interactive install of machineconfig and following on to run it and make basic machine configuration (RECOMMENDED):
|
|
@@ -51,7 +51,7 @@ machineconfig/cluster/templates/cli_trogon.py,sha256=PFWGy8SFYIhT9r3ZV4oIEYfImsQ
|
|
|
51
51
|
machineconfig/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
52
52
|
machineconfig/jobs/installer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
53
|
machineconfig/jobs/installer/check_installations.py,sha256=hkHmmT7Bx3_QWRn2v8dCKOzAapFzqHRzbe-Q08GLnKE,10743
|
|
54
|
-
machineconfig/jobs/installer/installer_data.json,sha256=
|
|
54
|
+
machineconfig/jobs/installer/installer_data.json,sha256=cG5leLVPS6wvqqdmqEWwpfrcygeYLFhEkYGO_EBAVGE,110168
|
|
55
55
|
machineconfig/jobs/installer/package_groups.py,sha256=HUCnLV6s3qkGXjT4VomOUUzMSqrUX_aJibPfPUWhYrU,4720
|
|
56
56
|
machineconfig/jobs/installer/custom/boxes.py,sha256=ws8QRbDn48oKhbQntr54I0nSfkwINbprjTy0HOpuX40,1974
|
|
57
57
|
machineconfig/jobs/installer/custom/gh.py,sha256=gn7TUSrsLx7uqFqj1Z-iYglS0EYBSgtJ9jWHxaJIfXM,4119
|
|
@@ -111,14 +111,14 @@ machineconfig/scripts/nu/wrap_mcfg.nu,sha256=9heiUHVkHjI_AMXT5QJJixk7ZK_hJNV_A8l
|
|
|
111
111
|
machineconfig/scripts/python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
112
112
|
machineconfig/scripts/python/agents.py,sha256=aVbLQDgpngXZm4taHcED4sAxyHvV2_Dz5VW3apPcQcY,10651
|
|
113
113
|
machineconfig/scripts/python/cloud.py,sha256=yAD6ciKiEtv2CH3g2NScDK5cpCZQi7Vu8yyeehw_cU8,1263
|
|
114
|
-
machineconfig/scripts/python/croshell.py,sha256=
|
|
114
|
+
machineconfig/scripts/python/croshell.py,sha256=8zYPwVanp2psAC_6XLQnfgXrlmkYVFkdjUrtssq4m_U,7132
|
|
115
115
|
machineconfig/scripts/python/define.py,sha256=AtuVac6tJeDMcxtbWmQh1TH3dYAPSGFdO51b75zJVeI,717
|
|
116
116
|
machineconfig/scripts/python/devops.py,sha256=x7CnxOnZPSrCwjflnJ6sht1M7g0nzY2SxyPtmNputSA,2212
|
|
117
117
|
machineconfig/scripts/python/devops_navigator.py,sha256=5Cm384D4S8_GsvMzTwr0C16D0ktf8_5Mk5bEJncwDO8,237
|
|
118
118
|
machineconfig/scripts/python/explore.py,sha256=3kNglM1KYp57U8yrbWeHEslN458-xieRuFYsJAhrpIs,1247
|
|
119
119
|
machineconfig/scripts/python/fire_jobs.py,sha256=zLLgPfqCSpXBeU5kC4XEcojscZFy-K0K3dbbGqkTczU,13135
|
|
120
120
|
machineconfig/scripts/python/ftpx.py,sha256=8tmhKBZgSuhFZZYaT4JAIgeXMKmxJhxg5aJQFbbdtDg,9857
|
|
121
|
-
machineconfig/scripts/python/interactive.py,sha256=
|
|
121
|
+
machineconfig/scripts/python/interactive.py,sha256=PzZw2BP0ucWCZg2FYOFx0twruv4gE0Fhi1djCScmM2A,11505
|
|
122
122
|
machineconfig/scripts/python/machineconfig.py,sha256=l211lxHRcQ6BH7x3FwQHSJCYbYs6RJL5e0POjyWAW9A,3048
|
|
123
123
|
machineconfig/scripts/python/msearch.py,sha256=3NbwJFJtrvPSVyOfa6ogPjD-NVuRJHeAQ1WriDXCduU,737
|
|
124
124
|
machineconfig/scripts/python/sessions.py,sha256=Mex8Y2NM0Z3JiO7-qEKew9lA29FfUDo_tB3-1jJ79bs,9532
|
|
@@ -156,7 +156,7 @@ machineconfig/scripts/python/ai/solutions/opencode/opencode.json,sha256=nahHKRw1
|
|
|
156
156
|
machineconfig/scripts/python/ai/solutions/opencode/opencode.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
157
157
|
machineconfig/scripts/python/env_manager/__init__.py,sha256=E4LAHbU1wo2dLjE36ntv8U7QNTe8TasujUAYK9SLvWk,6
|
|
158
158
|
machineconfig/scripts/python/env_manager/path_manager_backend.py,sha256=ZVGlGJALhg7zNABDdwXxL7MFbL2BXPebObipXSLGbic,1552
|
|
159
|
-
machineconfig/scripts/python/env_manager/path_manager_tui.py,sha256=
|
|
159
|
+
machineconfig/scripts/python/env_manager/path_manager_tui.py,sha256=9Wux_YbqGFSbnABJwepre-FEUesSCyTdU3j3GHE7-cU,6932
|
|
160
160
|
machineconfig/scripts/python/helpers_agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
161
161
|
machineconfig/scripts/python/helpers_agents/fire_agents_help_launch.py,sha256=YD6-rtudHNip8tx85amSmOZZIHBP9khq4az3dF41j6U,5934
|
|
162
162
|
machineconfig/scripts/python/helpers_agents/fire_agents_help_search.py,sha256=qIfSS_su2YJ1Gb0_lu4cbjlJlYMBw0v52NTGiSrGjk8,2991
|
|
@@ -187,11 +187,11 @@ machineconfig/scripts/python/helpers_croshell/viewer.py,sha256=heQNjB9fwn3xxbPgM
|
|
|
187
187
|
machineconfig/scripts/python/helpers_croshell/viewer_template.py,sha256=ve3Q1-iKhCLc0VJijKvAeOYp2xaFOeIOC_XW956GWCc,3944
|
|
188
188
|
machineconfig/scripts/python/helpers_devops/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
189
189
|
machineconfig/scripts/python/helpers_devops/cli_config.py,sha256=VLR7tH1SdR3ftWSNjyt0LHc1gRssYJXYvkLjtydxVOM,5007
|
|
190
|
-
machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py,sha256=
|
|
190
|
+
machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py,sha256=ZSiEwGgKf9p62jKTqtVbM6qiiEhxy_Qhj8oSYq7pHew,4139
|
|
191
191
|
machineconfig/scripts/python/helpers_devops/cli_data.py,sha256=79Xvx7YnbueruEnl69hrDg2AhVxf_zCUdlVcKfeMGyQ,1774
|
|
192
192
|
machineconfig/scripts/python/helpers_devops/cli_nw.py,sha256=u_2l5Cc3dFnh0seKrbH9j-Z0bUCrgy45MOM6HCjgkQg,7562
|
|
193
193
|
machineconfig/scripts/python/helpers_devops/cli_repos.py,sha256=mFrhosIFCCT70d82NYUxp9ta6BYeAHQNhsx7CEmWcg4,12478
|
|
194
|
-
machineconfig/scripts/python/helpers_devops/cli_self.py,sha256=
|
|
194
|
+
machineconfig/scripts/python/helpers_devops/cli_self.py,sha256=Q60PoM3BMFd-_vcTpctTD5T850j5uBaP9Q71DctzQr0,6993
|
|
195
195
|
machineconfig/scripts/python/helpers_devops/cli_share_file.py,sha256=AL04784ncdP9ue5bKyqJfXrMksxjFKtuv_w353kQQsI,6298
|
|
196
196
|
machineconfig/scripts/python/helpers_devops/cli_share_server.py,sha256=S2xQ7sDVvfvGKcJNlquXj9Gc0ofk2EXnfvpRx2AWVD8,6278
|
|
197
197
|
machineconfig/scripts/python/helpers_devops/cli_terminal.py,sha256=k_PzXaiGyE0vXr0Ii1XcJz2A7UvyPJrR31TRWt4RKRI,6019
|
|
@@ -228,9 +228,9 @@ machineconfig/scripts/python/helpers_navigator/search_bar.py,sha256=kDi8Jhxap8wd
|
|
|
228
228
|
machineconfig/scripts/python/helpers_repos/action.py,sha256=8je051kpGZ7A_GRsQyWKhPZ8xVW7tSm4bnPu6VjxaXk,9755
|
|
229
229
|
machineconfig/scripts/python/helpers_repos/action_helper.py,sha256=XRCtkGkNrxauqUd9qkxtfJt02Mx2gejSYDLL0jyWn24,6176
|
|
230
230
|
machineconfig/scripts/python/helpers_repos/clone.py,sha256=9RZgs2OD2RUH6UiZKCuUvRyweDBomAm2lDG2qJmhry0,5436
|
|
231
|
-
machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py,sha256=
|
|
231
|
+
machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py,sha256=lDA2JRsuASn5T5JAeW26AZnmiUG-danPrKZIk7Qe1ZI,11479
|
|
232
232
|
machineconfig/scripts/python/helpers_repos/count_lines.py,sha256=Q5c7b-DxvTlQmljoic7niTuiAVyFlwYvkVQ7uRJHiTo,16009
|
|
233
|
-
machineconfig/scripts/python/helpers_repos/count_lines_frontend.py,sha256=
|
|
233
|
+
machineconfig/scripts/python/helpers_repos/count_lines_frontend.py,sha256=_ZB9vLawCqAF8QDcuPx63JK_J8I8Hq6c9F1xbDs8VvM,607
|
|
234
234
|
machineconfig/scripts/python/helpers_repos/entrypoint.py,sha256=WYEFGUJp9HWImlFjbs_hiFZrUqM_KEYm5VvSUjWd04I,2810
|
|
235
235
|
machineconfig/scripts/python/helpers_repos/grource.py,sha256=lHxyfsIQr4pbu71Ekqu-9nohR7LXbN2wufw7LPTyOgM,14639
|
|
236
236
|
machineconfig/scripts/python/helpers_repos/record.py,sha256=FQo0swuJZOp0I2XGK-t1OQU4zJHmQ2z9zTpDD30Tmg4,11001
|
|
@@ -238,11 +238,10 @@ machineconfig/scripts/python/helpers_repos/sync.py,sha256=P0P7Dog2uFDvwxcLP3YHPw
|
|
|
238
238
|
machineconfig/scripts/python/helpers_repos/update.py,sha256=cUIMUMm-50HrY6fzxSMZnFplhToVjVPZMm1j_otTha4,11060
|
|
239
239
|
machineconfig/scripts/python/helpers_sessions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
240
240
|
machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py,sha256=F6D-e0v405UFy-aj_pNWudxZkstPvjYR0UXLx-PR8Ms,3136
|
|
241
|
-
machineconfig/scripts/python/helpers_utils/path.py,sha256=
|
|
241
|
+
machineconfig/scripts/python/helpers_utils/path.py,sha256=dfVXs2b_NURy1oiuGGbkpODJLEGHwQFB13eux1ib0h4,3982
|
|
242
242
|
machineconfig/scripts/python/nw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
243
|
-
machineconfig/scripts/python/nw/add_ssh_key.py,sha256=9JLmWu8pE7PAL5VuCFd19iVEdCR90LwY6_9P7gKQzEE,9373
|
|
244
243
|
machineconfig/scripts/python/nw/devops_add_identity.py,sha256=aPjcHbTLhxYwWYcandyAHdwuO15ZBu3fB82u6bI0tMQ,3773
|
|
245
|
-
machineconfig/scripts/python/nw/devops_add_ssh_key.py,sha256=
|
|
244
|
+
machineconfig/scripts/python/nw/devops_add_ssh_key.py,sha256=hPmrJb6Q8dbvZBkj00va4najYDKziQ9A7CfZ3TZPccI,9560
|
|
246
245
|
machineconfig/scripts/python/nw/mount_drive,sha256=zemKofv7hOmRN_V3qK0q580GkfWw3VdikyVVQyiu8j8,3514
|
|
247
246
|
machineconfig/scripts/python/nw/mount_nfs,sha256=Dri4hGiM2GxpqqxpdBPbf7dRHrr7P1HzZy6xtrHYQfU,1855
|
|
248
247
|
machineconfig/scripts/python/nw/mount_nfs.py,sha256=lOMDY4RS7tx8gsCazVR5tNNwFbaRyO2PJlnwBCDQgCM,3573
|
|
@@ -259,7 +258,7 @@ machineconfig/scripts/windows/wrap_mcfg.ps1,sha256=tFCj4wK7B35Uf6kdGCRV7EIr1xZFT
|
|
|
259
258
|
machineconfig/scripts/windows/mounts/mount_nfs.ps1,sha256=XrAdzpxE6a4OccSmWJ7YWHJTnsZK8uXnFE5j9GOPA20,2026
|
|
260
259
|
machineconfig/scripts/windows/mounts/mount_nw.ps1,sha256=puxcfZc3ZCJerm8pj8OZGVoTYkhzp-h7oV-MrksSqIE,454
|
|
261
260
|
machineconfig/scripts/windows/mounts/mount_smb.ps1,sha256=PzYWpIO9BpwXjdWlUQL9pnMRnOGNSkxfh4bHukJFme8,69
|
|
262
|
-
machineconfig/scripts/windows/mounts/mount_ssh.ps1,sha256=
|
|
261
|
+
machineconfig/scripts/windows/mounts/mount_ssh.ps1,sha256=IxLt9BX0VFHBVY6Dz_ngHyhyg9xhtdXBzJSRE5mSXEk,322
|
|
263
262
|
machineconfig/scripts/windows/mounts/share_cloud.cmd,sha256=exD7JCdxw2LqVjw2MKCYHbVZlEqmelXtwnATng-dhJ4,1028
|
|
264
263
|
machineconfig/scripts/windows/mounts/share_smb.ps1,sha256=U7x8ULYSjbgzTtiHNSKQuTaZ_apilDvkGV5Xm5hXk5M,384
|
|
265
264
|
machineconfig/scripts/windows/mounts/unlock_bitlocker.ps1,sha256=Wv-SLscdckV-1mG3p82VXKPY9zW3hgkRmcLUXIZ1daE,253
|
|
@@ -344,7 +343,7 @@ machineconfig/settings/shells/pwsh/init.ps1,sha256=T0Zw9mfQa8rgDTxRk40UbzBq-7gkM
|
|
|
344
343
|
machineconfig/settings/shells/pwsh/profile.ps1,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
345
344
|
machineconfig/settings/shells/starship/starship.toml,sha256=d5lWKC0AnTcriRAZV1opEZy76QknSpKFgJ3jyW9_vZ0,1305
|
|
346
345
|
machineconfig/settings/shells/vtm/settings.xml,sha256=5TNXd-i0eUGo2w3tuhY9aOkwoJdqih8_HO_U6uL2Dts,18262
|
|
347
|
-
machineconfig/settings/shells/wezterm/wezterm.lua,sha256=
|
|
346
|
+
machineconfig/settings/shells/wezterm/wezterm.lua,sha256=_ERpROSN3XNtbZJgL1jkAb8DhwGjUjOYuAW6p43CA00,6296
|
|
348
347
|
machineconfig/settings/shells/wt/settings.json,sha256=Nzk9IpD-Bp36wKJAgG7XAa0GVwW3I29xNjUW5AYfxEI,10599
|
|
349
348
|
machineconfig/settings/shells/zsh/init.sh,sha256=LcT8AOecHoCtmmkXkSlAROJy-xD1re6wvPEIEzgPN5U,3054
|
|
350
349
|
machineconfig/settings/streamlit/config.toml,sha256=O3d4ax88hoW7gm5r51xmCcPssQ8ol-oFz_d0NUDlU4k,483
|
|
@@ -381,7 +380,7 @@ machineconfig/setup_linux/others/cli_installation.sh,sha256=gVvszYZJgKPRJx2SEaE3
|
|
|
381
380
|
machineconfig/setup_linux/others/mint_keyboard_shortcuts.sh,sha256=F5dbg0n9RHsKGPn8fIdZMn3p0RrHEkb8rWBGsdVGbus,1207
|
|
382
381
|
machineconfig/setup_linux/ssh/openssh_all.sh,sha256=3dg6HEUFbHQOzLfSAtzK_D_GB8rGCCp_aBnxNdnidVc,824
|
|
383
382
|
machineconfig/setup_linux/ssh/openssh_wsl.sh,sha256=1eeRGrloVB34K5z8yWVUMG5b9pV-WBfHgV9jqXiYgCQ,1398
|
|
384
|
-
machineconfig/setup_linux/web_shortcuts/interactive.sh,sha256=
|
|
383
|
+
machineconfig/setup_linux/web_shortcuts/interactive.sh,sha256=fK_KeDExbFX358VCtFXW-9bCi11WY5aVwjSAZJcZ3yY,1606
|
|
385
384
|
machineconfig/setup_mac/__init__.py,sha256=PfdhwY4Ss-rfP7b4-9fvKwxCDtNAd-u1JdhFYnE7CwI,518
|
|
386
385
|
machineconfig/setup_mac/apps_gui.sh,sha256=3alvddg918oMlJB2aUWJWpGGoaq5atlxcaOwhnyXlRI,9517
|
|
387
386
|
machineconfig/setup_mac/uv.sh,sha256=CSN8oCBKS-LK1vJJqYOhAMcrouTf4Q_F3cpplc_ddMA,1157
|
|
@@ -396,7 +395,7 @@ machineconfig/setup_windows/ssh/add_identity.ps1,sha256=b8ZXpmNUSw3IMYvqSY7ClpdW
|
|
|
396
395
|
machineconfig/setup_windows/ssh/openssh-server.ps1,sha256=OMlYQdvuJQNxF5EILLPizB6BZAT3jAmDsv1WcVVxpFQ,2529
|
|
397
396
|
machineconfig/setup_windows/ssh/openssh-server_add_key.ps1,sha256=91cL3K4H2saAuzOS1GxGicpc64ZDpgvPY39YPBWyxZI,269
|
|
398
397
|
machineconfig/setup_windows/ssh/openssh-server_copy-ssh-id.ps1,sha256=-7pElYiGFXUvO4dp6rW0LXmNo65h3hFTHJWyHbmO3Xc,745
|
|
399
|
-
machineconfig/setup_windows/web_shortcuts/interactive.ps1,sha256=
|
|
398
|
+
machineconfig/setup_windows/web_shortcuts/interactive.ps1,sha256=dLbfrZVSo8CWntYKeX1sRTd-aL-2F5WPRUJIQru3ugE,1939
|
|
400
399
|
machineconfig/setup_windows/web_shortcuts/quick_init.ps1,sha256=8TOw-ZxaWA6mZkOICAQtpQfqB2fUyD4HVfqokpxCCqI,655
|
|
401
400
|
machineconfig/setup_windows/wt_and_pwsh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
402
401
|
machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py,sha256=ogxJnwpdcpH7N6dFJu95UCNoGYirZKQho_3X0F_hmXs,6791
|
|
@@ -409,13 +408,13 @@ machineconfig/utils/links.py,sha256=m5-MfendBa8YiPPyS-lWiuu6Ru1-jU3hg3BYQgIaWg8,
|
|
|
409
408
|
machineconfig/utils/meta.py,sha256=4ocYH3Zi6bVN6FVgXoGIfoasV6oxi67I9rQ8hvyYinc,9892
|
|
410
409
|
machineconfig/utils/notifications.py,sha256=tuXIudcip0tEioG-bm8BbLr3FMDve4f6BktlznBhKxM,9013
|
|
411
410
|
machineconfig/utils/options.py,sha256=VWYx3EKJxIp-CJ8gDGYdjclKSc1tMUhyrC8v3seeneo,7447
|
|
412
|
-
machineconfig/utils/path_extended.py,sha256
|
|
411
|
+
machineconfig/utils/path_extended.py,sha256=-WYWs5bxcu8iXI4OHGH-eK0gevDOWR8SB4fKoD5JhWY,50515
|
|
413
412
|
machineconfig/utils/path_helper.py,sha256=VnsWxAKSniw-GZ5zUie56463vTjaFDyoMnH2Xf88HO8,10557
|
|
414
413
|
machineconfig/utils/procs.py,sha256=YPA_vEYQGwPd_o_Lc6nOTBo5BrB1tSs8PJ42XiGpenM,10957
|
|
415
414
|
machineconfig/utils/scheduler.py,sha256=fguwvINyaupOxdU5Uadyxalh_jXTXDzt0ioEgjEOKcM,14705
|
|
416
415
|
machineconfig/utils/scheduling.py,sha256=vcJgajeJPSWkJNlarYJSmLvasdOuCtBM4druOAB1Nwc,11089
|
|
417
416
|
machineconfig/utils/source_of_truth.py,sha256=ZAnCRltiM07ig--P6g9_6nEAvNFC4X4ERFTVcvpIYsE,764
|
|
418
|
-
machineconfig/utils/ssh.py,sha256=
|
|
417
|
+
machineconfig/utils/ssh.py,sha256=AWiMjHq8nGzdExL_cpJBgMgBNWtznGin1kECGRiYQcY,39262
|
|
419
418
|
machineconfig/utils/terminal.py,sha256=VDgsjTjBmMGgZN0YIc0pJ8YksLDrBtiXON1EThy7_is,4264
|
|
420
419
|
machineconfig/utils/tst.py,sha256=6u1GI49NdcpxH2BYGAusNfY5q9G_ytCGVzFM5b6HYpM,674
|
|
421
420
|
machineconfig/utils/upgrade_packages.py,sha256=e4iJn_9vL2zCJxAR2dhKJjM0__ALKgI5yB1uBRxSjhQ,6994
|
|
@@ -438,14 +437,14 @@ machineconfig/utils/installer_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
|
|
|
438
437
|
machineconfig/utils/installer_utils/github_release_bulk.py,sha256=WJf_qZlF02SmIc6C7o1h4Gy4gAaJAfeAS8O9s2Itj-k,6535
|
|
439
438
|
machineconfig/utils/installer_utils/installer.py,sha256=2xhzgAyifm5sHsb0y6d94UMWwRpGWMmsCCalsrnRHKA,9023
|
|
440
439
|
machineconfig/utils/installer_utils/installer_abc.py,sha256=_QihkKgi7-IGrQQoy8muD0iL_n65ebvqDgiv43sCudI,8984
|
|
441
|
-
machineconfig/utils/installer_utils/installer_class.py,sha256=
|
|
440
|
+
machineconfig/utils/installer_utils/installer_class.py,sha256=H2e5kjGfS47Rwy6SF7bqDLDiZ4WQ-mmsNz1gWAip3ro,17497
|
|
442
441
|
machineconfig/utils/schemas/fire_agents/fire_agents_input.py,sha256=d3pwhmE-EuHPxaIoTTZeUdDUEK9QqtimV8zO3vV-7N4,2052
|
|
443
442
|
machineconfig/utils/schemas/installer/installer_types.py,sha256=QClRY61QaduBPJoSpdmTIdgS9LS-RvE-QZ-D260tD3o,1214
|
|
444
443
|
machineconfig/utils/schemas/layouts/layout_types.py,sha256=TcqlZdGVoH8htG5fHn1KWXhRdPueAcoyApppZsPAPto,2020
|
|
445
444
|
machineconfig/utils/schemas/repos/repos_types.py,sha256=ECVr-3IVIo8yjmYmVXX2mnDDN1SLSwvQIhx4KDDQHBQ,405
|
|
446
445
|
machineconfig/utils/ssh_utils/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
447
|
-
machineconfig-7.
|
|
448
|
-
machineconfig-7.
|
|
449
|
-
machineconfig-7.
|
|
450
|
-
machineconfig-7.
|
|
451
|
-
machineconfig-7.
|
|
446
|
+
machineconfig-7.57.dist-info/METADATA,sha256=DOiMOr-khnZAboqskT6w5SNnd6CwXf0QTGQA8dhp6tQ,5939
|
|
447
|
+
machineconfig-7.57.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
448
|
+
machineconfig-7.57.dist-info/entry_points.txt,sha256=_JNgkzaa_gVAWyZ6UwPwXXQqURRSvAGhrVQ1RiU2sHc,746
|
|
449
|
+
machineconfig-7.57.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
|
|
450
|
+
machineconfig-7.57.dist-info/RECORD,,
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
"""SSH"""
|
|
2
|
-
|
|
3
|
-
from platform import system
|
|
4
|
-
from machineconfig.utils.source_of_truth import LIBRARY_ROOT
|
|
5
|
-
from machineconfig.utils.path_extended import PathExtended
|
|
6
|
-
from rich.console import Console
|
|
7
|
-
from rich.panel import Panel
|
|
8
|
-
from rich import box # Import box
|
|
9
|
-
from typing import Optional, Annotated
|
|
10
|
-
import typer
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
console = Console()
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def get_add_ssh_key_script(path_to_key: PathExtended):
|
|
17
|
-
console.print(Panel("🔑 SSH KEY CONFIGURATION", title="[bold blue]SSH Setup[/bold blue]"))
|
|
18
|
-
if system() == "Linux" or system() == "Darwin":
|
|
19
|
-
authorized_keys = PathExtended.home().joinpath(".ssh/authorized_keys")
|
|
20
|
-
console.print(Panel(f"🐧 Linux SSH configuration\n📄 Authorized keys file: {authorized_keys}", title="[bold blue]System Info[/bold blue]"))
|
|
21
|
-
elif system() == "Windows":
|
|
22
|
-
authorized_keys = PathExtended("C:/ProgramData/ssh/administrators_authorized_keys")
|
|
23
|
-
console.print(Panel(f"🪟 Windows SSH configuration\n📄 Authorized keys file: {authorized_keys}", title="[bold blue]System Info[/bold blue]"))
|
|
24
|
-
else:
|
|
25
|
-
console.print(Panel("❌ ERROR: Unsupported operating system\nOnly Linux and Windows are supported", title="[bold red]Error[/bold red]"))
|
|
26
|
-
raise NotImplementedError
|
|
27
|
-
|
|
28
|
-
if authorized_keys.exists():
|
|
29
|
-
split = "\n"
|
|
30
|
-
keys_text = authorized_keys.read_text(encoding="utf-8").split(split)
|
|
31
|
-
key_count = len([k for k in keys_text if k.strip()])
|
|
32
|
-
console.print(Panel(f"🔍 Current SSH authorization status\n✅ Found {key_count} authorized key(s)", title="[bold blue]Status[/bold blue]"))
|
|
33
|
-
if path_to_key.read_text(encoding="utf-8") in authorized_keys.read_text(encoding="utf-8"):
|
|
34
|
-
console.print(Panel(f"⚠️ Key already authorized\nKey: {path_to_key.name}\nStatus: Already present in authorized_keys file\nNo action required", title="[bold yellow]Warning[/bold yellow]"))
|
|
35
|
-
program = ""
|
|
36
|
-
else:
|
|
37
|
-
console.print(Panel(f"➕ Adding new SSH key to authorized keys\n🔑 Key file: {path_to_key.name}", title="[bold blue]Action[/bold blue]"))
|
|
38
|
-
if system() == "Linux":
|
|
39
|
-
program = f"cat {path_to_key} >> ~/.ssh/authorized_keys"
|
|
40
|
-
elif system() == "Windows":
|
|
41
|
-
program_path = LIBRARY_ROOT.joinpath("setup_windows/add-sshkey.ps1")
|
|
42
|
-
program = program_path.expanduser().read_text(encoding="utf-8")
|
|
43
|
-
place_holder = r'$sshfile = "$env:USERPROFILE\.ssh\pubkey.pub"'
|
|
44
|
-
assert place_holder in program, f"This section performs string manipulation on the script {program_path} to add the key to the authorized_keys file. The script has changed and the string {place_holder} is not found."
|
|
45
|
-
program = program.replace(place_holder, f'$sshfile = "{path_to_key}"')
|
|
46
|
-
console.print(Panel("🔧 Configured PowerShell script for Windows\n📝 Replaced placeholder with actual key path", title="[bold blue]Configuration[/bold blue]"))
|
|
47
|
-
else:
|
|
48
|
-
raise NotImplementedError
|
|
49
|
-
else:
|
|
50
|
-
console.print(Panel(f"📝 Creating new authorized_keys file\n🔑 Using key: {path_to_key.name}", title="[bold blue]Action[/bold blue]"))
|
|
51
|
-
if system() == "Linux":
|
|
52
|
-
program = f"cat {path_to_key} > ~/.ssh/authorized_keys"
|
|
53
|
-
else:
|
|
54
|
-
program_path = LIBRARY_ROOT.joinpath("setup_windows/openssh-server_add-sshkey.ps1")
|
|
55
|
-
program = PathExtended(program_path).expanduser().read_text(encoding="utf-8").replace('$sshfile=""', f'$sshfile="{path_to_key}"')
|
|
56
|
-
console.print(Panel("🔧 Configured PowerShell script for Windows\n📝 Set key path in script", title="[bold blue]Configuration[/bold blue]"))
|
|
57
|
-
|
|
58
|
-
if system() == "Linux" or system() == "Darwin":
|
|
59
|
-
program += """
|
|
60
|
-
sudo chmod 700 ~/.ssh
|
|
61
|
-
sudo chmod 644 ~/.ssh/authorized_keys
|
|
62
|
-
sudo chmod 644 ~/.ssh/*.pub
|
|
63
|
-
sudo service ssh --full-restart
|
|
64
|
-
# from superuser.com/questions/215504/permissions-on-private-key-in-ssh-folder
|
|
65
|
-
"""
|
|
66
|
-
return program
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"""
|
|
71
|
-
# Common pitfalls:
|
|
72
|
-
# 🚫 Wrong line endings (LF/CRLF) in config files
|
|
73
|
-
# 🌐 Network port conflicts (try 2222 -> 2223) between WSL and Windows
|
|
74
|
-
# sudo service ssh restart
|
|
75
|
-
# sudo service ssh status
|
|
76
|
-
# sudo nano /etc/ssh/sshd_config
|
|
77
|
-
"""
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def main(pub_path: Annotated[Optional[str], typer.Argument(..., help="Path to the public key file")] = None,
|
|
81
|
-
pub_choose: Annotated[bool, typer.Option(..., "--choose", "-c", help="Choose from available public keys in ~/.ssh")] = False,
|
|
82
|
-
pub_val: Annotated[bool, typer.Option(..., "--paste", "-p", help="Paste the public key content manually")] = False,
|
|
83
|
-
from_github: Annotated[Optional[str], typer.Option(..., "--from-github", "-g", help="Fetch public keys from a GitHub username")] = None
|
|
84
|
-
) -> None:
|
|
85
|
-
if pub_path:
|
|
86
|
-
key_path = PathExtended(pub_path).expanduser().absolute()
|
|
87
|
-
if not key_path.exists():
|
|
88
|
-
console.print(Panel(f"❌ ERROR: Provided key path does not exist\nPath: {key_path}", title="[bold red]Error[/bold red]"))
|
|
89
|
-
raise FileNotFoundError(f"Provided key path does not exist: {key_path}")
|
|
90
|
-
console.print(Panel(f"📄 Using provided public key file: {key_path}", title="[bold blue]Info[/bold blue]"))
|
|
91
|
-
program = get_add_ssh_key_script(key_path)
|
|
92
|
-
from machineconfig.utils.code import run_shell_script
|
|
93
|
-
run_shell_script(script=program)
|
|
94
|
-
console.print(Panel("✅ SSH KEY AUTHORIZATION COMPLETED", box=box.DOUBLE_EDGE, title_align="left"))
|
|
95
|
-
return
|
|
96
|
-
elif pub_choose:
|
|
97
|
-
console.print(Panel("🔐 SSH PUBLIC KEY AUTHORIZATION TOOL", box=box.DOUBLE_EDGE, title_align="left"))
|
|
98
|
-
console.print(Panel("🔍 Searching for public keys...", title="[bold blue]SSH Setup[/bold blue]", border_style="blue"))
|
|
99
|
-
pub_keys = PathExtended.home().joinpath(".ssh").search("*.pub")
|
|
100
|
-
if pub_keys:
|
|
101
|
-
console.print(Panel(f"✅ Found {len(pub_keys)} public key(s)", title="[bold green]Status[/bold green]", border_style="green"))
|
|
102
|
-
else:
|
|
103
|
-
console.print(Panel("⚠️ No public keys found", title="[bold yellow]Warning[/bold yellow]", border_style="yellow"))
|
|
104
|
-
return
|
|
105
|
-
console.print(Panel(f"🔄 Processing all {len(pub_keys)} public keys...", title="[bold blue]Processing[/bold blue]", border_style="blue"))
|
|
106
|
-
program = "\n\n\n".join([get_add_ssh_key_script(key) for key in pub_keys])
|
|
107
|
-
|
|
108
|
-
elif pub_val:
|
|
109
|
-
console.print(Panel("📋 Please provide a filename and paste the public key content", title="[bold blue]Input Required[/bold blue]", border_style="blue"))
|
|
110
|
-
key_filename = input("📝 File name (default: my_pasted_key.pub): ") or "my_pasted_key.pub"
|
|
111
|
-
key_path = PathExtended.home().joinpath(f".ssh/{key_filename}")
|
|
112
|
-
key_path.write_text(input("🔑 Paste the public key here: "), encoding="utf-8")
|
|
113
|
-
console.print(Panel(f"💾 Key saved to: {key_path}", title="[bold green]Success[/bold green]", border_style="green"))
|
|
114
|
-
program = get_add_ssh_key_script(key_path)
|
|
115
|
-
elif from_github:
|
|
116
|
-
console.print(Panel(f"🌐 Fetching public keys from GitHub user: {from_github}", title="[bold blue]GitHub Fetch[/bold blue]", border_style="blue"))
|
|
117
|
-
import requests
|
|
118
|
-
# $pubkey_url = 'https://github.com/thisismygitrepo.keys' # $pubkey_string = (Invoke-WebRequest $pubkey_url).Content
|
|
119
|
-
response = requests.get(f"https://api.github.com/users/{from_github}/keys")
|
|
120
|
-
if response.status_code != 200:
|
|
121
|
-
console.print(Panel(f"❌ ERROR: Failed to fetch keys from GitHub user {from_github}\nStatus Code: {response.status_code}", title="[bold red]Error[/bold red]", border_style="red"))
|
|
122
|
-
raise RuntimeError(f"Failed to fetch keys from GitHub user {from_github}: Status Code {response.status_code}")
|
|
123
|
-
keys = response.json()
|
|
124
|
-
if not keys:
|
|
125
|
-
console.print(Panel(f"⚠️ No public keys found for GitHub user: {from_github}", title="[bold yellow]Warning[/bold yellow]", border_style="yellow"))
|
|
126
|
-
return
|
|
127
|
-
console.print(Panel(f"✅ Found {len(keys)} public key(s) for user: {from_github}", title="[bold green]Success[/bold green]", border_style="green"))
|
|
128
|
-
key_path = PathExtended.home().joinpath(f".ssh/{from_github}_github_keys.pub")
|
|
129
|
-
key_path.write_text("\n".join([key["key"] for key in keys]), encoding="utf-8")
|
|
130
|
-
console.print(Panel(f"💾 Keys saved to: {key_path}", title="[bold green]Success[/bold green]", border_style="green"))
|
|
131
|
-
program = get_add_ssh_key_script(key_path)
|
|
132
|
-
else:
|
|
133
|
-
console.print(Panel("❌ ERROR: No method provided to add SSH key\nUse --help for options", title="[bold red]Error[/bold red]", border_style="red"))
|
|
134
|
-
raise ValueError("No method provided to add SSH key. Use --help for options.")
|
|
135
|
-
console.print(Panel("🚀 SSH KEY AUTHORIZATION READY\nRun the generated script to apply changes", box=box.DOUBLE_EDGE, title_align="left"))
|
|
136
|
-
from machineconfig.utils.code import run_shell_script
|
|
137
|
-
run_shell_script(script=program)
|
|
138
|
-
import socket
|
|
139
|
-
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
140
|
-
s.connect(('8.8.8.8',80))
|
|
141
|
-
local_ip_v4 = s.getsockname()[0]
|
|
142
|
-
s.close()
|
|
143
|
-
print(f"This computer is @ {local_ip_v4}")
|
|
144
|
-
console.print(Panel("✅ SSH KEY AUTHORIZATION COMPLETED", box=box.DOUBLE_EDGE, title_align="left"))
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if __name__ == "__main__":
|
|
148
|
-
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|