使用场景
最近工作中遇到一个需求,需要配合AI组实现一个自动化升级工具,实现深度学习模型一键升级(就是一个文件夹,里面若干文件和子文件,用新文件夹替换老文件夹,再重启服务器)。细节如下:
- 客户现场有两台机器,一台windows,一台linux,局域网连接,禁用内网穿透,禁用远程;
- 研发不去客户现场(节省人力成本),现场只有工程服务的同事(完全不懂程序、linux和shell);
- 将升级程序给工程服务的同事,通过U盘传到客户现场windows机器上,一键升级,如果升级失败还能一键恢复;
- 不能做双机信任(做双机信任的话,任何人都可以通过windows上的终端连接linux,不需要输密码,有风险);
- 升级程序中不能有明文表示的服务器账号和密码;
难点
难点在于实现自动化的过程,在终端上完成文件上传,备份,重启服务器是很简单的过程,但是很多操作是需要交互式输入密码的,比如ssh或者使用sudo时都是需要做交互的。
思路
主要操作就两点,第一要把windows上的文件上传到linux上。第二就是在linux上做备份(cp)和重启(reboot)嘛,这部分可以编写几个shell脚本来实现。那么思路就明显了:第一步将目标文件和一些shell上上传到linux上,再依次调用shell完成升级过程。
1.windows上传文件到linux上
使用pscp实现此功能,pscp和scp功能相同,但pscp同时支持windows下使用,它有效解 决了windows系统向linux服务器传输文件,而且它只有一个文件,即pscp.exe,建议将该文件放到C:\WINDOWS\system32 下面,这样就可以在任何地方调用该文件命令。
pscp -r -q -l USER -pw PWD FILES USER@HOST:DIR
2.执行shell
这里还是老老实实ssh进去,再执行shell,那么如何自动填写密码而不是交互式输入密码呢?这里可以用Putty实现。
putty -ssh USER@HOST -pw PWD -m SHELL.txt
SHELL.txt中写入要执行的命令,我们这里就是想执行下已经上传到linux上的shell脚本,所以SHELL.txt就比较简单了。
// 给脚本添加可执行权限
chmod a+x target.sh
// 执行脚本
./target.sh
两个难点解决了,剩下的都是比较简单的逻辑了,通过cp命令进行备份,reboot进行重启,简单的账号密码加密。
简单的例子
这个例子比较简单,只是提供一下思路,自行完善。
1.自动化配置脚本环境
需要用到pscp、putty和SSH,客户现场电脑都没有对应环境,因此需要在开始前把环境配好,这里也是需要自动化实现的。
tool.bat
将putty.exe和pscp.exe拷贝到C:\Windows\System32下,将OpenSSH拷贝到C:\Program Files下,并给ssh配置path环境变量.
cd /d %~dp0
if exist "C:\Windows\System32\putty.exe" (
echo 配置putty >nul
) else (
xcopy /y putty.exe C:\Windows\System32
)
if exist "C:\Windows\System32\pscp.exe" (
echo 配置pscp >nul
) else (
xcopy /y pscp.exe C:\Windows\System32
)
if exist "C:\Program Files\OpenSSH" (
echo 配置SSH >nul
) else (
cd C:\Program Files
mkdir OpenSSH
cd /d %~dp0
xcopy "OpenSSH" "C:\Program Files\OpenSSH" /e /y /q
set path=%path%;C:\Program Files\OpenSSH
)
2.备份原程序
backup.bat
将备份的shell脚本上传到linux上,再执行shell,用户名密码加密这里不贴了。
pscp -r -q -l user -pw "123456" act.sh user@192.168.1.71:/home/fpi
putty -ssh user@192.168.1.71 -pw 123456 -m act.txt
act.txt
chmod a+x /home/fpi/act.sh
cd /home/fpi
./act.sh
act.sh
判断目标程序目录、上传目录、备份目录存不存在,不存在就新建一下,用cp命令复制备份目标程序文件,每次备份都是新增一个备份目录,命名为bp_n,里面会放一个bpinfo文件用于记录备份时间。
target_path="/home/fpi/OCR.P20.S01R.006";
backup_path="/home/fpi/backup";
upload_path="/home/fpi/upload";
if [ ! -d "$target_path" ];then
echo 目标程序目录不存在
exit
fi
if [ ! -d "$upload_path" ];then
mkdir $upload_path
else
rm -rf $upload_path
mkdir $upload_path
fi
if [ ! -d "$backup_path" ];then
mkdir $backup_path
fi
cd $backup_path
backupnum=`ls -l |grep "^d"|wc -l`
mkdir bp_$backupnum
cd bp_$backupnum
time=$(date "+%Y-%m-%d %H:%M:%S")
echo $time > bpinfo.txt
cp -r $target_path ./
3.上传新程序文件到上传目录
upload.bat
pscp -r -q -l user -pw "123456" ../OCR.P20.S01R.006 user@192.168.1.71:/home/fpi/upload
4.替换文件
update.bat
putty -ssh user@192.168.1.71 -pw 123456 -m update.txt
update.txt
cp -rf /home/fpi/upload/OCR.P20.S01R.006 /home/fpi
5.重启服务
reboot.bat
putty -ssh user@192.168.1.71 -pw 123456 -m reboot.txt
reboot.txt
rm -rf /home/fpi/act.sh
reboot
6.恢复
恢复就是把备份目录下最新的文件cp回程序目录就行,记得先做删除操作。
总结
因为不是专业的运维,就是一只弱小的JAVA开发,批处理和shell都不精通,这点功能也用了不少时间。不喜勿喷,有更好的方法请大哥些赐教。