machineconfig 1.92__py3-none-any.whl → 1.94__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/__init__.py +0 -8
- machineconfig/cluster/__init__.py +0 -0
- machineconfig/cluster/cloud_manager.py +359 -0
- machineconfig/cluster/data_transfer.py +56 -0
- machineconfig/cluster/distribute.py +280 -0
- machineconfig/cluster/file_manager.py +238 -0
- machineconfig/cluster/job_params.py +148 -0
- machineconfig/cluster/loader_runner.py +150 -0
- machineconfig/cluster/remote_machine.py +281 -0
- machineconfig/cluster/script_execution.py +209 -0
- machineconfig/cluster/script_notify_upon_completion.py +63 -0
- machineconfig/cluster/self_ssh.py +59 -0
- machineconfig/cluster/session_managers.py +183 -0
- machineconfig/cluster/templates/__init__.py +0 -0
- machineconfig/cluster/templates/cli_click.py +104 -0
- machineconfig/cluster/templates/cli_gooey.py +119 -0
- machineconfig/cluster/templates/cli_trogon.py +21 -0
- machineconfig/cluster/templates/f.py +4 -0
- machineconfig/cluster/templates/run_cloud.py +52 -0
- machineconfig/cluster/templates/run_cluster.py +69 -0
- machineconfig/cluster/templates/run_remote.py +67 -0
- machineconfig/cluster/templates/utils.py +37 -0
- machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/linux/msc/lid.sh +26 -0
- machineconfig/jobs/linux/msc/network.sh +39 -0
- machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python/__pycache__/check_installations.cpython-311.pyc +0 -0
- machineconfig/jobs/python/__pycache__/checkout_version.cpython-311.pyc +0 -0
- machineconfig/jobs/python/__pycache__/python_ve_symlink.cpython-311.pyc +0 -0
- machineconfig/jobs/python/archive/python_tools.txt +12 -0
- machineconfig/jobs/python/check_installations.py +26 -11
- machineconfig/jobs/python/checkout_version.py +24 -13
- machineconfig/jobs/python/create_zellij_template.py +4 -4
- machineconfig/jobs/python/python_cargo_build_share.py +13 -4
- machineconfig/jobs/python/python_ve_symlink.py +15 -4
- machineconfig/jobs/python/vscode/__pycache__/api.cpython-311.pyc +0 -0
- machineconfig/jobs/python/vscode/__pycache__/link_ve.cpython-311.pyc +0 -0
- machineconfig/jobs/python/vscode/api.py +48 -0
- machineconfig/jobs/python/vscode/link_ve.py +64 -0
- machineconfig/jobs/python/vscode/select_interpreter.py +84 -0
- machineconfig/jobs/python/vscode/sync_code.py +60 -0
- machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python_custom_installers/__pycache__/hx.cpython-311.pyc +0 -0
- machineconfig/jobs/python_custom_installers/archive/ngrok.py +62 -0
- machineconfig/jobs/python_custom_installers/dev/aider.py +37 -0
- machineconfig/jobs/python_custom_installers/dev/alacritty.py +72 -0
- machineconfig/jobs/python_custom_installers/dev/brave.py +67 -0
- machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +50 -0
- machineconfig/jobs/python_custom_installers/dev/code.py +62 -0
- machineconfig/jobs/python_custom_installers/dev/cursor.py +67 -0
- machineconfig/jobs/python_custom_installers/dev/docker.py +70 -0
- machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +77 -0
- machineconfig/jobs/python_custom_installers/dev/espanso.py +82 -0
- machineconfig/jobs/python_custom_installers/dev/goes.py +59 -0
- machineconfig/jobs/python_custom_installers/dev/lvim.py +76 -0
- machineconfig/jobs/python_custom_installers/dev/nerdfont.py +67 -0
- machineconfig/jobs/python_custom_installers/dev/redis.py +69 -0
- machineconfig/jobs/python_custom_installers/dev/reverse_proxy.md +31 -0
- machineconfig/jobs/python_custom_installers/dev/warp-cli.py +71 -0
- machineconfig/jobs/python_custom_installers/dev/wezterm.py +71 -0
- machineconfig/jobs/python_custom_installers/gh.py +46 -4
- machineconfig/jobs/python_custom_installers/hx.py +103 -18
- machineconfig/jobs/python_custom_installers/scripts/linux/brave.sh +52 -0
- machineconfig/jobs/python_custom_installers/scripts/linux/docker.sh +140 -0
- machineconfig/jobs/python_custom_installers/scripts/linux/docker_start.sh +48 -0
- machineconfig/jobs/python_custom_installers/scripts/linux/edge.sh +47 -0
- machineconfig/jobs/python_custom_installers/scripts/linux/nerdfont.sh +64 -0
- machineconfig/jobs/python_custom_installers/scripts/linux/pgsql.sh +53 -0
- machineconfig/jobs/python_custom_installers/scripts/linux/redis.sh +76 -0
- machineconfig/jobs/python_custom_installers/scripts/linux/timescaledb.sh +91 -0
- machineconfig/jobs/python_custom_installers/scripts/linux/vscode.sh +66 -0
- machineconfig/jobs/python_custom_installers/scripts/linux/warp-cli.sh +77 -0
- machineconfig/jobs/python_custom_installers/scripts/linux/wezterm.sh +43 -0
- machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python_generic_installers/config.json +267 -0
- machineconfig/jobs/python_generic_installers/dev/config.archive.json +18 -0
- machineconfig/jobs/python_generic_installers/dev/config.json +394 -0
- machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python_linux_installers/archive/config.json +10 -0
- machineconfig/jobs/python_linux_installers/config.json +74 -0
- machineconfig/jobs/python_linux_installers/dev/config.json +138 -0
- machineconfig/jobs/python_windows_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python_windows_installers/archive/file.json +11 -0
- machineconfig/jobs/python_windows_installers/config.json +50 -0
- machineconfig/jobs/python_windows_installers/dev/config.json +3 -0
- machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +14 -0
- machineconfig/jobs/windows/archive/openssh-server_add_key.ps1 +7 -0
- machineconfig/jobs/windows/archive/openssh-server_copy-ssh-id.ps1 +14 -0
- machineconfig/jobs/windows/start_terminal.ps1 +6 -0
- machineconfig/jobs/windows/startup_file.cmd +2 -0
- machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
- machineconfig/profile/create.py +47 -13
- machineconfig/profile/create_hardlinks.py +42 -12
- machineconfig/profile/records/generic/shares.toml +5 -0
- machineconfig/profile/records/linux/apps_summary_report.csv +48 -0
- machineconfig/profile/records/linux/apps_summary_report.md +49 -0
- machineconfig/profile/records/windows/apps_summary_report.csv +1 -0
- machineconfig/profile/records/windows/apps_summary_report.md +2 -0
- machineconfig/profile/shell.py +62 -11
- machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/cloud/init.sh +128 -0
- machineconfig/scripts/linux/activate_ve +87 -0
- machineconfig/scripts/linux/archive/tmate_conn +12 -0
- machineconfig/scripts/linux/archive/tmate_start +12 -0
- machineconfig/scripts/linux/archive/transfer_wsl_win +5 -0
- machineconfig/scripts/linux/checkout_versions +8 -0
- machineconfig/scripts/linux/choose_wezterm_theme +9 -0
- machineconfig/scripts/linux/cloud_copy +9 -0
- machineconfig/scripts/linux/cloud_manager +8 -0
- machineconfig/scripts/linux/cloud_mount +24 -0
- machineconfig/scripts/linux/cloud_repo_sync +22 -0
- machineconfig/scripts/linux/cloud_sync +24 -0
- machineconfig/scripts/linux/croshell +24 -0
- machineconfig/scripts/linux/devops +24 -0
- machineconfig/scripts/linux/fire +46 -0
- machineconfig/scripts/linux/ftpx +8 -0
- machineconfig/scripts/linux/fzf2g +21 -0
- machineconfig/scripts/linux/fzfag +17 -0
- machineconfig/scripts/linux/fzffg +25 -0
- machineconfig/scripts/linux/fzfg +23 -0
- machineconfig/scripts/linux/fzfrga +21 -0
- machineconfig/scripts/linux/gh_models +11 -0
- machineconfig/scripts/linux/kill_process +10 -0
- machineconfig/scripts/linux/mount_drive +128 -0
- machineconfig/scripts/linux/mount_nfs +62 -0
- machineconfig/scripts/linux/mount_nw_drive +72 -0
- machineconfig/scripts/linux/mount_smb +3 -0
- machineconfig/scripts/linux/programs +21 -0
- machineconfig/scripts/linux/repos +24 -0
- machineconfig/scripts/linux/scheduler +8 -0
- machineconfig/scripts/linux/share_cloud.sh +81 -0
- machineconfig/scripts/linux/share_nfs +49 -0
- machineconfig/scripts/linux/share_smb +1 -0
- machineconfig/scripts/linux/skrg +4 -0
- machineconfig/scripts/linux/start_docker +23 -0
- machineconfig/scripts/linux/start_slidev +23 -0
- machineconfig/scripts/linux/start_terminals +12 -0
- machineconfig/scripts/linux/switch_ip +20 -0
- machineconfig/scripts/linux/url2md +10 -0
- machineconfig/scripts/linux/z_ls +104 -0
- machineconfig/scripts/python/.mypy_cache/.gitignore +2 -0
- machineconfig/scripts/python/.mypy_cache/3.11/@plugins_snapshot.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/__future__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/__future__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_ast.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_ast.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_bz2.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_bz2.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_codecs.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_codecs.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_collections_abc.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_collections_abc.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_compression.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_compression.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_decimal.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_decimal.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_frozen_importlib.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_frozen_importlib.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_frozen_importlib_external.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_frozen_importlib_external.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_io.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_io.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_locale.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_locale.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_stat.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_stat.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_struct.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_struct.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_thread.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_thread.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_typeshed/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_typeshed/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_typeshed/importlib.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_typeshed/importlib.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_warnings.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_warnings.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_weakref.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_weakref.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_weakrefset.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/_weakrefset.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/abc.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/abc.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/argparse.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/argparse.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/ast.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/ast.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/binascii.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/binascii.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/builtins.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/builtins.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/bz2.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/bz2.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/calendar.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/calendar.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/codecs.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/codecs.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/collections/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/collections/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/collections/abc.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/collections/abc.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/configparser.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/configparser.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/contextlib.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/contextlib.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/dataclasses.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/dataclasses.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/datetime.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/datetime.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/decimal.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/decimal.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/dis.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/dis.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/_policybase.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/_policybase.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/charset.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/charset.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/contentmanager.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/contentmanager.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/errors.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/errors.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/header.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/header.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/message.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/message.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/policy.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/email/policy.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/enum.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/enum.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/fnmatch.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/fnmatch.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/functools.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/functools.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/gc.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/gc.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/genericpath.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/genericpath.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/getpass.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/getpass.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/cmd.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/cmd.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/compat.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/compat.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/config.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/config.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/db.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/db.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/diff.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/diff.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/exc.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/exc.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/index/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/index/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/index/base.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/index/base.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/index/fun.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/index/fun.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/index/typ.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/index/typ.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/index/util.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/index/util.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/base.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/base.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/blob.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/blob.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/commit.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/commit.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/fun.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/fun.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/base.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/base.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/root.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/root.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/util.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/submodule/util.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/tag.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/tag.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/tree.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/tree.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/util.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/objects/util.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/head.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/head.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/log.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/log.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/reference.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/reference.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/remote.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/remote.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/symbolic.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/symbolic.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/tag.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/refs/tag.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/remote.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/remote.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/repo/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/repo/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/repo/base.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/repo/base.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/repo/fun.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/repo/fun.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/types.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/types.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/util.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/git/util.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/glob.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/glob.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/gzip.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/gzip.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/_abc.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/_abc.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/_bootstrap.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/_bootstrap.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/_bootstrap_external.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/_bootstrap_external.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/abc.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/abc.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/machinery.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/machinery.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/metadata/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/metadata/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/metadata/_meta.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/metadata/_meta.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/readers.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/readers.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/resources/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/resources/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/resources/_common.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/resources/_common.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/resources/abc.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/importlib/resources/abc.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/inspect.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/inspect.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/io.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/io.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/itertools.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/itertools.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/locale.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/locale.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/logging/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/logging/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/mimetypes.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/mimetypes.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/mmap.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/mmap.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/numbers.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/numbers.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/opcode.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/opcode.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/os/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/os/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/os/path.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/os/path.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/pathlib.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/pathlib.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/platform.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/platform.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/posixpath.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/posixpath.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/re.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/re.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/resource.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/resource.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/shlex.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/shlex.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/shutil.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/shutil.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/signal.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/signal.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/src/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/src/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/src/machineconfig/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/src/machineconfig/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/src/machineconfig/scripts/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/src/machineconfig/scripts/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/src/machineconfig/scripts/python/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/src/machineconfig/scripts/python/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/sre_compile.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/sre_compile.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/sre_constants.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/sre_constants.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/sre_parse.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/sre_parse.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/stat.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/stat.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/string.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/string.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/struct.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/struct.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/subprocess.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/subprocess.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/sys/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/sys/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/tarfile.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/tarfile.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/tempfile.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/tempfile.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/textwrap.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/textwrap.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/threading.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/threading.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/time.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/time.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/types.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/types.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/typing.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/typing.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/typing_extensions.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/typing_extensions.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/urllib/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/urllib/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/urllib/parse.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/urllib/parse.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/uuid.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/uuid.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/warnings.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/warnings.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/weakref.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/weakref.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/zipfile/__init__.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/zipfile/__init__.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/zlib.data.json +1 -0
- machineconfig/scripts/python/.mypy_cache/3.11/zlib.meta.json +1 -0
- machineconfig/scripts/python/.mypy_cache/CACHEDIR.TAG +3 -0
- machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_copy.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_mount.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_repo_sync.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_sync.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_backup_retrieve.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/gh_models.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/url2md.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/viewer.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/vscode_api.cpython-311.pyc +0 -0
- machineconfig/scripts/python/archive/im2text.py +36 -0
- machineconfig/scripts/python/archive/tmate_conn.py +44 -0
- machineconfig/scripts/python/archive/tmate_start.py +48 -0
- machineconfig/scripts/python/choose_wezterm_theme.py +23 -4
- machineconfig/scripts/python/cloud_copy.py +131 -29
- machineconfig/scripts/python/cloud_manager.py +55 -2
- machineconfig/scripts/python/cloud_mount.py +43 -4
- machineconfig/scripts/python/cloud_repo_sync.py +114 -103
- machineconfig/scripts/python/cloud_sync.py +36 -220
- machineconfig/scripts/python/croshell.py +102 -32
- machineconfig/scripts/python/devops.py +143 -42
- machineconfig/scripts/python/devops_add_identity.py +112 -9
- machineconfig/scripts/python/devops_add_ssh_key.py +170 -15
- machineconfig/scripts/python/devops_backup_retrieve.py +132 -14
- machineconfig/scripts/python/devops_devapps_install.py +33 -11
- machineconfig/scripts/python/devops_update_repos.py +36 -29
- machineconfig/scripts/python/dotfile.py +8 -3
- machineconfig/scripts/python/fire_jobs.py +145 -289
- machineconfig/scripts/python/ftpx.py +76 -18
- machineconfig/scripts/python/get_zellij_cmd.py +14 -0
- machineconfig/scripts/python/gh_models.py +72 -25
- machineconfig/scripts/python/helpers/__init__.py +0 -0
- machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/cloud_helpers.py +134 -0
- machineconfig/scripts/python/helpers/helpers2.py +149 -0
- machineconfig/scripts/python/helpers/helpers4.py +178 -0
- machineconfig/scripts/python/helpers/helpers5.py +50 -0
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +126 -0
- machineconfig/scripts/python/mount_nfs.py +46 -15
- machineconfig/scripts/python/mount_nw_drive.py +22 -10
- machineconfig/scripts/python/mount_ssh.py +28 -12
- machineconfig/scripts/python/onetimeshare.py +23 -15
- machineconfig/scripts/python/pomodoro.py +38 -24
- machineconfig/scripts/python/repos.py +29 -32
- machineconfig/scripts/python/scheduler.py +19 -18
- machineconfig/scripts/python/snapshot.py +14 -6
- machineconfig/scripts/python/start_slidev.py +24 -32
- machineconfig/scripts/python/start_terminals.py +23 -10
- machineconfig/scripts/python/viewer.py +53 -0
- machineconfig/scripts/python/viewer_template.py +140 -0
- machineconfig/scripts/python/wifi_conn.py +20 -12
- machineconfig/scripts/python/wsl_windows_transfer.py +18 -10
- machineconfig/scripts/windows/activate_ve.ps1 +54 -0
- machineconfig/scripts/windows/archive/gource2vid.ps1 +14 -0
- machineconfig/scripts/windows/archive/im2text.ps1 +27 -0
- machineconfig/scripts/windows/archive/secure_pull.ps1 +46 -0
- machineconfig/scripts/windows/archive/secure_push.ps1 +85 -0
- machineconfig/scripts/windows/archive/tmate_conn.ps1 +7 -0
- machineconfig/scripts/windows/checkout_version.ps1 +6 -0
- machineconfig/scripts/windows/choose_wezterm_theme.ps1 +20 -0
- machineconfig/scripts/windows/cloud_copy.ps1 +17 -0
- machineconfig/scripts/windows/cloud_manager.ps1 +8 -0
- machineconfig/scripts/windows/cloud_mount.ps1 +25 -0
- machineconfig/scripts/windows/cloud_repo_sync.ps1 +8 -0
- machineconfig/scripts/windows/cloud_sync.ps1 +21 -0
- machineconfig/scripts/windows/croshell.ps1 +40 -0
- machineconfig/scripts/windows/devops.ps1 +32 -0
- machineconfig/scripts/windows/dotfile.ps1 +9 -0
- machineconfig/scripts/windows/fire.ps1 +33 -0
- machineconfig/scripts/windows/ftpx.ps1 +5 -0
- machineconfig/scripts/windows/fzfb.ps1 +3 -0
- machineconfig/scripts/windows/fzfg.ps1 +2 -0
- machineconfig/scripts/windows/fzfrga.bat +20 -0
- machineconfig/scripts/windows/gpt.ps1 +23 -0
- machineconfig/scripts/windows/grep.ps1 +2 -0
- machineconfig/scripts/windows/kill_process.ps1 +8 -0
- machineconfig/scripts/windows/mount_nfs.ps1 +44 -0
- machineconfig/scripts/windows/mount_nw.ps1 +9 -0
- machineconfig/scripts/windows/mount_smb.ps1 +2 -0
- machineconfig/scripts/windows/mount_ssh.ps1 +17 -0
- machineconfig/scripts/windows/nano.ps1 +3 -0
- machineconfig/scripts/windows/neofetch.ps1 +2 -0
- machineconfig/scripts/windows/pomodoro.ps1 +8 -0
- machineconfig/scripts/windows/py2exe.ps1 +12 -0
- machineconfig/scripts/windows/reload_path.ps1 +3 -0
- machineconfig/scripts/windows/repos.ps1 +27 -0
- machineconfig/scripts/windows/scheduler.ps1 +6 -0
- machineconfig/scripts/windows/share_cloud.cmd +34 -0
- machineconfig/scripts/windows/share_nfs.ps1 +0 -0
- machineconfig/scripts/windows/share_smb.ps1 +22 -0
- machineconfig/scripts/windows/snapshot.ps1 +5 -0
- machineconfig/scripts/windows/start_slidev.ps1 +21 -0
- machineconfig/scripts/windows/start_terminals.ps1 +22 -0
- machineconfig/scripts/windows/unlock_bitlocker.ps1 +10 -0
- machineconfig/scripts/windows/utils/op_script_delete.ps1 +7 -0
- machineconfig/scripts/windows/wifi_conn.ps1 +7 -0
- machineconfig/scripts/windows/wsl_rdp_windows_port_forwarding.ps1 +46 -0
- machineconfig/scripts/windows/wsl_ssh_windows_port_forwarding.ps1 +76 -0
- machineconfig/scripts/windows/wsl_windows_transfer.ps1 +7 -0
- machineconfig/settings/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/settings/broot/br.sh +51 -0
- machineconfig/settings/broot/brootcd.ps1 +32 -0
- machineconfig/settings/broot/conf.toml +5 -0
- machineconfig/settings/glow/glow.yml +11 -0
- machineconfig/settings/gromit-mpx/gromit-mpx.cfg +34 -0
- machineconfig/settings/helix/config.toml +27 -0
- machineconfig/settings/helix/languages.toml +22 -0
- machineconfig/settings/keras/keras.json +6 -0
- machineconfig/settings/keyboard/espanso/config/default.yml +45 -0
- machineconfig/settings/keyboard/espanso/match/base.yml +57 -0
- machineconfig/settings/keyboard/kanata/kanata.kbd +0 -0
- machineconfig/settings/lf/linux/autocall/delete.sh +0 -0
- machineconfig/settings/lf/linux/autocall/on-cd.sh +0 -0
- machineconfig/settings/lf/linux/autocall/on-quit.sh +0 -0
- machineconfig/settings/lf/linux/autocall/open.sh +0 -0
- machineconfig/settings/lf/linux/autocall/paste.sh +0 -0
- machineconfig/settings/lf/linux/autocall/pre-cd.sh +0 -0
- machineconfig/settings/lf/linux/autocall/rename.sh +0 -0
- machineconfig/settings/lf/linux/colors +196 -0
- machineconfig/settings/lf/linux/exe/cleaner.sh +7 -0
- machineconfig/settings/lf/linux/exe/fzf_nano.sh +16 -0
- machineconfig/settings/lf/linux/exe/leftpane_previewer.sh +5 -0
- machineconfig/settings/lf/linux/exe/lfcd.sh +32 -0
- machineconfig/settings/lf/linux/exe/previewer.sh +37 -0
- machineconfig/settings/lf/linux/exe/previewer_archive.sh +155 -0
- machineconfig/settings/lf/linux/icons +357 -0
- machineconfig/settings/lf/linux/lfrc +226 -0
- machineconfig/settings/lf/windows/autocall/delete.ps1 +0 -0
- machineconfig/settings/lf/windows/autocall/on-cd.ps1 +0 -0
- machineconfig/settings/lf/windows/autocall/on-quit.ps1 +0 -0
- machineconfig/settings/lf/windows/autocall/open.ps1 +0 -0
- machineconfig/settings/lf/windows/autocall/paste.ps1 +0 -0
- machineconfig/settings/lf/windows/autocall/pre-cd.ps1 +0 -0
- machineconfig/settings/lf/windows/autocall/rename.ps1 +0 -0
- machineconfig/settings/lf/windows/cd_tere.ps1 +4 -0
- machineconfig/settings/lf/windows/cd_zoxide.ps1 +4 -0
- machineconfig/settings/lf/windows/cd_zoxide2.ps1 +4 -0
- machineconfig/settings/lf/windows/colors +159 -0
- machineconfig/settings/lf/windows/fzf_edit.ps1 +6 -0
- machineconfig/settings/lf/windows/icons +357 -0
- machineconfig/settings/lf/windows/leftpane_previewer.ps1 +3 -0
- machineconfig/settings/lf/windows/lfcd.ps1 +35 -0
- machineconfig/settings/lf/windows/lfrc +133 -0
- machineconfig/settings/lf/windows/mkdir.ps1 +3 -0
- machineconfig/settings/lf/windows/mkfile.ps1 +3 -0
- machineconfig/settings/lf/windows/previewer.ps1 +7 -0
- machineconfig/settings/lf/windows/tst.ps1 +1 -0
- machineconfig/settings/linters/.flake8 +24 -0
- machineconfig/settings/linters/.mypy.ini +29 -0
- machineconfig/settings/linters/.pylintrc +91 -0
- machineconfig/settings/linters/.ruff.toml +77 -0
- machineconfig/settings/linters/.ruff_cache/.gitignore +2 -0
- machineconfig/settings/linters/.ruff_cache/CACHEDIR.TAG +1 -0
- machineconfig/settings/lvim/linux/config.lua +0 -0
- machineconfig/settings/lvim/windows/archive/config_additional.lua +39 -0
- machineconfig/settings/lvim/windows/lua/user/custom_config.lua +13 -0
- machineconfig/settings/mprocs/windows/mprocs.yaml +55 -0
- machineconfig/settings/mprocs/windows/other +12 -0
- machineconfig/settings/pistol/pistol.conf +8 -0
- machineconfig/settings/presenterm/config.yaml +76 -0
- machineconfig/settings/procs/.procs.toml +142 -0
- machineconfig/settings/pudb/pudb.cfg +25 -0
- machineconfig/settings/rofi/config.rasi +4 -0
- machineconfig/settings/rofi/config_default.rasi +147 -0
- machineconfig/settings/shells/alacritty/alacritty.toml +40 -0
- machineconfig/settings/shells/alacritty/alacritty.yml +0 -0
- machineconfig/settings/shells/bash/.inputrc +3 -0
- machineconfig/settings/shells/bash/init.sh +66 -0
- machineconfig/settings/shells/hyper/.hyper.js +201 -0
- machineconfig/settings/shells/ipy/profiles/default/__init__.py +0 -0
- machineconfig/settings/shells/ipy/profiles/default/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/settings/shells/ipy/profiles/default/startup/__init__.py +0 -0
- machineconfig/settings/shells/ipy/profiles/default/startup/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/settings/shells/ipy/profiles/default/startup/__pycache__/playext.cpython-311.pyc +0 -0
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +83 -0
- machineconfig/settings/shells/kitty/kitty.conf +1476 -0
- machineconfig/settings/shells/nushell/config.nu +36 -0
- machineconfig/settings/shells/nushell/env.nu +13 -0
- machineconfig/settings/shells/pwsh/init.ps1 +88 -0
- machineconfig/settings/shells/pwsh/profile.ps1 +0 -0
- machineconfig/settings/shells/starship/starship.toml +58 -0
- machineconfig/settings/shells/vtm/settings.xml +297 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +193 -0
- machineconfig/settings/shells/wt/settings.json +526 -0
- machineconfig/settings/streamlit/config.toml +22 -0
- machineconfig/settings/svim/linux/init.toml +48 -0
- machineconfig/settings/svim/windows/init.toml +48 -0
- machineconfig/settings/tere/terecd.ps1 +8 -0
- machineconfig/settings/tere/terecd.sh +8 -0
- machineconfig/settings/tmux/.tmate.conf +3 -0
- machineconfig/settings/tmux/.tmux.conf +6 -0
- machineconfig/settings/wsl/.wslconfig +35 -0
- machineconfig/settings/yazi/keymap.toml +0 -0
- machineconfig/settings/yazi/theme.toml +0 -0
- machineconfig/settings/yazi/yazi.toml +4 -0
- machineconfig/settings/zed/settings.json +35 -0
- machineconfig/settings/zellij/commands/monitor +9 -0
- machineconfig/settings/zellij/commands/standard_panes +33 -0
- machineconfig/settings/zellij/config.kdl +295 -0
- machineconfig/settings/zellij/config.orig.kdl +295 -0
- machineconfig/settings/zellij/layouts/hist +13 -0
- machineconfig/settings/zellij/layouts/panes.kdl +20 -0
- machineconfig/settings/zellij/layouts/st.kdl +21 -0
- machineconfig/settings/zellij/layouts/st2.kdl +59 -0
- machineconfig/settings/zellij/layouts/stacked_panes.kdl +11 -0
- machineconfig/setup_linux/nix/cli_installation.sh +166 -0
- machineconfig/setup_linux/others/mint_keyboard_shortcuts.sh +30 -0
- machineconfig/setup_linux/others/openssh-server_add_pub_key.sh +60 -0
- machineconfig/setup_linux/web_shortcuts/all.sh +53 -0
- machineconfig/setup_linux/web_shortcuts/ascii_art.sh +100 -0
- machineconfig/setup_linux/web_shortcuts/croshell.sh +66 -0
- machineconfig/setup_linux/web_shortcuts/interactive.sh +241 -0
- machineconfig/setup_linux/web_shortcuts/ssh.sh +64 -0
- machineconfig/setup_linux/web_shortcuts/update_system.sh +55 -0
- machineconfig/setup_windows/others/docker.ps1 +7 -0
- machineconfig/setup_windows/others/obs.ps1 +4 -0
- machineconfig/setup_windows/web_shortcuts/all.ps1 +18 -0
- machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +36 -0
- machineconfig/setup_windows/web_shortcuts/croshell.ps1 +16 -0
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +200 -0
- machineconfig/setup_windows/web_shortcuts/ssh.ps1 +11 -0
- machineconfig/setup_windows/wt_and_pwsh/install_fonts.ps1 +27 -0
- machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +12 -2
- machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +45 -9
- machineconfig/utils/ai/__init__.py +0 -0
- machineconfig/utils/ai/browser_user_wrapper.py +51 -0
- machineconfig/utils/ai/generate_file_checklist.py +74 -0
- machineconfig/utils/ai/url2md.py +75 -0
- machineconfig/utils/installer.py +101 -253
- machineconfig/utils/installer_utils/__init__.py +0 -0
- machineconfig/utils/installer_utils/installer_abc.py +100 -0
- machineconfig/utils/installer_utils/installer_class.py +253 -0
- machineconfig/utils/procs.py +69 -16
- machineconfig/utils/scheduling.py +47 -13
- machineconfig/utils/utils.py +39 -371
- machineconfig/utils/utils_code.py +82 -0
- machineconfig/utils/utils_links.py +88 -0
- machineconfig/utils/utils_options.py +163 -0
- machineconfig/utils/utils_path.py +151 -0
- machineconfig/utils/ve.py +37 -225
- machineconfig/utils/ve_utils/ve1.py +111 -0
- machineconfig/utils/ve_utils/ve2.py +142 -0
- {machineconfig-1.92.dist-info → machineconfig-1.94.dist-info}/METADATA +25 -21
- machineconfig-1.94.dist-info/RECORD +710 -0
- {machineconfig-1.92.dist-info → machineconfig-1.94.dist-info}/WHEEL +1 -1
- machineconfig-1.92.dist-info/LICENSE +0 -201
- machineconfig-1.92.dist-info/RECORD +0 -70
- {machineconfig-1.92.dist-info → machineconfig-1.94.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Distributed Computing
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from typing import Optional, Any, Callable, Union
|
|
7
|
+
from math import ceil, floor
|
|
8
|
+
from enum import Enum
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
import psutil
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
from crocodile.core import randstr, List as L, Struct as S, install_n_import
|
|
14
|
+
from crocodile.file_management import P, Save
|
|
15
|
+
from crocodile.meta import SSH, Terminal
|
|
16
|
+
from machineconfig.cluster.remote_machine import RemoteMachine, RemoteMachineConfig, WorkloadParams, LAUNCH_METHOD
|
|
17
|
+
from rich.console import Console
|
|
18
|
+
# from platform import system
|
|
19
|
+
# import time
|
|
20
|
+
# from rich.progress import track
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
console = Console()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class LoadCriterion(Enum):
|
|
27
|
+
cpu = "cpu"
|
|
28
|
+
ram = "ram"
|
|
29
|
+
product = "cpu * ram"
|
|
30
|
+
cpu_norm = "cpu_norm"
|
|
31
|
+
ram_norm = "ram_norm"
|
|
32
|
+
product_norm = "cpu_norm * ram_norm"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class MachineSpecs:
|
|
37
|
+
cpu: float
|
|
38
|
+
ram: float
|
|
39
|
+
product: float
|
|
40
|
+
cpu_norm: float
|
|
41
|
+
ram_norm: float
|
|
42
|
+
product_norm: float
|
|
43
|
+
@staticmethod
|
|
44
|
+
def get_this_machine_specs():
|
|
45
|
+
cpu, ram = psutil.cpu_count(), psutil.virtual_memory().total / 2 ** 30
|
|
46
|
+
assert cpu is not None
|
|
47
|
+
return MachineSpecs(cpu=cpu, ram=ram, product=cpu * ram, cpu_norm=cpu, ram_norm=ram, product_norm=cpu * ram)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ThreadLoadCalculator:
|
|
51
|
+
"""relies on relative values to a referenc machine specs.
|
|
52
|
+
Runs multiple instances of code per machine. Useful if code doesn't run faster with more resources avaliable.
|
|
53
|
+
equal distribution across instances of one machine"""
|
|
54
|
+
def __init__(self, num_jobs: Optional[int] = None, load_criterion: LoadCriterion = LoadCriterion.cpu, reference_specs: Optional[MachineSpecs] = None):
|
|
55
|
+
self.num_jobs = num_jobs
|
|
56
|
+
self.load_criterion = load_criterion
|
|
57
|
+
self.reference_specs: MachineSpecs = MachineSpecs.get_this_machine_specs() if reference_specs is None else reference_specs
|
|
58
|
+
def __getstate__(self): return self.__dict__
|
|
59
|
+
def __setstate__(self, state: dict[str, Any]): self.__dict__.update(state)
|
|
60
|
+
def get_num_threads(self, machine_specs: MachineSpecs) -> int:
|
|
61
|
+
if self.num_jobs is None: return 1
|
|
62
|
+
res = int(floor(self.num_jobs * (machine_specs.__dict__[self.load_criterion.name] / self.reference_specs.__dict__[self.load_criterion.name])))
|
|
63
|
+
return 1 if res == 0 else res
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class MachineLoadCalculator:
|
|
67
|
+
def __init__(self, max_num: int = 1000, load_criterion: LoadCriterion = LoadCriterion.product, load_ratios_repr: str = ""):
|
|
68
|
+
self.load_ratios: list[float] = []
|
|
69
|
+
self.load_ratios_repr = load_ratios_repr
|
|
70
|
+
self.max_num: int = max_num
|
|
71
|
+
self.load_criterion = load_criterion
|
|
72
|
+
def __getstate__(self) -> dict[str, Any]: return self.__dict__
|
|
73
|
+
def __setstate__(self, d: dict[str, Any]) -> None: self.__dict__.update(d)
|
|
74
|
+
def get_workload_params(self, machines_specs: list[MachineSpecs], threads_per_machine: list[int]) -> list[WorkloadParams]:
|
|
75
|
+
"""Note: like thread divider in parallelize function, the behaviour is to include the edge cases on both ends of subsequent intervals."""
|
|
76
|
+
tmp: list[WorkloadParams] = []
|
|
77
|
+
idx_so_far = 0
|
|
78
|
+
for machine_index, (machine_specs, a_threads_per_machine) in enumerate(zip(machines_specs, threads_per_machine)):
|
|
79
|
+
load_value = machine_specs.__dict__[self.load_criterion.name]
|
|
80
|
+
self.load_ratios.append(load_value)
|
|
81
|
+
idx1 = idx_so_far
|
|
82
|
+
idx2 = self.max_num if machine_index == len(threads_per_machine) - 1 else (floor(load_value * self.max_num) + idx1)
|
|
83
|
+
if idx2 > self.max_num:
|
|
84
|
+
print(machines_specs, '\n\n', threads_per_machine)
|
|
85
|
+
print(f"All values: {tmp=}, {idx_so_far=}, {idx1=}, {idx2=}, {self.max_num=}, {a_threads_per_machine=}, {machine_index=}, {machine_specs=}, {load_value=}, {self.load_ratios=}, {self.load_ratios_repr=}")
|
|
86
|
+
raise ValueError(f"idx2 ({idx2}) > max_num ({self.max_num})")
|
|
87
|
+
idx_so_far = idx2
|
|
88
|
+
tmp.append(WorkloadParams(idx_start=idx1, idx_end=idx2, idx_max=self.max_num, jobs=a_threads_per_machine))
|
|
89
|
+
return tmp
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class Cluster:
|
|
93
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
94
|
+
state = self.__dict__
|
|
95
|
+
state["func"] = None
|
|
96
|
+
return state
|
|
97
|
+
def __setstate__(self, state: dict[str, Any]) -> None: self.__dict__.update(state)
|
|
98
|
+
def save(self) -> P:
|
|
99
|
+
path = self.root_dir.joinpath("cluster.Cluster.pkl")
|
|
100
|
+
Save.pickle(obj=self.__getstate__(), path=path)
|
|
101
|
+
return path
|
|
102
|
+
@staticmethod
|
|
103
|
+
def load(job_id: str, base: Optional[str] = None) -> 'Cluster': return Cluster.get_cluster_path(job_id=job_id, base=base).joinpath("cluster.Cluster.pkl").readit()
|
|
104
|
+
@staticmethod
|
|
105
|
+
def get_cluster_path(job_id: str, base: Union[str, P, None] = None):
|
|
106
|
+
if base is None: base_obj = P.home().joinpath("tmp_results/remote_machines")
|
|
107
|
+
else: base_obj = P(base)
|
|
108
|
+
return base_obj.joinpath(f"job_id__{job_id}")
|
|
109
|
+
def __init__(self,
|
|
110
|
+
func: Callable[..., Any],
|
|
111
|
+
ssh_params: list[dict[str, Any]],
|
|
112
|
+
remote_machine_config: RemoteMachineConfig,
|
|
113
|
+
func_kwargs: Optional[dict[str, Any]] = None,
|
|
114
|
+
# workload_params: list[WorkloadParams] or None = None,
|
|
115
|
+
thread_load_calc: Optional[ThreadLoadCalculator] = None,
|
|
116
|
+
# machine_load_calc=None,
|
|
117
|
+
ditch_unavailable_machines: bool = False,
|
|
118
|
+
description: str = "",
|
|
119
|
+
job_id: Optional[str] = None,
|
|
120
|
+
base_dir: Union[str, P, None] = None):
|
|
121
|
+
self.job_id = job_id or randstr(noun=True)
|
|
122
|
+
self.root_dir = self.get_cluster_path(self.job_id, base=base_dir)
|
|
123
|
+
self.results_downloaded = False
|
|
124
|
+
|
|
125
|
+
self.thread_load_calc: ThreadLoadCalculator = thread_load_calc or ThreadLoadCalculator()
|
|
126
|
+
self.machine_load_calc: MachineLoadCalculator = MachineLoadCalculator(load_criterion=LoadCriterion[self.thread_load_calc.load_criterion.name + "_norm"], )
|
|
127
|
+
|
|
128
|
+
sshz: list[SSH] = []
|
|
129
|
+
for an_ssh_params in ssh_params:
|
|
130
|
+
try:
|
|
131
|
+
tmp = SSH(**an_ssh_params)
|
|
132
|
+
sshz.append(tmp)
|
|
133
|
+
except Exception as ex:
|
|
134
|
+
print(f"Couldn't connect to {an_ssh_params}")
|
|
135
|
+
if ditch_unavailable_machines: continue
|
|
136
|
+
else: raise Exception(f"Couldn't connect to {an_ssh_params}") from ex # type: ignore # pylint: disable=W0719
|
|
137
|
+
|
|
138
|
+
# lists of similar length:
|
|
139
|
+
self.sshz: list[SSH] = sshz
|
|
140
|
+
self.machines: list[RemoteMachine] = []
|
|
141
|
+
self.machines_specs: list[MachineSpecs] = []
|
|
142
|
+
self.threads_per_machine: list[int] = []
|
|
143
|
+
self.remote_machine_kwargs: RemoteMachineConfig = remote_machine_config
|
|
144
|
+
self.workload_params: list[WorkloadParams] = []
|
|
145
|
+
|
|
146
|
+
self.description: str = description
|
|
147
|
+
self.func = func
|
|
148
|
+
self.func_kwargs = func_kwargs if func_kwargs is not None else {}
|
|
149
|
+
|
|
150
|
+
# fire options
|
|
151
|
+
self.machines_per_tab: int = 1
|
|
152
|
+
self.window_number: int = 2
|
|
153
|
+
|
|
154
|
+
def __repr__(self): return "Cluster with following machines:\n" + "\n".join([repr(item) for item in (self.machines if self.machines else self.sshz)])
|
|
155
|
+
def print_func_kwargs(self):
|
|
156
|
+
print("\n" * 2)
|
|
157
|
+
console.rule(title="kwargs of functions to be run on machines")
|
|
158
|
+
for an_ssh, a_kwarg in zip(self.sshz, self.workload_params):
|
|
159
|
+
S(a_kwarg.__dict__).print(as_config=True, title=an_ssh.get_remote_repr())
|
|
160
|
+
def print_commands(self, launch_method: LAUNCH_METHOD):
|
|
161
|
+
print("\n" * 2)
|
|
162
|
+
console.rule(title="Commands to run on each machine:")
|
|
163
|
+
for machine in self.machines:
|
|
164
|
+
print(f"{repr(machine)} ==> {machine.file_manager.get_fire_command(launch_method=launch_method)}")
|
|
165
|
+
|
|
166
|
+
def generate_standard_kwargs(self) -> None:
|
|
167
|
+
if self.workload_params:
|
|
168
|
+
self.print_func_kwargs()
|
|
169
|
+
print(self.workload_params, len(self.workload_params), type(self.workload_params))
|
|
170
|
+
print("workload_params is not None, so not generating standard kwargs")
|
|
171
|
+
return None
|
|
172
|
+
cpus: list[float] = []
|
|
173
|
+
rams: list[float] = []
|
|
174
|
+
for an_ssh in self.sshz:
|
|
175
|
+
res = an_ssh.run_py("import psutil; print(psutil.cpu_count(), psutil.virtual_memory().total)", verbose=False).op
|
|
176
|
+
try: cpus.append(int(res.split(' ')[0]))
|
|
177
|
+
except ValueError as ve:
|
|
178
|
+
print(f"Couldn't get cpu count from {an_ssh}")
|
|
179
|
+
raise ValueError(f"Couldn't get cpu count from {an_ssh.get_remote_repr()}") from ve
|
|
180
|
+
rams.append(ceil(int(res.split(' ')[1]) / 2 ** 30))
|
|
181
|
+
total_cpu = np.array(cpus).sum()
|
|
182
|
+
total_ram = np.array(rams).sum()
|
|
183
|
+
total_product = (np.array(cpus) * np.array(rams)).sum()
|
|
184
|
+
|
|
185
|
+
self.machines_specs = [MachineSpecs(cpu=a_cpu, ram=a_ram, product=a_cpu * a_ram, cpu_norm=a_cpu / total_cpu, ram_norm=a_ram / total_ram, product_norm=a_cpu * a_ram / total_product) for a_cpu, a_ram in zip(cpus, rams)]
|
|
186
|
+
self.threads_per_machine = [self.thread_load_calc.get_num_threads(machine_specs=machine_specs) for machine_specs in self.machines_specs]
|
|
187
|
+
self.workload_params = self.machine_load_calc.get_workload_params(machines_specs=self.machines_specs, threads_per_machine=self.threads_per_machine)
|
|
188
|
+
self.print_func_kwargs()
|
|
189
|
+
|
|
190
|
+
def viz_load_ratios(self) -> None:
|
|
191
|
+
if not self.workload_params: raise RuntimeError("func_kwargs_list is None. You need to run generate_standard_kwargs() first.")
|
|
192
|
+
plt = install_n_import("plotext")
|
|
193
|
+
names = L(self.sshz).apply(lambda x: x.get_remote_repr(add_machine=True)).list
|
|
194
|
+
|
|
195
|
+
plt.simple_multiple_bar(names, [[machine_specs.cpu for machine_specs in self.machines_specs], [machine_specs.ram for machine_specs in self.machines_specs]], title="Resources per machine", labels=["#cpu threads", "memory size"])
|
|
196
|
+
plt.show()
|
|
197
|
+
print("")
|
|
198
|
+
plt.simple_bar(names, self.machine_load_calc.load_ratios, width=100, title=f"Load distribution for machines using criterion `{self.machine_load_calc.load_criterion}`")
|
|
199
|
+
plt.show()
|
|
200
|
+
|
|
201
|
+
tmp = S(dict(zip(names, L((np.array(self.machine_load_calc.load_ratios) * 100).round(1)).apply(lambda x: f"{int(x)}%")))).print(as_config=True, justify=75, return_str=True)
|
|
202
|
+
assert isinstance(tmp, str)
|
|
203
|
+
self.machine_load_calc.load_ratios_repr = tmp
|
|
204
|
+
print(self.machine_load_calc.load_ratios_repr)
|
|
205
|
+
# self.workload_params.
|
|
206
|
+
print("\n")
|
|
207
|
+
|
|
208
|
+
def submit(self) -> None:
|
|
209
|
+
if not self.workload_params: raise RuntimeError("You need to generate standard kwargs first.")
|
|
210
|
+
for idx, (a_workload_params, an_ssh) in enumerate(zip(self.workload_params, self.sshz)):
|
|
211
|
+
desc = self.description + f"\nLoad Ratios on machines:\n{self.machine_load_calc.load_ratios_repr}"
|
|
212
|
+
# if self.remote_machine_kwargs is not None:
|
|
213
|
+
config = self.remote_machine_kwargs
|
|
214
|
+
config.__dict__.update(dict(description=desc, job_id=self.job_id + f"_{idx}", base_dir=self.root_dir, workload_params=a_workload_params, ssh_obj=an_ssh))
|
|
215
|
+
# else: config = RemoteMachineConfig(description=desc, job_id=self.job_id + f"_{idx}", base_dir=self.root_dir.as_posix(), workload_params=a_workload_params, ssh_obj=an_ssh)
|
|
216
|
+
m = RemoteMachine(func=self.func, func_kwargs=self.func_kwargs, config=config)
|
|
217
|
+
m.generate_scripts()
|
|
218
|
+
m.submit()
|
|
219
|
+
self.machines.append(m)
|
|
220
|
+
try: self.save()
|
|
221
|
+
except Exception as re:
|
|
222
|
+
print(re)
|
|
223
|
+
print("Couldn't pickle cluster object")
|
|
224
|
+
# self.print_commands()
|
|
225
|
+
|
|
226
|
+
def open_mux(self, machines_per_tab: int = 1, window_number: Optional[int] = None):
|
|
227
|
+
self.machines_per_tab = machines_per_tab
|
|
228
|
+
self.window_number = window_number if window_number is not None else 0 # randstr(length=3, lower=False, upper=False)
|
|
229
|
+
cmd = f"wt -w {self.window_number} "
|
|
230
|
+
for idx, m in enumerate(self.machines):
|
|
231
|
+
|
|
232
|
+
sub_cmd = m.get_session_manager().get_new_session_ssh_command(ssh=m.ssh, sess_name=m.job_params.session_name)
|
|
233
|
+
if idx == 0: cmd += f""" new-tab --title '{str(m.ssh.hostname) + str(idx)}' pwsh -Command "{sub_cmd}" `;""" # avoid new tabs despite being even index
|
|
234
|
+
elif idx % self.machines_per_tab == 0: cmd += f""" new-tab --title {str(m.ssh.hostname) + str(idx)} pwsh -Command "{sub_cmd}" `;"""
|
|
235
|
+
else: cmd += f""" split-pane --horizontal --size {1 / self.machines_per_tab} pwsh -Command "{sub_cmd}" `;"""
|
|
236
|
+
|
|
237
|
+
print("Terminal launch command:\n", cmd)
|
|
238
|
+
if cmd.endswith("`;"): cmd = cmd[:-2]
|
|
239
|
+
Terminal().run_async(*cmd.replace("`;", ";").split(" ")) # `; only for powershell, cmd is okay for ; as it is not a special character
|
|
240
|
+
rm_last = self.machines[-1]
|
|
241
|
+
rm_last.get_session_manager().asssert_session_started(ssh=rm_last.ssh, sess_name=rm_last.job_params.session_name)
|
|
242
|
+
|
|
243
|
+
def fire(self, machines_per_tab: int = 1, window_number: Optional[int] = None, run: bool = False):
|
|
244
|
+
self.open_mux(machines_per_tab=machines_per_tab, window_number=window_number)
|
|
245
|
+
for m in self.machines:
|
|
246
|
+
m.fire(run=run, open_console=False)
|
|
247
|
+
|
|
248
|
+
def run(self, run: bool = False, machines_per_tab: int = 1, window_number: Optional[int] = None):
|
|
249
|
+
self.generate_standard_kwargs()
|
|
250
|
+
self.viz_load_ratios()
|
|
251
|
+
print(self)
|
|
252
|
+
self.submit()
|
|
253
|
+
self.fire(run=run, machines_per_tab=machines_per_tab, window_number=window_number)
|
|
254
|
+
self.save()
|
|
255
|
+
return self
|
|
256
|
+
|
|
257
|
+
def check_job_status(self) -> None: L(self.machines).apply(lambda machine: machine.check_job_status())
|
|
258
|
+
def download_results(self):
|
|
259
|
+
if self.results_downloaded:
|
|
260
|
+
print(f"All results downloaded to {self.root_dir} 🤗")
|
|
261
|
+
return True
|
|
262
|
+
for idx, a_m in enumerate(self.machines):
|
|
263
|
+
_ = idx
|
|
264
|
+
if a_m.results_path is None:
|
|
265
|
+
print(f"Results are not ready for machine {a_m}.")
|
|
266
|
+
print("Try to run `.check_job_status()` to check if the job is done and obtain results path.")
|
|
267
|
+
continue
|
|
268
|
+
# results_folder = P(a_m.results_path).expanduser()
|
|
269
|
+
if a_m.results_downloaded is False:
|
|
270
|
+
print("\n")
|
|
271
|
+
console.rule(f"Downloading results from {a_m}")
|
|
272
|
+
print("\n")
|
|
273
|
+
a_m.download_results(target=None) # TODO another way of resolve multiple machines issue is to create a directory at downlaod_results time.
|
|
274
|
+
if L(self.machines).results_downloaded.to_numpy().sum() == len(self.machines):
|
|
275
|
+
print(f"All results downloaded to {self.root_dir} 🤗")
|
|
276
|
+
self.results_downloaded = True
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
if __name__ == '__main__':
|
|
280
|
+
pass
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
|
|
2
|
+
from rich import inspect
|
|
3
|
+
from rich.console import Console
|
|
4
|
+
import pandas as pd
|
|
5
|
+
|
|
6
|
+
from crocodile.core import Struct as S, install_n_import
|
|
7
|
+
from crocodile.file_management import P, Save
|
|
8
|
+
from crocodile.meta import MACHINE
|
|
9
|
+
from machineconfig.cluster.loader_runner import JOB_STATUS, LAUNCH_METHOD, JobStatus
|
|
10
|
+
|
|
11
|
+
from typing import Union, Any
|
|
12
|
+
import time
|
|
13
|
+
import os
|
|
14
|
+
import platform
|
|
15
|
+
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class FileManager:
|
|
20
|
+
running_path = P("~/tmp_results/remote_machines/file_manager/running_jobs.pkl")
|
|
21
|
+
queue_path = P("~/tmp_results/remote_machines/file_manager/queued_jobs.pkl")
|
|
22
|
+
history_path = P("~/tmp_results/remote_machines/file_manager/history_jobs.pkl")
|
|
23
|
+
shell_script_path_log = P("~/tmp_results/remote_machines/file_manager/last_cluster_script.txt")
|
|
24
|
+
default_base = P("~/tmp_results/remote_machines/jobs")
|
|
25
|
+
@staticmethod
|
|
26
|
+
def from_pickle(path: Union[str, P]):
|
|
27
|
+
fm = FileManager(job_id='1', remote_machine_type='Windows', lock_resources=True, max_simulataneous_jobs=1, base=None)
|
|
28
|
+
fm.__setstate__(dict(P(path).expanduser().readit()))
|
|
29
|
+
return fm
|
|
30
|
+
def __getstate__(self): return self.__dict__
|
|
31
|
+
def __setstate__(self, state: dict[str, Any]): self.__dict__ = state
|
|
32
|
+
def __init__(self, job_id: str, remote_machine_type: MACHINE, lock_resources: bool, max_simulataneous_jobs: int = 1, base: Union[str, P, None] = None):
|
|
33
|
+
"""Log files to track execution process:
|
|
34
|
+
* A text file that cluster deletes at the begining then write to at the end of each job.
|
|
35
|
+
* pickle of Machine and clusters objects.
|
|
36
|
+
"""
|
|
37
|
+
# EVERYTHING MUST REMAIN IN RELATIVE PATHS
|
|
38
|
+
self.remote_machine_type = remote_machine_type
|
|
39
|
+
self.job_id = job_id
|
|
40
|
+
self.max_simulataneous_jobs = max_simulataneous_jobs
|
|
41
|
+
self.lock_resources = lock_resources
|
|
42
|
+
|
|
43
|
+
self.submission_time = pd.Timestamp.now()
|
|
44
|
+
|
|
45
|
+
self.base_dir = P(base).collapseuser() if bool(base) else FileManager.default_base
|
|
46
|
+
status: JOB_STATUS
|
|
47
|
+
status = 'queued'
|
|
48
|
+
self.job_root = self.base_dir.joinpath(f"{status}/{self.job_id}")
|
|
49
|
+
@property
|
|
50
|
+
def py_script_path(self): return self.job_root.joinpath("python/cluster_wrap.py")
|
|
51
|
+
@property
|
|
52
|
+
def cloud_download_py_script_path(self): return self.job_root.joinpath("python/download_data.py")
|
|
53
|
+
@property
|
|
54
|
+
def shell_script_path(self): return self.job_root.joinpath("shell/cluster_script" + {"Windows": ".ps1", "Linux": ".sh"}[self.remote_machine_type]) # noqa: E501
|
|
55
|
+
@property
|
|
56
|
+
def kwargs_path(self): return self.job_root.joinpath("data/func_kwargs.pkl")
|
|
57
|
+
@property
|
|
58
|
+
def file_manager_path(self): return self.job_root.joinpath("data/file_manager.pkl")
|
|
59
|
+
@property
|
|
60
|
+
def remote_machine_path(self): return self.job_root.joinpath("data/remote_machine.Machine.pkl")
|
|
61
|
+
@property
|
|
62
|
+
def remote_machine_config_path(self): return self.job_root.joinpath("data/remote_machine_config.pkl")
|
|
63
|
+
@property
|
|
64
|
+
def execution_log_dir(self): return self.job_root.joinpath("logs")
|
|
65
|
+
def get_fire_command(self, launch_method: LAUNCH_METHOD):
|
|
66
|
+
_ = launch_method
|
|
67
|
+
script_path = self.shell_script_path.expanduser()
|
|
68
|
+
# if launch_method == "remotely": pass # shell_script is already repared for target machine.
|
|
69
|
+
# else:
|
|
70
|
+
if platform.system() == "Windows" and script_path.name.endswith(".sh"):
|
|
71
|
+
tmp = script_path.with_suffix(".ps1")
|
|
72
|
+
tmp.write_text(script_path.read_text(), encoding="utf-8", newline=None)
|
|
73
|
+
script_path = tmp
|
|
74
|
+
if platform.system() == "Linux" and script_path.name.endswith(".ps1"):
|
|
75
|
+
tmp = script_path.with_suffix(".sh")
|
|
76
|
+
tmp.write_text(script_path.read_text(), encoding="utf-8", newline='\n')
|
|
77
|
+
script_path = tmp
|
|
78
|
+
return f". {script_path}"
|
|
79
|
+
def fire_command_to_clip_memory(self, launch_method: LAUNCH_METHOD):
|
|
80
|
+
print("Execution command copied to clipboard 📋")
|
|
81
|
+
print(self.get_fire_command(launch_method=launch_method)); install_n_import("clipboard").copy(self.get_fire_command(launch_method=launch_method))
|
|
82
|
+
print("\n")
|
|
83
|
+
def get_job_status(self, session_name: str, tab_name: str) -> JOB_STATUS:
|
|
84
|
+
pid_path = self.execution_log_dir.expanduser().joinpath("pid.txt")
|
|
85
|
+
tmp = self.execution_log_dir.expanduser().joinpath("status.txt").read_text()
|
|
86
|
+
status: JOB_STATUS = tmp # type: ignore
|
|
87
|
+
if status == "running":
|
|
88
|
+
if not pid_path.exists():
|
|
89
|
+
print(f"Something wrong happened to job `{self.job_id}`. Its status log file says `{status}`, but pid_path doesn't exists. Moving to failed.")
|
|
90
|
+
status = 'failed'
|
|
91
|
+
self.execution_log_dir.expanduser().joinpath("status.txt").write_text(status)
|
|
92
|
+
return status
|
|
93
|
+
pid: int = int(pid_path.read_text().rstrip())
|
|
94
|
+
import psutil
|
|
95
|
+
try: proc = psutil.Process(pid=pid)
|
|
96
|
+
except psutil.NoSuchProcess:
|
|
97
|
+
print(f"Something wrong happened to job `{self.job_id}`.. Its status log file says `{status}`, but its declared `{pid=}` is dead. Moving to failed.")
|
|
98
|
+
status = 'failed'
|
|
99
|
+
self.execution_log_dir.expanduser().joinpath("status.txt").write_text(status)
|
|
100
|
+
return status
|
|
101
|
+
command = " ".join(proc.cmdline())
|
|
102
|
+
if self.job_id not in command:
|
|
103
|
+
print(f"Something wrong happened to job `{self.job_id}`. Its status log file says `{status}` but the `{pid=}` declared seem to belong to a different process as indicated by the firing command `{command=}`. Moving to failed.")
|
|
104
|
+
status = 'failed'
|
|
105
|
+
self.execution_log_dir.expanduser().joinpath("status.txt").write_text(status)
|
|
106
|
+
return status
|
|
107
|
+
print(f"Job `{self.job_id}` is running with {pid=} & {session_name=} & {tab_name=}.")
|
|
108
|
+
return status
|
|
109
|
+
return status
|
|
110
|
+
|
|
111
|
+
def add_to_queue(self, job_status: JobStatus):
|
|
112
|
+
try:
|
|
113
|
+
queue_file: list[JobStatus] = self.queue_path.expanduser().readit()
|
|
114
|
+
except FileNotFoundError:
|
|
115
|
+
print("Queue file was deleted by the locking job, creating an empty one and saving it.")
|
|
116
|
+
queue_file = []
|
|
117
|
+
Save.pickle(obj=queue_file, path=self.queue_path.expanduser())
|
|
118
|
+
job_ids = [job.job_id for job in queue_file]
|
|
119
|
+
if self.job_id not in job_ids:
|
|
120
|
+
print(f"Adding this job {self.job_id} to the queue and saving it. {len(queue_file)=}")
|
|
121
|
+
queue_file.append(job_status)
|
|
122
|
+
Save.pickle(obj=queue_file, path=self.queue_path.expanduser())
|
|
123
|
+
return queue_file
|
|
124
|
+
|
|
125
|
+
def get_resources_unlocking(self): # this one works at shell level in case python script failed.
|
|
126
|
+
return f"""
|
|
127
|
+
rm {self.running_path.collapseuser().as_posix()}
|
|
128
|
+
echo "Unlocked resources"
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
def secure_resources(self):
|
|
132
|
+
if self.lock_resources is False: return True
|
|
133
|
+
this_job = JobStatus(job_id=self.job_id, pid=os.getpid(), submission_time=self.submission_time, start_time=None, status='locked')
|
|
134
|
+
sleep_time_mins = 10
|
|
135
|
+
lock_status = 'locked'
|
|
136
|
+
while lock_status == 'locked':
|
|
137
|
+
|
|
138
|
+
try: running_file: list[JobStatus] = self.running_path.expanduser().readit()
|
|
139
|
+
except FileNotFoundError:
|
|
140
|
+
print("Running file was deleted by the locking job, making one.")
|
|
141
|
+
running_file = []
|
|
142
|
+
Save.pickle(obj=running_file, path=self.running_path.expanduser())
|
|
143
|
+
|
|
144
|
+
queue_file = self.add_to_queue(job_status=this_job)
|
|
145
|
+
|
|
146
|
+
if len(running_file) < self.max_simulataneous_jobs:
|
|
147
|
+
lock_status = 'unlocked'
|
|
148
|
+
break
|
|
149
|
+
|
|
150
|
+
# --------------- Clearning up queue_file from dead processes -----------------
|
|
151
|
+
import psutil
|
|
152
|
+
next_job_in_queue = queue_file[0] # only consider the first job in the queue
|
|
153
|
+
try: _ = psutil.Process(next_job_in_queue.pid)
|
|
154
|
+
except psutil.NoSuchProcess:
|
|
155
|
+
print(f"Next job in queue {next_job_in_queue} has no associated process, removing it from the queue.")
|
|
156
|
+
queue_file.pop(0)
|
|
157
|
+
Save.pickle(obj=queue_file, path=self.queue_path.expanduser())
|
|
158
|
+
continue
|
|
159
|
+
|
|
160
|
+
# --------------- Clearning up running_file from dead processes -----------------
|
|
161
|
+
found_dead_process = False
|
|
162
|
+
assert len(running_file) > 0, "Running file is empty. This should not happen. There should be a break before this point."
|
|
163
|
+
|
|
164
|
+
for running_job in running_file:
|
|
165
|
+
try: proc = psutil.Process(pid=running_job.pid)
|
|
166
|
+
except psutil.NoSuchProcess:
|
|
167
|
+
print(f"Locking process with pid {running_job.pid} is dead. Ignoring this lock file.")
|
|
168
|
+
S(running_job.__dict__).print(as_config=True, title="Ignored Lock File Details")
|
|
169
|
+
running_file.remove(running_job)
|
|
170
|
+
Save.pickle(obj=running_file, path=self.running_path.expanduser())
|
|
171
|
+
found_dead_process = True
|
|
172
|
+
continue # for for loop
|
|
173
|
+
attrs_txt = ['status', 'memory_percent', 'exe', 'num_ctx_switches',
|
|
174
|
+
'ppid', 'num_threads', 'pid', 'cpu_percent', 'create_time', 'nice',
|
|
175
|
+
'name', 'cpu_affinity', 'cmdline', 'username', 'cwd']
|
|
176
|
+
# if self.remote_machine_type == 'Windows': attrs_txt += ['num_handles']
|
|
177
|
+
# environ, memory_maps, 'io_counters'
|
|
178
|
+
attrs_objs = ['memory_info', 'memory_full_info', 'cpu_times', 'ionice', 'threads', 'open_files', 'connections']
|
|
179
|
+
inspect(S(proc.as_dict(attrs=attrs_objs)), value=False, title=f"Process holding the Lock (pid = {running_job.pid})", docs=False, sort=False)
|
|
180
|
+
inspect(S(proc.as_dict(attrs=attrs_txt)), value=False, title=f"Process holding the Lock (pid = {running_job.pid})", docs=False, sort=False)
|
|
181
|
+
|
|
182
|
+
if found_dead_process: continue # repeat while loop logic.
|
|
183
|
+
running_job = running_file[0] # arbitrary job in the running file.
|
|
184
|
+
assert running_job.start_time is not None, f"Running job {running_job} has no start time. This should not happen."
|
|
185
|
+
|
|
186
|
+
this_specs = {"Submission time": this_job.submission_time, "Time now": pd.Timestamp.now(),
|
|
187
|
+
"Time spent waiting in the queue so far 🛌": pd.Timestamp.now() - this_job.submission_time,
|
|
188
|
+
f"Time consumed by locking job so far (job_id = {running_job.job_id}) so far ⏰": pd.Timestamp.now() - running_job.start_time}
|
|
189
|
+
S(this_specs).print(as_config=True, title=f"This Job `{this_job.job_id}` Details")
|
|
190
|
+
console.rule(title=f"Resources are locked by another job `{running_job.job_id}`. Sleeping for {sleep_time_mins} minutes. 😴", style="bold red", characters="-")
|
|
191
|
+
print("\n")
|
|
192
|
+
time.sleep(sleep_time_mins * 60)
|
|
193
|
+
self.write_lock_file(job_status=this_job)
|
|
194
|
+
console.print(f"Resources are locked by this job `{self.job_id}`. Process pid = {os.getpid()}.", highlight=True)
|
|
195
|
+
|
|
196
|
+
def write_lock_file(self, job_status: JobStatus):
|
|
197
|
+
job_status.start_time = pd.Timestamp.now()
|
|
198
|
+
queue_path = self.queue_path.expanduser()
|
|
199
|
+
try: queue_file: list[JobStatus] = queue_path.readit()
|
|
200
|
+
except FileNotFoundError as fne: raise FileNotFoundError(f"Queue file {queue_path} does not exist. This method should not be called in the first place.") from fne
|
|
201
|
+
|
|
202
|
+
if job_status in queue_file: queue_file.remove(job_status)
|
|
203
|
+
print("Removed current job from waiting queue and added it to the running queue. Saving both files.")
|
|
204
|
+
Save.pickle(obj=queue_file, path=queue_path)
|
|
205
|
+
|
|
206
|
+
running_path = self.running_path.expanduser()
|
|
207
|
+
try: running_file: list[JobStatus] = running_path.readit()
|
|
208
|
+
except FileNotFoundError as fne: raise FileNotFoundError(f"Queue file {running_path} does not exist. This method should not be called in the first place.") from fne
|
|
209
|
+
|
|
210
|
+
assert job_status not in running_file, f"Job status {job_status} is already in the running file. This should not happen."
|
|
211
|
+
assert len(running_file) < self.max_simulataneous_jobs, f"Number of running jobs ({len(running_file)}) is greater than the maximum allowed ({self.max_simulataneous_jobs}). This method should not be called in the first place."
|
|
212
|
+
running_file.append(job_status)
|
|
213
|
+
Save.pickle(obj=running_file, path=running_path)
|
|
214
|
+
|
|
215
|
+
def unlock_resources(self):
|
|
216
|
+
if self.lock_resources is False: return True
|
|
217
|
+
running_file: list[JobStatus] = self.running_path.expanduser().readit()
|
|
218
|
+
for job_status in running_file:
|
|
219
|
+
if job_status.job_id == self.job_id:
|
|
220
|
+
this_job = job_status
|
|
221
|
+
break
|
|
222
|
+
else:
|
|
223
|
+
print(f"Job {self.job_id} is not in the running file. This should not happen. The file is corrupt.")
|
|
224
|
+
this_job = None
|
|
225
|
+
if this_job is not None:
|
|
226
|
+
running_file.remove(this_job)
|
|
227
|
+
console.print(f"Resources have been released by this job `{self.job_id}`. Saving new running file")
|
|
228
|
+
Save.pickle(path=self.running_path.expanduser(), obj=running_file)
|
|
229
|
+
start_time = pd.to_datetime(self.execution_log_dir.expanduser().joinpath("start_time.txt").readit(), utc=False)
|
|
230
|
+
end_time = pd.Timestamp.now()
|
|
231
|
+
item = {"job_id": self.job_id, "start_time": start_time, "end_time": end_time, "submission_time": self.submission_time}
|
|
232
|
+
hist_file = self.history_path.expanduser()
|
|
233
|
+
if hist_file.exists(): hist = hist_file.readit()
|
|
234
|
+
else: hist = []
|
|
235
|
+
hist.append(item)
|
|
236
|
+
print(f"Saved history file to {hist_file} with {len(hist)} items.")
|
|
237
|
+
Save.pickle(obj=hist, path=hist_file)
|
|
238
|
+
# this is further handled by the calling script in case this function failed.
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import git
|
|
5
|
+
from crocodile.file_management import P
|
|
6
|
+
|
|
7
|
+
from typing import Optional, Callable, Union, Any
|
|
8
|
+
from machineconfig.cluster.remote_machine import WorkloadParams
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
import getpass
|
|
11
|
+
import platform
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class JobParams:
|
|
16
|
+
"""What Python script needs to run the job. This will be dynamically injected into the script. Notice that all attrs are either strings or integers."""
|
|
17
|
+
description: str
|
|
18
|
+
ssh_repr: str
|
|
19
|
+
ssh_repr_remote: str
|
|
20
|
+
error_message: str
|
|
21
|
+
session_name: str
|
|
22
|
+
tab_name: str
|
|
23
|
+
file_manager_path: str
|
|
24
|
+
|
|
25
|
+
repo_path_rh: str
|
|
26
|
+
file_path_rh: str
|
|
27
|
+
file_path_r: str
|
|
28
|
+
func_module: str
|
|
29
|
+
func_class: Optional[str] = None # the callable might be a function on its own, not a method of a class.
|
|
30
|
+
func_name: Optional[str] = None # the job might be running a script as is, no particular method.
|
|
31
|
+
|
|
32
|
+
def auto_commit(self):
|
|
33
|
+
from git.repo import Repo
|
|
34
|
+
repo = Repo(P(self.repo_path_rh).expanduser(), search_parent_directories=True)
|
|
35
|
+
# do a commit if the repo is dirty
|
|
36
|
+
if repo.is_dirty():
|
|
37
|
+
repo.git.add(update=True)
|
|
38
|
+
repo.index.commit(f"CloudManager auto commit by {getpass.getuser()}@{platform.node()}")
|
|
39
|
+
print(f"⚠️ Repo {repo.working_dir} was dirty, auto-committed.")
|
|
40
|
+
else: print(f"✅ Repo {repo.working_dir} was clean, no auto-commit.")
|
|
41
|
+
|
|
42
|
+
def is_installabe(self) -> bool: return True if "setup.py" in P(self.repo_path_rh).expanduser().absolute().listdir().apply(str) else False
|
|
43
|
+
@staticmethod
|
|
44
|
+
def from_empty() -> 'JobParams':
|
|
45
|
+
return JobParams(repo_path_rh="", file_path_rh="", file_path_r="", func_module="", func_class="", func_name="", description="", ssh_repr="", ssh_repr_remote="", error_message="", session_name="", tab_name="", file_manager_path="")
|
|
46
|
+
@staticmethod
|
|
47
|
+
def from_func(func: Union[Callable[[Any], Any], P, str]) -> 'JobParams':
|
|
48
|
+
# if callable(self.func): executed_obj = f"""**{self.func.__name__}** from *{P(self.func.__code__.co_filename).collapseuser().as_posix()}*""" # for email.
|
|
49
|
+
if callable(func) and not isinstance(func, P):
|
|
50
|
+
func_name = func.__name__
|
|
51
|
+
func_module = func.__module__
|
|
52
|
+
if func_module == "<run_path>": # function imported through readpy module.
|
|
53
|
+
func_module = P(func.__globals__['__file__']).name
|
|
54
|
+
assert func_module != "__main__", f"Function must be defined in a module, not in __main__. Consider importing `{func.__name__}` or, restart this session and import the contents of this module."
|
|
55
|
+
if func.__name__ != func.__qualname__:
|
|
56
|
+
# print(f"Passed function {func} is a method of a class.")
|
|
57
|
+
func_file, func_class = P(func.__code__.co_filename), func.__qualname__.split(".")[0]
|
|
58
|
+
else:
|
|
59
|
+
# print(f"Passed function {func} is not a method of a class.")
|
|
60
|
+
func_file, func_class = P(func.__code__.co_filename), None
|
|
61
|
+
elif type(func) is str or type(func) is P:
|
|
62
|
+
func_file = P(func)
|
|
63
|
+
# func = None
|
|
64
|
+
func_class = None
|
|
65
|
+
func_name = None
|
|
66
|
+
func_module = func_file.stem
|
|
67
|
+
else: raise TypeError(f"Passed function {func} is not a callable or a path to a python file.")
|
|
68
|
+
try:
|
|
69
|
+
repo_path = P(git.Repo(func_file, search_parent_directories=True).working_dir)
|
|
70
|
+
func_relative_file = func_file.relative_to(repo_path)
|
|
71
|
+
except Exception as e:
|
|
72
|
+
print(e)
|
|
73
|
+
repo_path, func_relative_file = func_file.parent, func_file.name
|
|
74
|
+
return JobParams(repo_path_rh=repo_path.collapseuser().as_posix(), file_path_rh=repo_path.collapseuser().joinpath(func_relative_file).collapseuser().as_posix(),
|
|
75
|
+
file_path_r=P(func_relative_file).as_posix(),
|
|
76
|
+
func_module=func_module, func_class=func_class, func_name=func_name,
|
|
77
|
+
description="", ssh_repr="", ssh_repr_remote="", error_message="",
|
|
78
|
+
session_name="", tab_name="", file_manager_path="")
|
|
79
|
+
|
|
80
|
+
def get_execution_line(self, workload_params: Optional[WorkloadParams], parallelize: bool, wrap_in_try_except: bool) -> str:
|
|
81
|
+
# P(self.repo_path_rh).name}.{self.file_path_r.replace(".py", '').replace('/', '.')#
|
|
82
|
+
# if func_module is not None:
|
|
83
|
+
# # noinspection PyTypeChecker
|
|
84
|
+
# module = __import__(func_module, fromlist=[None])
|
|
85
|
+
# exec_obj = module.__dict__[func_name] if not bool(func_class) else getattr(module.__dict__[func_class], func_name)
|
|
86
|
+
# elif func_name is not None:
|
|
87
|
+
# # This approach is not conducive to parallelization since "mymod" is not pickleable.
|
|
88
|
+
# module = SourceFileLoader("mymod", P.home().joinpath(rel_full_path).as_posix()).load_module() # loading the module assumes its not a script, there should be at least if __name__ == __main__ wrapping any script.
|
|
89
|
+
# exec_obj = getattr(module, func_name) if not bool(func_class) else getattr(getattr(module, func_class), func_name)
|
|
90
|
+
# else:
|
|
91
|
+
# module = P.home().joinpath(rel_full_path).readit() # uses runpy to read .py files.
|
|
92
|
+
# exec_obj = module # for README.md generation.
|
|
93
|
+
|
|
94
|
+
if workload_params is not None: base = f"""
|
|
95
|
+
workload_params = WorkloadParams(**{workload_params.__dict__})
|
|
96
|
+
repo_path = P(rf'{self.repo_path_rh}').expanduser().absolute()
|
|
97
|
+
file_root = P(rf'{self.file_path_rh}').expanduser().absolute().parent
|
|
98
|
+
tb.sys.path.insert(0, repo_path.str)
|
|
99
|
+
tb.sys.path.insert(0, file_root.str)
|
|
100
|
+
"""
|
|
101
|
+
else: base = ""
|
|
102
|
+
|
|
103
|
+
# loading function ===============================================================
|
|
104
|
+
if self.func_name is not None:
|
|
105
|
+
if self.func_class is None: base += f"""
|
|
106
|
+
from {self.func_module.replace('.py', '')} import {self.func_name} as func
|
|
107
|
+
"""
|
|
108
|
+
elif self.func_class is not None: # type: ignore
|
|
109
|
+
base += f"""
|
|
110
|
+
from {self.func_module.replace('.py', '')} import {self.func_class} as {self.func_class}
|
|
111
|
+
func = {self.func_class}.{self.func_name}
|
|
112
|
+
"""
|
|
113
|
+
else: base = f"""
|
|
114
|
+
res = None # in case the file did not define it.
|
|
115
|
+
# --------------------------------- SCRIPT AS IS
|
|
116
|
+
{P(self.file_path_rh).expanduser().read_text()}
|
|
117
|
+
# --------------------------------- END OF SCRIPT AS IS
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
if workload_params is not None and parallelize is False: base += """
|
|
121
|
+
res = func(workload_params=workload_params, **func_kwargs)
|
|
122
|
+
"""
|
|
123
|
+
elif workload_params is not None and parallelize is True: base += f"""
|
|
124
|
+
kwargs_workload = {list(workload_params.split_to_jobs().apply(lambda a_kwargs: a_kwargs.__dict__))}
|
|
125
|
+
workload_params = []
|
|
126
|
+
for idx, x in enumerate(kwargs_workload):
|
|
127
|
+
S(x).print(as_config=True, title=f"Instance {{idx}}")
|
|
128
|
+
workload_params.append(WorkloadParams(**x))
|
|
129
|
+
print("\\n" * 2)
|
|
130
|
+
res = L(workload_params).apply(lambda a_workload_params: func(workload_params=a_workload_params, **func_kwargs), jobs={workload_params.jobs})
|
|
131
|
+
"""
|
|
132
|
+
else: base += """
|
|
133
|
+
res = func(**func_kwargs)
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
if wrap_in_try_except:
|
|
137
|
+
import textwrap
|
|
138
|
+
base = textwrap.indent(base, " " * 4)
|
|
139
|
+
base = f"""
|
|
140
|
+
try:
|
|
141
|
+
{base}
|
|
142
|
+
except Exception as e:
|
|
143
|
+
print(e)
|
|
144
|
+
params.error_message = str(e)
|
|
145
|
+
res = None
|
|
146
|
+
|
|
147
|
+
"""
|
|
148
|
+
return base
|