machineconfig 7.98__py3-none-any.whl → 8.51__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.
- machineconfig/cluster/remote/run_cluster.py +1 -1
- machineconfig/cluster/remote/run_remote.py +1 -1
- machineconfig/cluster/sessions_managers/utils/maker.py +10 -8
- machineconfig/cluster/sessions_managers/wt_local.py +1 -1
- machineconfig/cluster/sessions_managers/wt_local_manager.py +1 -1
- machineconfig/cluster/sessions_managers/zellij_local.py +1 -1
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +1 -1
- machineconfig/jobs/installer/checks/check_installations.py +133 -0
- machineconfig/jobs/installer/checks/install_utils.py +132 -0
- machineconfig/jobs/installer/checks/report_utils.py +39 -0
- machineconfig/jobs/installer/checks/vt_utils.py +89 -0
- machineconfig/jobs/installer/installer_data.json +271 -152
- machineconfig/jobs/installer/linux_scripts/docker.sh +6 -9
- machineconfig/jobs/installer/package_groups.py +11 -9
- machineconfig/jobs/installer/{custom → python_scripts}/boxes.py +1 -2
- machineconfig/jobs/installer/{custom_dev → python_scripts}/brave.py +1 -1
- machineconfig/jobs/installer/{custom_dev → python_scripts}/code.py +10 -8
- machineconfig/jobs/installer/{custom → python_scripts}/hx.py +30 -13
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerdfont.py +1 -1
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerfont_windows_helper.py +6 -5
- machineconfig/jobs/installer/{custom_dev → python_scripts}/sysabc.py +26 -20
- machineconfig/jobs/installer/{custom_dev → python_scripts}/wezterm.py +1 -1
- machineconfig/jobs/installer/{custom → python_scripts}/yazi.py +39 -19
- machineconfig/jobs/scripts/powershell_scripts/cmatrix.ps1 +52 -0
- machineconfig/jobs/scripts/powershell_scripts/mount_ssh.ps1 +13 -0
- machineconfig/jobs/scripts/powershell_scripts/obs.ps1 +4 -0
- machineconfig/jobs/scripts_dynamic/a.py +428 -0
- machineconfig/logger.py +1 -1
- machineconfig/profile/create_helper.py +21 -10
- machineconfig/profile/create_links.py +77 -20
- machineconfig/profile/create_links_export.py +63 -58
- machineconfig/profile/create_shell_profile.py +14 -0
- machineconfig/profile/mapper_data.toml +45 -0
- machineconfig/profile/mapper_dotfiles.toml +249 -0
- machineconfig/scripts/python/agents.py +76 -171
- machineconfig/scripts/python/ai/initai.py +3 -1
- machineconfig/scripts/python/ai/scripts/__init__.py +1 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +2 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +8 -6
- machineconfig/scripts/python/ai/solutions/claude/claude.py +1 -1
- machineconfig/scripts/python/ai/solutions/cline/cline.py +1 -1
- machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +1 -1
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +29 -0
- machineconfig/scripts/python/ai/solutions/crush/crush.py +1 -1
- machineconfig/scripts/python/ai/solutions/cursor/cursors.py +1 -1
- machineconfig/scripts/python/ai/solutions/gemini/gemini.py +1 -1
- machineconfig/scripts/python/ai/solutions/gemini/settings.json +3 -0
- machineconfig/scripts/python/ai/{solutions → utils}/generic.py +2 -15
- machineconfig/scripts/python/ai/utils/vscode_tasks.py +6 -3
- machineconfig/scripts/python/cloud.py +58 -11
- machineconfig/scripts/python/croshell.py +4 -155
- machineconfig/scripts/python/devops.py +57 -38
- machineconfig/scripts/python/devops_navigator.py +17 -3
- machineconfig/scripts/python/fire_jobs.py +10 -193
- machineconfig/scripts/python/ftpx.py +5 -224
- machineconfig/scripts/python/graph/cli_graph.json +8743 -0
- machineconfig/scripts/python/{env_manager → helper_env}/path_manager_tui.py +2 -2
- machineconfig/scripts/python/{env_manager → helpers/helper_env}/env_manager_tui.py +1 -1
- machineconfig/scripts/python/helpers/helper_env/path_manager_tui.py +228 -0
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.py +1 -1
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_cursor_agents.py +1 -1
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_gemini.py +1 -1
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_qwen.py +1 -1
- machineconfig/scripts/python/helpers/helpers_agents/agents_impl.py +168 -0
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_launch.py +10 -7
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aichat/config.yaml +5 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aider/.aider.conf.yml +2 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/copilot/config.yml +1 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/crush/crush.json +10 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/gemini/settings.json +12 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/privacy.py +109 -0
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.sh +3 -1
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_copy.py +6 -6
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_mount.py +10 -5
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_sync.py +4 -4
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers2.py +1 -1
- machineconfig/scripts/python/helpers/helpers_croshell/croshell_impl.py +225 -0
- machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/scheduler.py +4 -4
- machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/start_slidev.py +7 -6
- machineconfig/scripts/python/helpers/helpers_devops/backup_config.py +149 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_backup_retrieve.py +262 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_config.py +98 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_config_dotfile.py +274 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_data.py +67 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_nw.py +69 -82
- machineconfig/scripts/python/helpers/helpers_devops/cli_repos.py +274 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_self.py +47 -22
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_file.py +44 -30
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_server.py +26 -43
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_terminal.py +12 -6
- machineconfig/scripts/python/helpers/helpers_devops/cli_ssh.py +167 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_status.py +12 -6
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_update_repos.py +1 -1
- machineconfig/scripts/python/{interactive.py → helpers/helpers_devops/interactive.py} +64 -50
- machineconfig/scripts/python/helpers/helpers_devops/run_script.py +197 -0
- machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.ps1 +41 -0
- machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.sh +48 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_wezterm_theme.py +3 -3
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/file_wrangler.py +1 -0
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_args_helper.py +1 -0
- machineconfig/scripts/python/helpers/helpers_fire_command/fire_jobs_impl.py +233 -0
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_route_helper.py +3 -3
- machineconfig/scripts/python/helpers/helpers_msearch/msearch_impl.py +248 -0
- machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_linux/fzfg +4 -3
- machineconfig/scripts/python/helpers/helpers_msearch/scripts_linux/search_with_context.sh +48 -0
- machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_windows/fzfg.ps1 +1 -1
- machineconfig/scripts/python/helpers/helpers_navigator/__init__.py +20 -0
- machineconfig/scripts/python/helpers/helpers_navigator/cli_graph_loader.py +234 -0
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/command_builder.py +61 -13
- machineconfig/scripts/python/helpers/helpers_navigator/command_detail.py +153 -0
- machineconfig/scripts/python/helpers/helpers_navigator/command_tree.py +45 -0
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/data_models.py +18 -11
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/main_app.py +5 -5
- machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/address.py +52 -10
- machineconfig/scripts/python/helpers/helpers_network/address_switch.py +78 -0
- machineconfig/scripts/python/helpers/helpers_network/ftpx_impl.py +276 -0
- machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_ssh.py +2 -2
- machineconfig/scripts/python/helpers/helpers_network/ssh_add_identity.py +73 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_add_ssh_key.py +175 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_debug_linux.py +319 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_debug_windows.py +275 -0
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action.py +3 -3
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action_helper.py +3 -3
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/cloud_repo_sync.py +118 -34
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/grource.py +3 -2
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/record.py +33 -13
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_2.py +63 -19
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/update.py +0 -6
- machineconfig/scripts/python/helpers/helpers_search/script_help.py +81 -0
- machineconfig/scripts/python/helpers/helpers_sessions/__init__.py +0 -0
- machineconfig/scripts/python/helpers/helpers_sessions/sessions_impl.py +186 -0
- machineconfig/scripts/python/{helpers_sessions → helpers/helpers_sessions}/sessions_multiprocess.py +1 -2
- machineconfig/scripts/python/helpers/helpers_terminal/__init__.py +0 -0
- machineconfig/scripts/python/helpers/helpers_terminal/terminal_impl.py +96 -0
- machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/download.py +1 -1
- machineconfig/scripts/python/{helpers_devops/cli_utils.py → helpers/helpers_utils/pdf.py} +2 -2
- machineconfig/scripts/python/{helpers_utils/path.py → helpers/helpers_utils/python.py} +65 -40
- machineconfig/scripts/python/helpers/helpers_utils/specs.py +246 -0
- machineconfig/scripts/python/mcfg_entry.py +133 -48
- machineconfig/scripts/python/msearch.py +16 -61
- machineconfig/scripts/python/sessions.py +68 -203
- machineconfig/scripts/python/terminal.py +27 -102
- machineconfig/scripts/python/utils.py +101 -22
- machineconfig/settings/atuin/config.toml +294 -0
- machineconfig/settings/atuin/themes/catppuccin-mocha-mauve.toml +12 -0
- machineconfig/settings/linters/.ruff.toml +2 -1
- machineconfig/settings/mprocs/windows/mprocs.yaml +2 -2
- machineconfig/settings/shells/bash/init.sh +6 -3
- machineconfig/settings/shells/nushell/config.nu +23 -1
- machineconfig/settings/shells/nushell/env.nu +22 -48
- machineconfig/settings/shells/nushell/init.nu +64 -240
- machineconfig/settings/shells/pwsh/init.ps1 +69 -1
- machineconfig/settings/shells/pwsh/search_pwsh_history.ps1 +99 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +4 -1
- machineconfig/settings/shells/wt/settings.json +21 -21
- machineconfig/settings/shells/zsh/init.sh +25 -4
- machineconfig/settings/television/cable_unix/bash-history.toml +1 -1
- machineconfig/settings/television/cable_windows/pwsh-history.toml +1 -1
- machineconfig/settings/tv/config.toml +234 -0
- machineconfig/settings/tv/themes/catppuccin-mocha-sky.toml +22 -0
- machineconfig/settings/wsl/.wslconfig +5 -30
- machineconfig/settings/wt/__init__.py +0 -0
- machineconfig/settings/yazi/yazi_linux.toml +18 -8
- machineconfig/settings/zellij/layouts/st.kdl +40 -9
- machineconfig/settings/zellij/layouts/st2.kdl +1 -1
- machineconfig/setup_linux/__init__.py +0 -1
- machineconfig/setup_linux/apps_desktop.sh +8 -27
- machineconfig/setup_linux/web_shortcuts/interactive.sh +10 -10
- machineconfig/setup_linux/web_shortcuts/live_from_github.sh +3 -0
- machineconfig/setup_mac/__init__.py +0 -2
- machineconfig/setup_windows/__init__.py +2 -5
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +14 -13
- machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +4 -3
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +3 -3
- machineconfig/type_hinting/sql/__init__.py +1 -0
- machineconfig/type_hinting/sql/base.py +216 -0
- machineconfig/type_hinting/sql/core_schema.py +64 -0
- machineconfig/type_hinting/sql/core_schema_typeddict.py +41 -0
- machineconfig/type_hinting/sql/typeddict_codegen.py +222 -0
- machineconfig/type_hinting/typedict/__init__.py +1 -0
- machineconfig/type_hinting/typedict/ast_utils.py +130 -0
- machineconfig/type_hinting/typedict/generator_helpers.py +319 -0
- machineconfig/type_hinting/typedict/generators.py +231 -0
- machineconfig/type_hinting/typedict/polars_schema.py +24 -0
- machineconfig/type_hinting/typedict/polars_schema_typeddict.py +63 -0
- machineconfig/utils/accessories.py +24 -0
- machineconfig/utils/code.py +78 -33
- machineconfig/utils/files/ascii_art.py +10 -14
- machineconfig/utils/files/headers.py +3 -5
- machineconfig/utils/files/read.py +8 -1
- machineconfig/utils/installer_utils/github_release_bulk.py +11 -91
- machineconfig/utils/installer_utils/github_release_scraper.py +99 -0
- machineconfig/utils/installer_utils/install_from_url.py +1 -1
- machineconfig/utils/installer_utils/installer_class.py +12 -4
- machineconfig/utils/installer_utils/installer_cli.py +1 -15
- machineconfig/utils/installer_utils/installer_helper.py +2 -2
- machineconfig/utils/installer_utils/installer_locator_utils.py +13 -13
- machineconfig/utils/installer_utils/installer_runner.py +4 -4
- machineconfig/utils/io.py +25 -8
- machineconfig/utils/meta.py +6 -4
- machineconfig/utils/options.py +49 -19
- machineconfig/utils/options_utils/__init__.py +0 -0
- machineconfig/utils/options_utils/options_tv_linux.py +211 -0
- machineconfig/utils/options_utils/options_tv_windows.py +88 -0
- machineconfig/utils/options_utils/tv_options.py +37 -0
- machineconfig/utils/path_extended.py +8 -7
- machineconfig/utils/scheduler.py +8 -2
- machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
- machineconfig/utils/source_of_truth.py +6 -1
- machineconfig/utils/ssh.py +73 -23
- machineconfig/utils/ssh_utils/abc.py +1 -1
- machineconfig/utils/ssh_utils/copy_from_here.py +19 -14
- machineconfig/utils/ssh_utils/copy_to_here.py +2 -1
- machineconfig/utils/ssh_utils/utils.py +23 -7
- machineconfig/utils/ssh_utils/wsl.py +107 -170
- machineconfig/utils/ssh_utils/wsl_helper.py +217 -0
- machineconfig/utils/upgrade_packages.py +4 -8
- {machineconfig-7.98.dist-info → machineconfig-8.51.dist-info}/METADATA +30 -22
- machineconfig-8.51.dist-info/RECORD +543 -0
- machineconfig/jobs/installer/check_installations.py +0 -248
- machineconfig/profile/backup.toml +0 -49
- machineconfig/profile/mapper.toml +0 -263
- machineconfig/scripts/linux/other/switch_ip +0 -20
- machineconfig/scripts/python/helpers/run_py_script.py +0 -79
- machineconfig/scripts/python/helpers/tmp_py_scripts/a.py +0 -26
- machineconfig/scripts/python/helpers_devops/cli_config.py +0 -105
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +0 -89
- machineconfig/scripts/python/helpers_devops/cli_data.py +0 -25
- machineconfig/scripts/python/helpers_devops/cli_repos.py +0 -215
- machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +0 -80
- machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +0 -3
- machineconfig/scripts/python/helpers_navigator/__init__.py +0 -20
- machineconfig/scripts/python/helpers_navigator/command_detail.py +0 -44
- machineconfig/scripts/python/helpers_navigator/command_tree.py +0 -620
- machineconfig/scripts/python/helpers_network/devops_add_identity.py +0 -82
- machineconfig/scripts/python/helpers_network/devops_add_ssh_key.py +0 -153
- machineconfig/scripts/python/helpers_network/ssh_debug_linux.py +0 -391
- machineconfig/scripts/python/helpers_network/ssh_debug_windows.py +0 -338
- machineconfig/scripts/python/helpers_network/wsl_windows_transfer.py +0 -67
- machineconfig/scripts/python/helpers_repos/entrypoint.py +0 -77
- machineconfig/scripts/windows/mounts/mount_ssh.ps1 +0 -13
- machineconfig/setup_linux/others/mint_keyboard_shortcuts.sh +0 -30
- machineconfig/setup_linux/ssh/openssh_all.sh +0 -25
- machineconfig/setup_linux/ssh/openssh_wsl.sh +0 -38
- machineconfig/setup_mac/ssh/openssh_setup.sh +0 -114
- machineconfig/setup_windows/others/obs.ps1 +0 -4
- machineconfig/setup_windows/ssh/add-sshkey.ps1 +0 -29
- machineconfig/setup_windows/ssh/add_identity.ps1 +0 -11
- machineconfig/setup_windows/ssh/openssh-server.ps1 +0 -37
- machineconfig/setup_windows/ssh/openssh-server_add_key.ps1 +0 -7
- machineconfig/setup_windows/ssh/openssh-server_copy-ssh-id.ps1 +0 -14
- machineconfig/utils/options_tv.py +0 -119
- machineconfig/utils/tst.py +0 -20
- machineconfig-7.98.dist-info/RECORD +0 -504
- /machineconfig/jobs/installer/{custom_dev → checks}/__init__.py +0 -0
- /machineconfig/{scripts/python/helpers_agents → jobs/installer/python_scripts}/__init__.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/alacritty.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/bypass_paywall.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/cloudflare_warp_cli.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/cursor.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/dubdb_adbc.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/espanso.py +0 -0
- /machineconfig/jobs/installer/{custom → python_scripts}/gh.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/goes.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/lvim.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/redis.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/winget.py +0 -0
- /machineconfig/{setup_linux/others → jobs/scripts/bash_scripts}/android.sh +0 -0
- /machineconfig/jobs/{installer/linux_scripts → scripts/bash_scripts}/lid.sh +0 -0
- /machineconfig/{scripts/python/helpers_network → jobs/scripts/bash_scripts}/mount_drive +0 -0
- /machineconfig/{scripts/python/helpers_network → jobs/scripts/bash_scripts}/mount_nfs +0 -0
- /machineconfig/{scripts/python/helpers_network → jobs/scripts/bash_scripts}/mount_nw_drive +0 -0
- /machineconfig/{scripts/python/helpers_network → jobs/scripts/bash_scripts}/mount_smb +0 -0
- /machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_cloud.sh +0 -0
- /machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_nfs +0 -0
- /machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/start_docker +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/Restore-ThunderbirdProfile.ps1 +0 -0
- /machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/docker.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nfs.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nw.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_smb.ps1 +0 -0
- /machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/power_options.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_cloud.cmd +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_smb.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/unlock_bitlocker.ps1 +0 -0
- /machineconfig/scripts/python/ai/{solutions/_shared.py → utils/shared.py} +0 -0
- /machineconfig/scripts/python/{helpers_agents/agentic_frameworks → graph}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_cloud → helpers}/__init__.py +0 -0
- /machineconfig/scripts/python/{env_manager → helpers/helper_env}/__init__.py +0 -0
- /machineconfig/scripts/python/{env_manager → helpers/helper_env}/path_manager_backend.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_agents}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_devops → helpers/helpers_agents/agentic_frameworks}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.json +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_search.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_helper_types.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_load_balancer.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/prompt.txt +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.ps1 +0 -0
- /machineconfig/scripts/python/{helpers_devops/themes → helpers/helpers_cloud}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_helpers.py +0 -0
- /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers5.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_croshell}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/crosh.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/pomodoro.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer_template.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_devops}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_sessions → helpers/helpers_devops/themes}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → scripts/python/helpers/helpers_fire_command}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/cloud_manager.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/f.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_streamlit_helper.py +0 -0
- /machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/search_bar.py +0 -0
- /machineconfig/scripts/python/{helpers_devops/themes/choose_starship_theme.ps1 → helpers/helpers_network/__init__.py} +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_nfs.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_nw_drive.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/onetimeshare.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/wifi_conn.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/clone.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_1.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/sync.py +0 -0
- /machineconfig/scripts/python/helpers/{ast_search.py → helpers_search/ast_search.py} +0 -0
- /machineconfig/scripts/python/helpers/{qr_code.py → helpers_search/qr_code.py} +0 -0
- /machineconfig/scripts/python/helpers/{repo_rag.py → helpers_search/repo_rag.py} +0 -0
- /machineconfig/scripts/python/helpers/{symantic_search.py → helpers_search/symantic_search.py} +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → settings/wt}/set_wt_settings.py +0 -0
- {machineconfig-7.98.dist-info → machineconfig-8.51.dist-info}/WHEEL +0 -0
- {machineconfig-7.98.dist-info → machineconfig-8.51.dist-info}/entry_points.txt +0 -0
- {machineconfig-7.98.dist-info → machineconfig-8.51.dist-info}/top_level.txt +0 -0
|
@@ -1,10 +1,54 @@
|
|
|
1
|
+
from typing import Optional, TypedDict, cast
|
|
1
2
|
|
|
2
|
-
|
|
3
|
+
|
|
4
|
+
class CountryFlag(TypedDict, total=False):
|
|
5
|
+
emoji: str
|
|
6
|
+
unicode: str
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CountryCurrency(TypedDict, total=False):
|
|
10
|
+
code: str
|
|
11
|
+
symbol: str
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Continent(TypedDict, total=False):
|
|
15
|
+
code: str
|
|
16
|
+
name: str
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PublicIpInfo(TypedDict, total=True):
|
|
20
|
+
ip: str
|
|
21
|
+
hostname: str
|
|
22
|
+
city: str
|
|
23
|
+
region: str
|
|
24
|
+
country: str
|
|
25
|
+
country_name: str
|
|
26
|
+
country_flag: CountryFlag
|
|
27
|
+
country_flag_url: str
|
|
28
|
+
country_currency: CountryCurrency
|
|
29
|
+
continent: Continent
|
|
30
|
+
loc: str
|
|
31
|
+
org: str
|
|
32
|
+
postal: str
|
|
33
|
+
timezone: str
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_public_ip_address() -> PublicIpInfo:
|
|
37
|
+
from machineconfig.utils.installer_utils.installer_cli import install_if_missing
|
|
38
|
+
import subprocess
|
|
39
|
+
|
|
40
|
+
install_if_missing("ipinfo")
|
|
41
|
+
result = subprocess.run(["ipinfo", "myip", "--json"], check=True, capture_output=True, text=True, encoding="utf-8")
|
|
42
|
+
import json
|
|
43
|
+
|
|
44
|
+
loaded_json: PublicIpInfo = json.loads(result.stdout)
|
|
45
|
+
return loaded_json
|
|
3
46
|
|
|
4
47
|
|
|
5
48
|
def get_all_ipv4_addresses() -> list[tuple[str, str]]:
|
|
6
49
|
import psutil
|
|
7
50
|
import socket
|
|
51
|
+
|
|
8
52
|
result: list[tuple[str, str]] = []
|
|
9
53
|
for iface, addrs in psutil.net_if_addrs().items():
|
|
10
54
|
for addr in addrs:
|
|
@@ -38,19 +82,16 @@ def select_lan_ipv4(prefer_vpn: bool) -> Optional[str]:
|
|
|
38
82
|
)
|
|
39
83
|
|
|
40
84
|
# Light preference for names that look like real NICs
|
|
41
|
-
PHYSICAL_IFACE_PAT = re.compile(
|
|
42
|
-
r"^(?:eth\d*|en\d*|enp.*|ens.*|eno.*|wlan\d*|wl.*|.*wifi.*|.*ethernet.*)$",
|
|
43
|
-
re.IGNORECASE,
|
|
44
|
-
)
|
|
85
|
+
PHYSICAL_IFACE_PAT = re.compile(r"^(?:eth\d*|en\d*|enp.*|ens.*|eno.*|wlan\d*|wl.*|.*wifi.*|.*ethernet.*)$", re.IGNORECASE)
|
|
45
86
|
|
|
46
87
|
# Known noisy CIDRs to avoid
|
|
47
88
|
NOISY_NETS: list[ipaddress.IPv4Network] = [
|
|
48
|
-
ipaddress.IPv4Network("100.64.0.0/10"),
|
|
49
|
-
ipaddress.IPv4Network("172.17.0.0/16"),
|
|
89
|
+
ipaddress.IPv4Network("100.64.0.0/10"), # CGNAT (Tailscale/others)
|
|
90
|
+
ipaddress.IPv4Network("172.17.0.0/16"), # docker0 default
|
|
50
91
|
ipaddress.IPv4Network("172.18.0.0/16"),
|
|
51
92
|
ipaddress.IPv4Network("172.19.0.0/16"),
|
|
52
|
-
ipaddress.IPv4Network("192.168.49.0/24"),
|
|
53
|
-
ipaddress.IPv4Network("10.0.2.0/24"),
|
|
93
|
+
ipaddress.IPv4Network("192.168.49.0/24"), # minikube default
|
|
94
|
+
ipaddress.IPv4Network("10.0.2.0/24"), # VirtualBox NAT
|
|
54
95
|
]
|
|
55
96
|
|
|
56
97
|
def _in_any(ip: ipaddress.IPv4Address, nets: Sequence[ipaddress.IPv4Network]) -> bool:
|
|
@@ -58,8 +99,9 @@ def select_lan_ipv4(prefer_vpn: bool) -> Optional[str]:
|
|
|
58
99
|
|
|
59
100
|
stats = psutil.net_if_stats()
|
|
60
101
|
best = None
|
|
61
|
-
best_score = -10**9
|
|
102
|
+
best_score = -(10**9)
|
|
62
103
|
import socket
|
|
104
|
+
|
|
63
105
|
for iface, addrs in psutil.net_if_addrs().items():
|
|
64
106
|
st = stats.get(iface)
|
|
65
107
|
if not st or not st.isup:
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
from machineconfig.scripts.python.helpers.helpers_network.address import get_public_ip_address
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def switch_public_ip_address(max_trials: int = 10, wait_seconds: float = 4.0) -> None:
|
|
8
|
+
print("🔁 Switching IP ... ")
|
|
9
|
+
from machineconfig.utils.installer_utils.installer_cli import install_if_missing
|
|
10
|
+
install_if_missing("warp-cli")
|
|
11
|
+
|
|
12
|
+
current_ip: str | None = None
|
|
13
|
+
try:
|
|
14
|
+
current_data = get_public_ip_address()
|
|
15
|
+
current_ip = current_data.get("ip")
|
|
16
|
+
except Exception as e:
|
|
17
|
+
print(f"⚠️ Could not get current IP: {e}")
|
|
18
|
+
|
|
19
|
+
print(f"Current IP: {current_ip}")
|
|
20
|
+
|
|
21
|
+
for attempt in range(1, max_trials + 1):
|
|
22
|
+
print(f"\n--- Attempt {attempt}/{max_trials} ---")
|
|
23
|
+
|
|
24
|
+
print("🔻 Deactivating current connection ... ")
|
|
25
|
+
# We use check=False because if it's already deleted it might return non-zero
|
|
26
|
+
subprocess.run(["warp-cli", "registration", "delete"], check=False)
|
|
27
|
+
|
|
28
|
+
print(f"😴 Sleeping for {wait_seconds} seconds ... ")
|
|
29
|
+
time.sleep(wait_seconds)
|
|
30
|
+
|
|
31
|
+
print("🔼 Registering new connection ... ")
|
|
32
|
+
res_reg = subprocess.run(["warp-cli", "registration", "new"], check=False)
|
|
33
|
+
if res_reg.returncode != 0:
|
|
34
|
+
print("⚠️ Registration failed, retrying loop...")
|
|
35
|
+
continue
|
|
36
|
+
|
|
37
|
+
print("🔗 Connecting ... ")
|
|
38
|
+
subprocess.run(["warp-cli", "connect"], check=False)
|
|
39
|
+
|
|
40
|
+
print(f"😴 Sleeping for {wait_seconds} seconds ... ")
|
|
41
|
+
time.sleep(wait_seconds)
|
|
42
|
+
|
|
43
|
+
print("🔍 Checking status of warp ... ")
|
|
44
|
+
subprocess.run(["warp-cli", "status"], check=False)
|
|
45
|
+
|
|
46
|
+
print("🔍 Checking new IP ... ")
|
|
47
|
+
new_ip: str | None = None
|
|
48
|
+
# Retry getting IP a few times before giving up on this connection attempt
|
|
49
|
+
for ip_check_attempt in range(5):
|
|
50
|
+
try:
|
|
51
|
+
new_data = get_public_ip_address()
|
|
52
|
+
new_ip = new_data["ip"]
|
|
53
|
+
if new_ip:
|
|
54
|
+
break
|
|
55
|
+
except Exception as e:
|
|
56
|
+
print(f"⚠️ Error checking new IP (attempt {ip_check_attempt+1}/5): {e}")
|
|
57
|
+
time.sleep(wait_seconds)
|
|
58
|
+
|
|
59
|
+
if new_ip:
|
|
60
|
+
print(f"New IP: {new_ip}")
|
|
61
|
+
|
|
62
|
+
if current_ip and new_ip != current_ip:
|
|
63
|
+
print("✅ Done ... IP Changed.")
|
|
64
|
+
return
|
|
65
|
+
elif current_ip is None:
|
|
66
|
+
print("✅ Done ... IP obtained (was unknown).")
|
|
67
|
+
return
|
|
68
|
+
else:
|
|
69
|
+
print("❌ IP did not change.")
|
|
70
|
+
else:
|
|
71
|
+
print("⚠️ Could not retrieve new IP after multiple attempts.")
|
|
72
|
+
|
|
73
|
+
print("❌ Failed to switch IP after max trials.")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
switch_public_ip_address()
|
|
78
|
+
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"""Pure Python implementation for ftpx command - no typer dependencies."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def ftpx(source: str, target: str, recursive: bool, zipFirst: bool, cloud: bool, overwrite_existing: bool) -> None:
|
|
8
|
+
"""File transfer utility through SSH."""
|
|
9
|
+
if target == "wsl" or source == "wsl":
|
|
10
|
+
_handle_wsl_transfer(source=source, target=target, overwrite_existing=overwrite_existing)
|
|
11
|
+
return
|
|
12
|
+
elif source == "win" or target == "win":
|
|
13
|
+
_handle_win_transfer(source=source, target=target, overwrite_existing=overwrite_existing, windows_username=None)
|
|
14
|
+
return
|
|
15
|
+
|
|
16
|
+
from rich.console import Console
|
|
17
|
+
from rich.panel import Panel
|
|
18
|
+
|
|
19
|
+
console = Console()
|
|
20
|
+
|
|
21
|
+
console.print(
|
|
22
|
+
Panel(
|
|
23
|
+
"\n".join(["🚀 FTP File Transfer", "📋 Starting transfer process..."]),
|
|
24
|
+
title="Transfer Initialisation",
|
|
25
|
+
border_style="blue",
|
|
26
|
+
padding=(1, 2),
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
resolved_source, resolved_target, machine, source_is_remote = _resolve_paths(source=source, target=target)
|
|
31
|
+
|
|
32
|
+
from machineconfig.utils.accessories import pprint
|
|
33
|
+
|
|
34
|
+
pprint({"source": str(resolved_source), "target": str(resolved_target), "machine": machine}, "CLI Resolution")
|
|
35
|
+
|
|
36
|
+
ssh = _create_ssh_connection(machine=machine, console=console)
|
|
37
|
+
|
|
38
|
+
if cloud:
|
|
39
|
+
received_file = _handle_cloud_transfer(ssh=ssh, resolved_source=resolved_source, resolved_target=resolved_target, console=console)
|
|
40
|
+
else:
|
|
41
|
+
received_file = _handle_direct_transfer(
|
|
42
|
+
ssh=ssh,
|
|
43
|
+
resolved_source=resolved_source,
|
|
44
|
+
resolved_target=resolved_target,
|
|
45
|
+
source_is_remote=source_is_remote,
|
|
46
|
+
zipFirst=zipFirst,
|
|
47
|
+
recursive=recursive,
|
|
48
|
+
overwrite_existing=overwrite_existing,
|
|
49
|
+
console=console,
|
|
50
|
+
)
|
|
51
|
+
if source_is_remote and received_file is not None:
|
|
52
|
+
console.print(
|
|
53
|
+
Panel(
|
|
54
|
+
"\n".join(["📁 File Received", f"Parent: [cyan]{repr(received_file.parent)}[/cyan]", f"File: [cyan]{repr(received_file)}[/cyan]"]),
|
|
55
|
+
title="Transfer Result",
|
|
56
|
+
border_style="green",
|
|
57
|
+
padding=(1, 2),
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
console.print(Panel("File transfer process finished successfully", title="✅ Transfer Complete", border_style="green", padding=(1, 2)))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _handle_wsl_transfer(source: str, target: str, overwrite_existing: bool) -> None:
|
|
64
|
+
"""Handle WSL transfer when inside Windows."""
|
|
65
|
+
from machineconfig.utils.ssh_utils.wsl import copy_when_inside_windows
|
|
66
|
+
|
|
67
|
+
if target == "wsl":
|
|
68
|
+
target_obj = Path(source).expanduser().absolute().relative_to(Path.home())
|
|
69
|
+
source_obj = target_obj
|
|
70
|
+
else:
|
|
71
|
+
source_obj = Path(target).expanduser().absolute().relative_to(Path.home())
|
|
72
|
+
target_obj = source_obj
|
|
73
|
+
copy_when_inside_windows(source_obj, target_obj, overwrite_existing)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _handle_win_transfer(source: str, target: str, overwrite_existing: bool, windows_username: str | None) -> None:
|
|
77
|
+
"""Handle Windows transfer when inside WSL."""
|
|
78
|
+
from machineconfig.utils.ssh_utils.wsl import copy_when_inside_wsl
|
|
79
|
+
|
|
80
|
+
if source == "win":
|
|
81
|
+
source_obj = Path(target).expanduser().absolute().relative_to(Path.home())
|
|
82
|
+
target_obj = source_obj
|
|
83
|
+
else:
|
|
84
|
+
target_obj = Path(source).expanduser().absolute().relative_to(Path.home())
|
|
85
|
+
source_obj = target_obj
|
|
86
|
+
copy_when_inside_wsl(source_obj, target_obj, overwrite_existing, windows_username=windows_username)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _resolve_paths(source: str, target: str) -> tuple[Optional[str], Optional[str], str, bool]:
|
|
90
|
+
"""Resolve source and target paths, determine machine and direction."""
|
|
91
|
+
from machineconfig.utils.path_extended import PathExtended
|
|
92
|
+
from machineconfig.scripts.python.helpers.helpers_cloud.helpers2 import ES
|
|
93
|
+
|
|
94
|
+
resolved_source: Optional[str] = None
|
|
95
|
+
resolved_target: Optional[str] = None
|
|
96
|
+
machine: str = ""
|
|
97
|
+
source_is_remote: bool = False
|
|
98
|
+
|
|
99
|
+
if ":" in source and (source[1] != ":" if len(source) > 1 else True):
|
|
100
|
+
source_is_remote = True
|
|
101
|
+
source_parts = source.split(":")
|
|
102
|
+
machine = source_parts[0]
|
|
103
|
+
if len(source_parts) > 1 and source_parts[1] == ES:
|
|
104
|
+
if target == ES:
|
|
105
|
+
raise ValueError(f"""
|
|
106
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
107
|
+
┃ ❌ Configuration Error
|
|
108
|
+
┃ Cannot use expand symbol `{ES}` in both source and target
|
|
109
|
+
┃ This creates a cyclical inference dependency
|
|
110
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━""")
|
|
111
|
+
else:
|
|
112
|
+
target_path_obj = PathExtended(target).expanduser().absolute()
|
|
113
|
+
resolved_source = target_path_obj.collapseuser().as_posix()
|
|
114
|
+
resolved_target = target
|
|
115
|
+
else:
|
|
116
|
+
resolved_source = ":".join(source.split(":")[1:])
|
|
117
|
+
if target == ES:
|
|
118
|
+
resolved_target = None
|
|
119
|
+
else:
|
|
120
|
+
resolved_target = PathExtended(target).expanduser().absolute().as_posix()
|
|
121
|
+
|
|
122
|
+
elif ":" in target and (target[1] != ":" if len(target) > 1 else True):
|
|
123
|
+
source_is_remote = False
|
|
124
|
+
target_parts = target.split(":")
|
|
125
|
+
machine = target_parts[0]
|
|
126
|
+
if len(target_parts) > 1 and target_parts[1] == ES:
|
|
127
|
+
if source == ES:
|
|
128
|
+
raise ValueError(f"""
|
|
129
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
130
|
+
┃ ❌ Configuration Error
|
|
131
|
+
┃ Cannot use expand symbol `{ES}` in both source and target
|
|
132
|
+
┃ This creates a cyclical inference dependency
|
|
133
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━""")
|
|
134
|
+
else:
|
|
135
|
+
resolved_source = source
|
|
136
|
+
resolved_target = None
|
|
137
|
+
else:
|
|
138
|
+
resolved_target = ":".join(target.split(":")[1:])
|
|
139
|
+
if source == ES:
|
|
140
|
+
resolved_source = None
|
|
141
|
+
else:
|
|
142
|
+
resolved_source = PathExtended(source).expanduser().absolute().as_posix()
|
|
143
|
+
else:
|
|
144
|
+
raise ValueError("""
|
|
145
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
146
|
+
┃ ❌ Path Error
|
|
147
|
+
┃ Either source or target must be a remote path
|
|
148
|
+
┃ Format should be: machine:path
|
|
149
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━""")
|
|
150
|
+
|
|
151
|
+
return resolved_source, resolved_target, machine, source_is_remote
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def _create_ssh_connection(machine: str, console: "Console") -> "SSH": # type: ignore[name-defined]
|
|
155
|
+
"""Create SSH connection, handling authentication."""
|
|
156
|
+
from machineconfig.utils.ssh import SSH
|
|
157
|
+
from paramiko.ssh_exception import AuthenticationException # type: ignore
|
|
158
|
+
from rich.panel import Panel
|
|
159
|
+
|
|
160
|
+
try:
|
|
161
|
+
ssh = SSH(host=rf"{machine}", username=None, hostname=None, ssh_key_path=None, password=None, port=22, enable_compression=True)
|
|
162
|
+
except AuthenticationException:
|
|
163
|
+
console.print(
|
|
164
|
+
Panel(
|
|
165
|
+
"\n".join(
|
|
166
|
+
[
|
|
167
|
+
"🔑 Authentication failed. Trying manual authentication...",
|
|
168
|
+
"⚠️ Ensure that the username is provided correctly; only password prompts are handled here.",
|
|
169
|
+
]
|
|
170
|
+
),
|
|
171
|
+
title="Authentication Required",
|
|
172
|
+
border_style="yellow",
|
|
173
|
+
padding=(1, 2),
|
|
174
|
+
)
|
|
175
|
+
)
|
|
176
|
+
import getpass
|
|
177
|
+
|
|
178
|
+
pwd = getpass.getpass()
|
|
179
|
+
ssh = SSH(host=rf"{machine}", username=None, hostname=None, ssh_key_path=None, password=pwd, port=22, enable_compression=True)
|
|
180
|
+
|
|
181
|
+
return ssh
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _handle_cloud_transfer(
|
|
185
|
+
ssh: "SSH", resolved_source: Optional[str], resolved_target: Optional[str], console: "Console"
|
|
186
|
+
) -> Optional["PathExtended"]: # type: ignore[name-defined]
|
|
187
|
+
"""Handle cloud transfer mode."""
|
|
188
|
+
from machineconfig.utils.path_extended import PathExtended
|
|
189
|
+
from rich.panel import Panel
|
|
190
|
+
|
|
191
|
+
console.print(Panel.fit("☁️ Cloud transfer mode — uploading from remote to cloud...", title="Cloud Upload", border_style="cyan"))
|
|
192
|
+
ssh.run_shell_cmd_on_remote(
|
|
193
|
+
command=f"cloud copy {resolved_source} :^",
|
|
194
|
+
verbose_output=True,
|
|
195
|
+
description="Uploading from remote to the cloud.",
|
|
196
|
+
strict_stderr=False,
|
|
197
|
+
strict_return_code=False,
|
|
198
|
+
)
|
|
199
|
+
console.print(Panel.fit("⬇️ Cloud transfer mode — downloading from cloud to local...", title="Cloud Download", border_style="cyan"))
|
|
200
|
+
ssh.run_shell_cmd_on_local(command=f"cloud copy :^ {resolved_target}")
|
|
201
|
+
return PathExtended(resolved_target) # type: ignore
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def _handle_direct_transfer(
|
|
205
|
+
ssh: "SSH",
|
|
206
|
+
resolved_source: Optional[str],
|
|
207
|
+
resolved_target: Optional[str],
|
|
208
|
+
source_is_remote: bool,
|
|
209
|
+
zipFirst: bool,
|
|
210
|
+
recursive: bool,
|
|
211
|
+
overwrite_existing: bool,
|
|
212
|
+
console: "Console",
|
|
213
|
+
) -> Optional["PathExtended"]: # type: ignore[name-defined]
|
|
214
|
+
"""Handle direct SSH transfer."""
|
|
215
|
+
from rich.panel import Panel
|
|
216
|
+
|
|
217
|
+
if source_is_remote:
|
|
218
|
+
if resolved_source is None:
|
|
219
|
+
print("❌ Path Error: Source must be a remote path (machine:path)")
|
|
220
|
+
return None
|
|
221
|
+
target_display = resolved_target or "<auto>"
|
|
222
|
+
console.print(
|
|
223
|
+
Panel(
|
|
224
|
+
"\n".join(
|
|
225
|
+
[
|
|
226
|
+
"📥 Transfer Mode: Remote → Local",
|
|
227
|
+
f"Source: [cyan]{resolved_source}[/cyan]",
|
|
228
|
+
f"Target: [cyan]{target_display}[/cyan]",
|
|
229
|
+
f"Options: {'ZIP compression' if zipFirst else 'No compression'}, {'Recursive' if recursive else 'Non-recursive'}",
|
|
230
|
+
]
|
|
231
|
+
),
|
|
232
|
+
title="Transfer Details",
|
|
233
|
+
border_style="cyan",
|
|
234
|
+
padding=(1, 2),
|
|
235
|
+
)
|
|
236
|
+
)
|
|
237
|
+
received_file = ssh.copy_to_here(source=resolved_source, target=resolved_target, compress_with_zip=zipFirst, recursive=recursive)
|
|
238
|
+
else:
|
|
239
|
+
assert resolved_source is not None, "❌ Path Error: Target must be a remote path (machine:path)"
|
|
240
|
+
target_display = resolved_target or "<auto>"
|
|
241
|
+
console.print(
|
|
242
|
+
Panel(
|
|
243
|
+
"\n".join(
|
|
244
|
+
[
|
|
245
|
+
"📤 Transfer Mode: Local → Remote",
|
|
246
|
+
f"Source: [cyan]{resolved_source}[/cyan]",
|
|
247
|
+
f"Target: [cyan]{target_display}[/cyan]",
|
|
248
|
+
f"Options: {'ZIP compression' if zipFirst else 'No compression'}, {'Recursive' if recursive else 'Non-recursive'}",
|
|
249
|
+
]
|
|
250
|
+
),
|
|
251
|
+
title="Transfer Details",
|
|
252
|
+
border_style="cyan",
|
|
253
|
+
padding=(1, 2),
|
|
254
|
+
)
|
|
255
|
+
)
|
|
256
|
+
received_file = ssh.copy_from_here(
|
|
257
|
+
source_path=resolved_source,
|
|
258
|
+
target_rel2home=resolved_target,
|
|
259
|
+
compress_with_zip=zipFirst,
|
|
260
|
+
recursive=recursive,
|
|
261
|
+
overwrite_existing=overwrite_existing,
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
return received_file
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
if __name__ == "__main__":
|
|
268
|
+
from machineconfig.utils.ssh import SSH
|
|
269
|
+
|
|
270
|
+
_ = SSH
|
|
271
|
+
from machineconfig.utils.path_extended import PathExtended
|
|
272
|
+
|
|
273
|
+
_ = PathExtended
|
|
274
|
+
from rich.console import Console
|
|
275
|
+
|
|
276
|
+
_ = Console
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from platform import system
|
|
4
4
|
import subprocess
|
|
5
5
|
from machineconfig.utils.ssh import SSH
|
|
6
|
-
from
|
|
6
|
+
from pathlib import Path
|
|
7
7
|
|
|
8
8
|
from machineconfig.utils.options import choose_ssh_host
|
|
9
9
|
|
|
@@ -35,7 +35,7 @@ def main():
|
|
|
35
35
|
|
|
36
36
|
mount_point = input(f"📂 Enter the mount point directory (e.g., /mnt/network) [Default: ~/data/mount_ssh/{ssh.hostname}]: ")
|
|
37
37
|
if mount_point == "":
|
|
38
|
-
mount_point =
|
|
38
|
+
mount_point = Path.home().joinpath(rf"data/mount_ssh/{ssh.hostname}")
|
|
39
39
|
|
|
40
40
|
print(f"\n📁 Mount Point: {mount_point}")
|
|
41
41
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
r"""ID
|
|
2
|
+
|
|
3
|
+
On windows:
|
|
4
|
+
|
|
5
|
+
$sshfile = "$env:USERPROFILE/.ssh/id_rsa"
|
|
6
|
+
Set-Service ssh-agent -StartupType Manual # allow the service to be started manually
|
|
7
|
+
ssh-agent # start the service
|
|
8
|
+
ssh-add.exe $sshfile # add the key to the agent
|
|
9
|
+
|
|
10
|
+
# copy ssh key:
|
|
11
|
+
# This is the Windows equivalent of copy-ssh-id on Linux.
|
|
12
|
+
# Just like the original function, it is a convenient way of doing two things in one go:
|
|
13
|
+
# 1- copy a certain public key to the remote machine.
|
|
14
|
+
# scp ~/.ssh/id_rsa.pub $remote_user@$remote_host:~/.ssh/authorized_keys
|
|
15
|
+
# 2- Store the value on the remote in a file called .ssh/authorized_keys
|
|
16
|
+
# ssh $remote_user@$remote_host "echo $public_key >> ~/.ssh/authorized_keys"
|
|
17
|
+
# Idea from: https://www.chrisjhart.com/Windows-10-ssh-copy-id/
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from machineconfig.utils.path_extended import PathExtended
|
|
24
|
+
from machineconfig.utils.options import choose_from_options
|
|
25
|
+
from rich.console import Console
|
|
26
|
+
from rich.panel import Panel
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
console = Console()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def main() -> None:
|
|
33
|
+
private_keys = [PathExtended(x).with_name(x.stem) for x in PathExtended.home().joinpath(".ssh").glob("*.pub")]
|
|
34
|
+
key_status = f"Found {len(private_keys)} key(s)" if private_keys else "No keys found"
|
|
35
|
+
console.print(Panel(f"🔑 SSH Identity Management\n🔍 {key_status} in ~/.ssh", title="[bold blue]Setup[/bold blue]", expand=False))
|
|
36
|
+
|
|
37
|
+
choice = choose_from_options(msg="Path to private key to be used when ssh'ing: ", options=[str(x) for x in private_keys] + ["I have the path to the key file", "I want to paste the key itself"], multi=False)
|
|
38
|
+
|
|
39
|
+
if choice == "I have the path to the key file":
|
|
40
|
+
path_to_key = PathExtended(input("📋 Enter path to private key: ")).expanduser().absolute()
|
|
41
|
+
elif choice == "I want to paste the key itself":
|
|
42
|
+
key_filename = input("📝 File name (default: my_pasted_key): ") or "my_pasted_key"
|
|
43
|
+
path_to_key = PathExtended.home().joinpath(f".ssh/{key_filename}")
|
|
44
|
+
path_to_key.parent.mkdir(parents=True, exist_ok=True)
|
|
45
|
+
path_to_key.write_text(input("🔑 Paste the private key: "), encoding="utf-8")
|
|
46
|
+
else:
|
|
47
|
+
path_to_key = PathExtended(choice)
|
|
48
|
+
|
|
49
|
+
txt = f"IdentityFile {path_to_key.collapseuser().as_posix()}"
|
|
50
|
+
config_path = PathExtended.home().joinpath(".ssh/config")
|
|
51
|
+
|
|
52
|
+
if config_path.exists():
|
|
53
|
+
current = config_path.read_text(encoding="utf-8")
|
|
54
|
+
config_action = "updated"
|
|
55
|
+
else:
|
|
56
|
+
current = txt
|
|
57
|
+
config_action = "created"
|
|
58
|
+
lines = current.split("\n")
|
|
59
|
+
found = False
|
|
60
|
+
for i, line in enumerate(lines):
|
|
61
|
+
if txt in line:
|
|
62
|
+
lines[i] = txt
|
|
63
|
+
found = True
|
|
64
|
+
if not found:
|
|
65
|
+
lines.insert(0, txt)
|
|
66
|
+
config_path.write_text("\n".join(lines), encoding="utf-8")
|
|
67
|
+
|
|
68
|
+
console.print(Panel(f"✅ Identity: {path_to_key.name}\n📄 Config {config_action}: {config_path}", title="[bold green]Complete[/bold green]", expand=False, border_style="green"))
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
pass
|