坑爹的部署脚本

我司在开发机器上部署最新版的代码需要用到一些陈年的脚本,经历以下3个步骤:

  1. 执行一个叫 mkview.sh 脚本,脚本运行之后会提示你输入 input 一个URL地址,就是你仓库分支的 gitlab 地址。然后这个脚本会去拉最新的代码分支;
  2. 执行一个叫 build.sh 的脚本,等待 3min;
  3. 执行一个脚 deploy.sh 的脚本,等待5min;

虽然说只有三步,但是太反人类了。首先必须 ssh 登陆执行,然后竟然是命令提示输入这种奇葩形式,而不是直接参数传入。另外这个竟然是传 URL 进去(然后脚本里面奇葩的再把 URL 解析成仓库名字,分支名字)。每次输入之间还要等待几分钟,烦的要死。

操作了几次就受不了了,所以就想办法简化这些步骤。

重写的尝试

首先尝试的是把这三个脚本合成一个,我来打开看看这里面都是什么妖魔鬼怪。结果一打开发现事情并不简单,这都是上千行的脚本(虽然我也不知道里面都写了些啥),然后中间还调用了一些 binary,里面掺杂着各种 xxx 已转岗,xxx 不再维护的注释。看了半天,我连哪里把 git 权限塞进去的都没找到,直接 clone 是不行的,这个脚本就有权限 clone。头大,我还是不去动他了。

上 Ansible

然后我就尝试用 Ansible 处理这三个操作。

处理 prompt

首先要解决的是那个蛋疼的 prompt 问题,毕竟我可不想每次都去拼 URL。搜索了一下,看起来只有这个 expect 模块能够解决终端提示输入的问题。看了一下,不出所料,实现其实是用的 pexpect 包,这个包我最近在开发终端工具 iredis 的时候用了很多。其实这个包坑也蛮多的,比如找不到预期输出的时候只能等待 Timeout。我猜大家都用这个是可能没有更好的选择吧。

因为这是 Ansible 在 remote 机器上的功能,所以需要给机器装上 pexpect。可我司机器 Python 版本是 2.6,没有自带pip……折腾一顿之后,总算是装上了 pexpect。

执行的时候,出现更加蛋疼的编码问题。好吧,看了一下,发现这个脚本把编码写死在脚本里面了。也太反人类了。

放弃这条路了。然后我想这个输入是从键盘输入进去的啊,也就意味着 stdin 输入进去就可以了。试了一下直接用下面这命令就可以:

假设 /bin/script 需要用户输入的话,user_input 就会输入进去。

其实这个问题之前遇到过的,像 apt 这种东西要你确认的Y/n?  可以这样: yes | apt install htop ,yes 会一直输出 y 。当然也可以直接用 -y 选项,正常的脚本都会有这种选项的。

处理 Daemon 进程问题

花了我时间最多的,是一个 deploy.sh 那个操作。很神奇的是,我直接 ssh 跳上去执行,部署成功。

但是放在 Ansible 里面,一模一样的命令,就不行了。

shell command 不同的模块都试过了,换 bash deploy.sh 啥的来执行也试过,都不行。但是直接 ssh 去执行就可以。

Ansible 和 ssh 到底差在哪里呢?

想不出来,去问老师。

老师说:

-_-|| 看了一下,果然是 Ansible 退出的时候会清理一个 session group 的进程

我试了下 Ansible 的 async 功能,好像还是没用,过段时间进程还是被杀掉的。最后直接暴力使用 setsid 重置进程组,父进程直接设置为1,就好了。命令是这么写的:

有关 setsid,nohup 和 disown 的区别,这篇文章写得很好,可以看下。

 

等等,这明明是 deploy.sh 脚本啊,部署的时候不应该把进程 id 啥的都给处理好吗?我都是在经历了些啥啊!

坑爹的部署脚本”已经有7条评论

    • 是有自动化的流程的。但是流程太慢,这是开发机器的环境,比如我更新的代码,想直接部署到开发机器上,这样跑脚本比走平台一步一步来要快一些。部署到生产环境还是走平台的。

Leave a comment

电子邮件地址不会被公开。 必填项已用*标注