├── figs ├── apply.png └── job_log.png ├── sshd ├── vgg.py ├── get_running_host.py ├── sshd_job.sh └── sshd_config ├── README.md ├── .gitignore └── install.sh /figs/apply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Suchun-sv/Slurm_sshd_scripts/HEAD/figs/apply.png -------------------------------------------------------------------------------- /figs/job_log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Suchun-sv/Slurm_sshd_scripts/HEAD/figs/job_log.png -------------------------------------------------------------------------------- /sshd/vgg.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import torch 3 | import torch.nn as nn 4 | import time 5 | import os 6 | os.environ['CUDA_LAUNCH_BLOCKING'] = "1" 7 | 8 | parser = argparse.ArgumentParser(description='GPU Memory Occupation Script') 9 | parser.add_argument('--mem_size', type=int, default=256, help='Size of tensor to allocate memory (will be squared)') 10 | parser.add_argument('--duration', type=int, default=24, help='Duration to run the program, in hours') 11 | args = parser.parse_args() 12 | 13 | device = torch.device('cuda') 14 | 15 | class SmallModel(nn.Module): 16 | def __init__(self): 17 | super(SmallModel, self).__init__() 18 | self.linear = nn.Linear(args.mem_size, args.mem_size) 19 | 20 | def forward(self, x): 21 | return self.linear(x) 22 | 23 | model = SmallModel().to(device) 24 | 25 | input_data = torch.randn(args.mem_size, args.mem_size).to(device) 26 | 27 | model.train() 28 | 29 | optimizer = torch.optim.SGD(model.parameters(), lr=0.01) 30 | 31 | end_time = time.time() + args.duration * 3600 # 转换小时为秒 32 | print(f'Running with memory size: {args.mem_size}x{args.mem_size}, duration: {args.duration} hours') 33 | 34 | while time.time() < end_time: 35 | output = model(input_data) 36 | 37 | loss = output.sum() 38 | 39 | optimizer.zero_grad() 40 | loss.backward() 41 | optimizer.step() 42 | time.sleep(0.1) 43 | 44 | 45 | print('Finished running.') 46 | -------------------------------------------------------------------------------- /sshd/get_running_host.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | from posixpath import expanduser 4 | 5 | os.system("squeue -u $USER | grep apply_ | awk '{print $1}' > ${HOME}/sshd/running_job") 6 | 7 | with open(os.path.expanduser("~")+'/sshd/running_job', 'r') as f: 8 | running_job = f.readlines() 9 | 10 | with open(os.path.expanduser("~")+'/sshd/gpu_ports.conf', 'r') as f: 11 | configs = f.readlines() 12 | 13 | if len(running_job) == 0: 14 | print("no running hosts, exit..") 15 | elif len(configs) == 0: 16 | print("no configs, exit...") 17 | else: 18 | running_hosts = [] 19 | for config in configs: 20 | config = config.strip() 21 | for job in running_job: 22 | job = job.strip() 23 | if job in config: 24 | _, user, host, port = config.split(" ") 25 | running_hosts.append({"host": host, "user": user, "port": port}) 26 | print(f"there are {len(running_hosts)} jobs running, congratulate...") 27 | 28 | 29 | with open(os.path.expanduser("~")+"/sshd/gpu_ssh.conf", "w") as f: 30 | for i, host_config in enumerate(running_hosts): 31 | config_str = f"Host slurm_gpu_{i}" + "\n" + \ 32 | "\t" + f"HostName {host_config['host']}" + "\n" + \ 33 | "\t" + f"User {host_config['user']}" + "\n" + \ 34 | "\t" + f"Port {host_config['port']}" + "\n" + \ 35 | "\t" + "IdentityFile ~/.ssh/id_rsa" + "\n" 36 | f.write(config_str) 37 | print("saved to ~/sshd/gpu_ssh.conf, try connect by you own.") 38 | 39 | with open(os.path.expanduser("~")+"/sshd/running_ports.conf", "w") as f: 40 | for i, host_config in enumerate(running_hosts): 41 | f.write(f"export user={host_config['user']} && export host={host_config['host']} && export port={host_config['port']}\n") 42 | print("saved to ~/sshd/running_ports.conf") 43 | 44 | 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Slurm_sshd_scripts 2 | sshd scripts for slurm 3 | 4 | # Function 5 | This repository is used to apply for the GPU and start a sshd service to connect to the GPU. 6 | 7 | You can DIRECTLY use the `ssh` to connect to the GPU without any other operations. 8 | 9 | you can use the sshd service to connect to the GPU in the following situations: 10 | 1. Debugging in the vscode 11 | 2. Check the GPU status in the terminal 12 | 3. Run the code in the terminal 13 | 14 | # Usage 15 | 1. logging into the slurm sontrol node and `sbatch sshd_jobs.sh` 16 | ![apply](./figs/apply.png) 17 | 2. view the job log and get the ip & port 18 | ![job_log](./figs/job_log.png) 19 | 3. connecting to the computing node with the standard SSH 20 | 21 | 22 | 23 | # Install 24 | ## login to the cluster control node 25 | 26 | ## clone the repository 27 | ```bash 28 | git clone XX XX 29 | cd Slurm_sshd_scripts 30 | ``` 31 | 32 | ## Automatic installation 33 | ``` 34 | source ./install.sh 35 | ``` 36 | 37 | ## Manual installation 38 | 39 | ### generate the ssh key (must in the control code e.g. dell-mgt-01) 40 | ```bash 41 | ssh-keygen -t rsa -f ~/.ssh/vcg_cluster_user_sshd 42 | ``` 43 | 44 | ### modify the important things 45 | 1. in the `sshd/sshd_job.sh` file, you should modify the YOUR_ENVIRONMENT to your own environment. (you can use the following command to do this) 46 | ```bash 47 | export ENV="YOUR_OWN_ENVIRONMENT" # change this to your own environment 48 | cp ./sshd/sshd_job.sh ./sshd/sshd_job.sh.bak 49 | sed "s/YOUR_OWN_ENVIRONMENT/$ENV/g" ./sshd/sshd_job.sh.bak > ./sshd/sshd_job.sh 50 | ``` 51 | 2. in the `sshd/sshd_job.sh` file, you should change the `YOUR_PYTHON` to your own python path. (you can use the following command to do this) 52 | ```bash 53 | YOUR_PYTHON=$(export PYTHONNOUSERSITE=1 && conda activate $ENV && which python) 54 | cp ./sshd/sshd_job.sh ./sshd/sshd_job.sh.bak 55 | sed "s|YOUR_PYTHON=python|YOUR_PYTHON=$YOUR_PYTHON|g" ./sshd/sshd_job.sh.bak > ./sshd/sshd_job.sh 56 | ``` 57 | 3. in the `sshd/sshd_config` file, you should modify the YOUR_USER_NAME to your own user name. (you can use the following command to do this) 58 | ```bash 59 | cp ./sshd/sshd_config ./sshd/sshd_config.bak 60 | sed "s/YOUR_USER_NAME/$USER/g" ./sshd/sshd_config.bak > ./sshd/sshd_config 61 | ``` 62 | 63 | ### move to your home directory 64 | ```bash 65 | # mv sshd/ ~/ 66 | ln -s $(pwd)/sshd/ ~/ 67 | ``` 68 | 69 | ## apply for the GPU 70 | ``` 71 | sbatch ~/sshd/sshd_job.sh 72 | ``` 73 | 74 | ## check the ip_port of the sshd service 75 | ``` 76 | squeue -u $USER | grep apply_gpu 77 | cat Slurm-XXX.out 78 | ``` 79 | 80 | 81 | IMPORTANT: This script preserves ONE GPU for 24 hours by default 82 | 83 | If you have any questions, please feel free to contact me. 84 | 85 | If you find this repository useful, please give me a star, thank you very much! 86 | 87 | -------------------------------------------------------------------------------- /sshd/sshd_job.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #SBATCH --job-name=apply_gpu 4 | 5 | #SBATCH --gres gpu:1 6 | 7 | #PORT=$(python -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()') 8 | 9 | # echo following line 10 | echo "This file is a helper script for the sshd service. It is used to start the sshd service in a Slurm job. " 11 | echo "The script is executed by the Slurm job scheduler and is not intended to be run manually. " 12 | echo "The script starts the sshd service and sets the port number to a random value between 8000 and 8100. " 13 | echo "The script also prints the port number to the console so that the user can connect to the sshd service." 14 | 15 | echo "Copyright (C) 2024 Beining Yang" 16 | 17 | echo "Please do not occupy the GPU for a long time, and release the GPU as soon as possible after use!!!" 18 | echo "Please do not occupy the GPU for a long time, and release the GPU as soon as possible after use!!!" 19 | echo "Please do not occupy the GPU for a long time, and release the GPU as soon as possible after use!!!" 20 | 21 | YOUR_ENVIRONMENT=YOUR_OWN_ENVIRONMENT # your conda environment name which includes torch 22 | YOUR_PYTHON=python 23 | 24 | START_PORT=8000 25 | END_PORT=8100 26 | 27 | find_free_port() { 28 | for port in $(seq $START_PORT $END_PORT); do 29 | if ! ss -tuln | grep -q ":$port "; then 30 | echo $port 31 | break 32 | fi 33 | done 34 | } 35 | 36 | PORT=$(find_free_port) 37 | echo "Get Port:" $PORT 38 | 39 | host=$(ip a | grep 'inet 192.168' | awk '{print $2}' | cut -d'/' -f1 | grep -v '^$') 40 | 41 | echo "********************************************************************" 42 | echo "Starting sshd in Slurm as user" 43 | echo "Environment information:" 44 | echo "Date:" $(date) 45 | echo "Allocated node:" $(hostname) 46 | echo "Node IP:" $(ip a | grep 192.168) 47 | echo "Path:" $(pwd) 48 | echo "Listening on:" $PORT 49 | echo "********************************************************************" 50 | 51 | # source /home/LAB/anaconda3/etc/profile.d/conda.sh 52 | # export PYTHONNOUSERSITE=1 53 | # source ~/.bashrc 54 | # conda activate $YOUR_ENVIRONMENT 55 | cd ${HOME}/sshd/ 56 | 57 | 58 | echo "Starting sshd for you...." 59 | 60 | 61 | echo "********************************************************************" 62 | echo "Copy the following command to connect to the sshd service:" 63 | echo "\n\n" 64 | echo "ssh $USER@$host -p $PORT" 65 | echo "********************************************************************" 66 | 67 | echo "Host slurm_gpu 68 | HostName $host 69 | User $USER 70 | Port $PORT 71 | IdentityFile ~/.ssh/id_rsa" >> ~/sshd/gpu_ssh.conf 72 | 73 | /usr/sbin/sshd -D -p ${PORT} -f ${HOME}/sshd/sshd_config -h ${HOME}/.ssh/vcg_cluster_user_sshd & 74 | 75 | if [[ -n "$SLURM_JOBID" ]]; then 76 | echo "This script is running under sbatch." 77 | echo "This script preserves ONE GPU for 24 hours by default" 78 | echo "$SLURM_JOBID $USER $host $PORT" >> ~/sshd/gpu_ports.conf 79 | $YOUR_PYTHON vgg.py --mem_size 5000 80 | else 81 | echo "You are running in your bash." 82 | fi 83 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | -------------------------------------------------------------------------------- /sshd/sshd_config: -------------------------------------------------------------------------------- 1 | 2 | # This is the sshd server system-wide configuration file. See 3 | # sshd_config(5) for more information. 4 | 5 | # This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games 6 | 7 | # The strategy used for options in the default sshd_config shipped with 8 | # OpenSSH is to specify options with their default value where 9 | # possible, but leave them commented. Uncommented options override the 10 | # default value. 11 | 12 | # Include /etc/ssh/sshd_config.d/*.conf 13 | 14 | #Port 22 15 | #AddressFamily any 16 | #ListenAddress 0.0.0.0 17 | #ListenAddress :: 18 | 19 | #HostKey /etc/ssh/ssh_host_rsa_key 20 | #HostKey /etc/ssh/ssh_host_ecdsa_key 21 | #HostKey /etc/ssh/ssh_host_ed25519_key 22 | 23 | # Ciphers and keying 24 | #RekeyLimit default none 25 | 26 | # Logging 27 | #SyslogFacility AUTH 28 | #LogLevel INFO 29 | 30 | # Authentication: 31 | 32 | #LoginGraceTime 2m 33 | #PermitRootLogin prohibit-password 34 | #StrictModes yes 35 | #MaxAuthTries 6 36 | #MaxSessions 10 37 | 38 | #PubkeyAuthentication yes 39 | 40 | # Expect .ssh/authorized_keys2 to be disregarded by default in future. 41 | #AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 42 | 43 | #AuthorizedPrincipalsFile none 44 | 45 | #AuthorizedKeysCommand none 46 | #AuthorizedKeysCommandUser nobody 47 | 48 | # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts 49 | #HostbasedAuthentication no 50 | # Change to yes if you don't trust ~/.ssh/known_hosts for 51 | # HostbasedAuthentication 52 | #IgnoreUserKnownHosts no 53 | # Don't read the user's ~/.rhosts and ~/.shosts files 54 | #IgnoreRhosts yes 55 | 56 | # To disable tunneled clear text passwords, change to no here! 57 | #PasswordAuthentication yes 58 | #PermitEmptyPasswords no 59 | 60 | # Change to yes to enable challenge-response passwords (beware issues with 61 | # some PAM modules and threads) 62 | KbdInteractiveAuthentication no 63 | 64 | # Kerberos options 65 | #KerberosAuthentication no 66 | #KerberosOrLocalPasswd yes 67 | #KerberosTicketCleanup yes 68 | #KerberosGetAFSToken no 69 | 70 | # GSSAPI options 71 | #GSSAPIAuthentication no 72 | #GSSAPICleanupCredentials yes 73 | #GSSAPIStrictAcceptorCheck yes 74 | #GSSAPIKeyExchange no 75 | 76 | # Set this to 'yes' to enable PAM authentication, account processing, 77 | # and session processing. If this is enabled, PAM authentication will 78 | # be allowed through the KbdInteractiveAuthentication and 79 | # PasswordAuthentication. Depending on your PAM configuration, 80 | # PAM authentication via KbdInteractiveAuthentication may bypass 81 | # the setting of "PermitRootLogin without-password". 82 | # If you just want the PAM account and session checks to run without 83 | # PAM authentication, then enable this but set PasswordAuthentication 84 | # and KbdInteractiveAuthentication to 'no'. 85 | UsePAM yes 86 | 87 | #AllowAgentForwarding yes 88 | #AllowTcpForwarding yes 89 | #GatewayPorts no 90 | X11Forwarding yes 91 | #X11DisplayOffset 10 92 | #X11UseLocalhost yes 93 | #PermitTTY yes 94 | PrintMotd no 95 | #PrintLastLog yes 96 | #TCPKeepAlive yes 97 | #PermitUserEnvironment no 98 | #Compression delayed 99 | #ClientAliveInterval 0 100 | #ClientAliveCountMax 3 101 | #UseDNS no 102 | #PidFile /run/sshd.pid 103 | #MaxStartups 10:30:100 104 | #PermitTunnel no 105 | #ChrootDirectory none 106 | #VersionAddendum none 107 | 108 | # no default banner path 109 | #Banner none 110 | 111 | # Allow client to pass locale environment variables 112 | AcceptEnv LANG LC_* 113 | 114 | # override default of no subsystems 115 | Subsystem sftp /usr/lib/openssh/sftp-server 116 | 117 | # Example of overriding settings on a per-user basis 118 | #Match User anoncvs 119 | # X11Forwarding no 120 | # AllowTcpForwarding no 121 | # PermitTTY no 122 | # ForceCommand cvs server 123 | 124 | # Add your own user name 125 | AllowUsers root YOUR_USER_NAME -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Function to ask the user for the environment name and confirm it 3 | confirm_environment() { 4 | local env_name 5 | 6 | # Ask the user for the environment name without a new line 7 | echo -n "Please enter the name of your environment (include torch): " 8 | read env_name 9 | 10 | # Ask the user to confirm the environment name 11 | echo -n "Please confirm the environment name 【$env_name】[y/n]: " 12 | read confirm 13 | 14 | # Check the user's confirmation 15 | if [[ $confirm == [yY]* ]]; then 16 | echo # Print a new line 17 | echo "The environment name 【$env_name】 is confirmed." 18 | export ENV=$env_name 19 | else 20 | echo # Print a new line 21 | echo "Environment name confirmation failed." 22 | confirm_environment # Ask again 23 | fi 24 | } 25 | 26 | # Call the function to confirm the environment name 27 | confirm_environment 28 | 29 | 30 | 31 | # Check if the ENV variable is set and print the result 32 | if [[ -v ENV ]]; then 33 | echo "The environment name you entered is: $ENV" 34 | YOUR_PYTHON=$(export PYTHONNOUSERSITE=1 && conda activate $ENV && which python) 35 | # 如果为空,报错并退出 36 | if [ -z "$YOUR_PYTHON" ]; then 37 | echo "The python path is not found. Please check the environment name." 38 | exit 1 39 | else 40 | echo "The python path is changed to: $YOUR_PYTHON" 41 | fi 42 | else 43 | echo "Environment name was not confirmed." 44 | fi 45 | 46 | cp ./sshd/sshd_job.sh ./sshd/sshd_job.sh.bak 47 | sed "s/YOUR_OWN_ENVIRONMENT/$ENV/g" ./sshd/sshd_job.sh.bak > ./sshd/sshd_job.sh 48 | 49 | cp ./sshd/sshd_job.sh ./sshd/sshd_job.sh.bak 50 | sed "s|YOUR_PYTHON=python|YOUR_PYTHON=$YOUR_PYTHON|g" ./sshd/sshd_job.sh.bak > ./sshd/sshd_job.sh 51 | 52 | cp ./sshd/sshd_config ./sshd/sshd_config.bak 53 | sed "s/YOUR_USER_NAME/$USER/g" ./sshd/sshd_config.bak > ./sshd/sshd_config 54 | 55 | # check if ./ssh/vcg_cluster_user_sshd exists 56 | if [ ! -f ~/.ssh/vcg_cluster_user_sshd ]; then 57 | echo "Generating ssh key for vcg_cluster_user_sshd" 58 | ssh-keygen -t rsa -f ~/.ssh/vcg_cluster_user_sshd 59 | fi 60 | 61 | if [ ! -d ~/sshd ]; then 62 | ln -s $(pwd)/sshd ~/sshd 63 | else 64 | echo -n "The sshd directory already exists. Do you want to reset the settings? [y/n]" 65 | read confirm 66 | if [[ $confirm == [yY]* ]]; then 67 | rm -r ~/sshd 68 | ln -s $(pwd)/sshd ~/sshd 69 | fi 70 | fi 71 | 72 | alias_to_add="alias apply_gpu='sbatch ~/sshd/sshd_job.sh'" 73 | 74 | bashrc_file=~/.bashrc 75 | 76 | if ! grep -qF "$alias_to_add" "$bashrc_file"; then 77 | echo "$alias_to_add" >> "$bashrc_file" 78 | echo "Alias added to ~/.bashrc." 79 | else 80 | echo "Alias already exists in ~/.bashrc." 81 | fi 82 | 83 | alias_to_add="alias get_host='python ~/sshd/get_running_host.py'" 84 | 85 | bashrc_file=~/.bashrc 86 | 87 | if ! grep -qF "$alias_to_add" "$bashrc_file"; then 88 | echo "$alias_to_add" >> "$bashrc_file" 89 | echo "Alias added to ~/.bashrc." 90 | else 91 | echo "Alias already exists in ~/.bashrc." 92 | fi 93 | 94 | include_config="Include ${HOME}/sshd/gpu_ssh.conf" 95 | ssh_config_file=~/.ssh/config 96 | echo -n "Do you want to include the configuration in your ~/.ssh/config file? [y/n]" 97 | read confirm 98 | if [[ $confirm == [yY]* ]]; then 99 | if ! grep -qF "$include_config" "$ssh_config_file"; then 100 | cp ~/.ssh/config ~/.ssh/config.slurm.bak 101 | touch ~/.ssh/tmp 102 | echo "$include_config" >> ~/.ssh/tmp 103 | cat ~/.ssh/config.slurm.bak >> ~/.ssh/tmp 104 | mv ~/.ssh/tmp ~/.ssh/config.slurm.bak 105 | echo "Now you can check the configuration in ~/.ssh/config.slurm.bak. and rename it to ~/.ssh/config." 106 | echo "" 107 | echo "" 108 | echo "if you think everything is fine, you can run the following command:" 109 | echo "cp ~/.ssh/config.slurm.bak ~/.ssh/config" 110 | else 111 | echo "Configuration already exists in ~/.ssh/config." 112 | fi 113 | fi 114 | 115 | echo "The sshd script is all set up. You can now run the following command to apply for the sshd service:" 116 | echo "====================================================================================================" 117 | echo "sbatch ~/sshd/sshd_job.sh" 118 | echo "or you can use the alias: apply_gpu" 119 | echo "====================================================================================================" 120 | 121 | 122 | echo "You can reset the settings by re-running this script." --------------------------------------------------------------------------------