关于配置
最近经常有迁移服务器的需求,但是又嫌弃每次配置比较麻烦,就把配置存在了本地,使用脚本统一配置。
PowerShell Scripting
开始的想法是写 PowerShell Scripting,就了解了一下在编写PowerShell脚本,在PowerShell脚本中,可以使用 *param *声明参数,如下:
param($args1, $args2, $args3=default)
一旦使用这样的方式,所有的参数都必须声明在这参数组里。
但是问题是 Windows 里面没有 ssh-copy-id 这个函数,只能自己定义:
# copyid.ps1
function ssh-copy-id([string]$userAtMachine, $args){
$publicKey = "$ENV:USERPROFILE" + "/.ssh/id_rsa.pub"
if (!(Test-Path "$publicKey")){
Write-Error "ERROR: failed to open ID file '$publicKey': No such file"
}
else {
# Write-Output $userAtMachine
& cat "$publicKey" | ssh $args $userAtMachine -tt "umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys || exit 1"
}
}
ssh-copy-id $args[0]
Python 脚本
服务器文件传输
首先是处理 config 文件以及通过 os.system 将需要的内容传到服务器上
# settmux.py: python settmux.py abbr addr [port]
import sys
import os
from subprocess import call
import paramiko, time
import platform
os.system('cp /mnt/c/Users/China/.ssh/config /root/.ssh/')
print("[INFO]: Moving config in to /root/.ssh/")
# Args processing
username = "name"
args = sys.argv
print(f"[INFO]: Getting {len(args)} args: {args}")
if len(args) == 3:
port = "22"
_, abbr, addr = args
else:
_, abbr, addr, port = args
# Get config file and processing
with open("/root/.ssh/config", 'r') as f:
OCCUPIED = False
context = f.read()
context = context.split("\n")
with open("/root/.ssh/config", 'a') as f:
for line in context:
line = line.split("#")[0].strip()
if line == "":
continue
kind = line.split(" ")[0]
if kind == 'HostName':
config_addr = line.split(" ")[1]
if addr == config_addr:
print("[INFO]: Already have config")
OCCUPIED = True
if not OCCUPIED:
f.write(f"\n\nHost {abbr}\n HostName {addr}\n Port {port}\n User {username}")
# Using platform to check the platform
if platform.system().lower() == 'windows':
os.system(f".\ssh-copy-id {abbr}")
elif platform.system().lower() == 'linux':
os.system(f"ssh-copy-id -i /mnt/c/Users/China/.ssh/id_rsa.pub {abbr}")
# SCP all the needed files
os.system(f"scp -r ./serverconfig/.tmux/ {username}@{abbr}:~/.tmux")
os.system(f"scp ./serverconfig/.bashrc {username}@{abbr}:~/")
os.system(f"scp ./serverconfig/.tmux.conf {username}@{abbr}:~/")
首先处理参数,然后根据 config 文件获得内容,注意,(就目前我的知识水平而言)在打开文件的时候无法同时进入可读之前内容与可添加的模式,虽然存在”a+”的扩展模式,但由于”a”模式下光标将位于文件末尾,因此需要打开两次。
通过在不同平台下的判断将 id_rsa.pub 上传到服务器之后就可以通过 Host 免密登陆了。
服务器文件执行
然后是在本地执行服务器端的配置文件生效的操作。这里我了解到paramiko库,所以使用了一下
import sys
import os
from subprocess import call
import paramiko, time
from collections import defaultdict
# Reading configs
with open("/root/.ssh/config", 'r') as f:
OCCUPIED = False
context = f.read()
context = context.split("\n")
config = defaultdict(dict)
for line in context:
line = line.split("#")[0].strip()
if line == "":
continue
kind = line.split(" ")[0]
if kind == 'Host':
temp_name = line.split(" ")[1]
elif kind == 'Port':
config[temp_name]['port'] = line.split(" ")[1]
elif 'jump' in temp_name:
continue
elif kind == 'HostName':
config[temp_name]['hostname'] = line.split(" ")[1]
elif kind == 'User':
config[temp_name]['user'] = line.split(" ")[1]
else:
print("[INFO]: Not known args")
print(f"[INFO]: CONFIG is")
for conf in config:
print(conf, config[conf])
username = "name"
abbr = sys.argv[1]
addr = config[abbr]['hostname']
port = config[abbr]['port'] if 'port' in config[abbr] else '22'
# Using the private key to log in without a password
pkey='/root/.ssh/id_rsa'
key=paramiko.RSAKey.from_private_key_file(pkey)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(addr, port, username, pkey=key)
# Setting tmux config
stdin, stdout, stderr = ssh.exec_command('tmux new -s Tiberius')
stdin, stdout, stderr = ssh.exec_command('tmux source-file ~/.tmux.conf')
out = stdout.read().decode('utf8')
err = stderr.read().decode('utf8')
result = [out, err]
print(f"[INFO]: result of command {result}")
# Downloading Anaconda
stdin, stdout, stderr = ssh.exec_command('wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.3.1-Linux-x86_64.sh')
out = stdout.read().decode('utf8')
err = stderr.read().decode('utf8')
result = [out, err]
print(f"[INFO]: result of command {result}")
ssh.close()
通过私钥配置免密登录,配置后设置tmux的操作以及下载anaconda,随后只需要scp将环境传输到新的anaconda上即可。