- Published on
解决 GitHub Action Runner 自动更新失败
- Authors
- Name
半个月前为了能自动 release 毕设论文,在服务器上装了 texlive 2020 和 GitHub Action Runner,并且写了个 service 文件跑了起来,今天 push 了一个新 tag 到 GitHub 上却收到邮件通知 “Run Failed”。
去 runner 的安装目录下发现它自动更新到了 2.262.1,而且目录下多了几个文件夹 bin.2.262.1/ 和 externals.2.262.1/,看日志发现上次服务退出之前报错了无数行
run.sh[647]: /etc/github-actions-runner/_work/_update.sh: line 31: nul: Permission denied
尝试重启服务也失败,日志说找不到 /etc/github-actions-runner/bin/Runner.Listener,再看发现目录下并没有 bin/,于是把 bin.2.262.1/ 软链到了 bin/,这下服务启动成功了,去 GitHub 运行 workflow 还是不行,回来又把 externals.2.262.1/ 也软链到了 externals/,再重启服务就能正常工作了。
是能用了,然而之前为什么会报错呢,整理好别的事情之后又回到服务器上看了一下这个 _update.sh 的内容,报错的那行的内容是
ping -c 2 127.0.0.1 >nul
但是整个文件夹和下面的所有文件都已经被 chown 到服务的运行用户 gh-action 了,没道理会没权限。自己用用户 gh-action 跑了一下 _update.sh,也是正常地运行起了 runner。由于这个 _update.sh 是实时被生成的,于是写了个监控脚本只要发现 _update.sh 被创建就把里面的 nul 改成绝对路径,然而再运行还是报 Permission denied。
之后搜索到了 GitHub 官方关于自行创建服务的文档,文档里说需要用 RunnerRoot 下的 svc.sh 来管理服务,如果要自行创建 systemd 文件则需要按照这个模板来创建。看了一下模板文件,和自己写的文件区别在于 ExecStart 的文件不是 run.sh 而是 runsvc.sh,以及增加了 WorkingDirectory KillMode 和 TimeoutStopSec。
解决
拿各种组合分别跑了一下,得出结论是
Permission denied是因为没有设置工作目录,添加
WorkingDirectory=${RunnerRoot}
可以解决。
- 服务退出是由于 GitHub Action Runner 自动更新之后还要自动重启,默认的
KillMode是control-group,会把所有的进程都关掉。加上
KillMode=process
KillSignal=SIGTERM
可以解决,代表只关闭主进程而不关闭子进程,这样才能正常执行 scheduled restart。
sshd 也是用的这种
KillMode,是为了防止用 ssh 连到服务器上执行systemctl restart sshd时把当前连接也关闭。 [ ref ]
都加上之后就能正常运行服务了,但是去看状态显示的是
failed,然而 workflow 都在正常地跑着。怀疑是因为ExecStart用的是run.sh而不是模板里的runsvc.sh。到 RunnerRoot 下也没找到这个文件,看到svc.sh里是从${RunnerRoot}/bin/下面复制出来的,于是试着跑了./svc.sh install gh-action后,runsvc.sh就出现了。看了一下生成的服务文件内容也很简单,和模板几乎完全一样。跑这个服务时就不会再出现之前的问题了,看状态也显示的是正常的active (running)。还有一个区别在于
TimeoutStopSec,模板里面用的是5min,不写的话默认值是90s,毕竟是停止超时时长,这项并不是前面问题的关键,所以直接用模板里的5min了。
最后把自己的服务文件删了,以后再有自己跑 GitHub Actions 的需求就用 svc.sh 安装服务吧,也不用麻烦自己去写了。