拦截 Docker 容器上的 GitHub 工作流取消

问题描述 投票:0回答:1

我正在使用工作流程在 GitHub Actions 上运行测试,该工作流程使用我创建的 自定义 Docker 映像

取消工作流程时,GitHub 根据文档杀死 docker 容器

有没有办法拦截容器的“kill”,以便我可以在终止容器之前在容器中运行一些拆卸命令?

docker containers github-actions workflow
1个回答
0
投票

至少可以通过使用自定义入口点脚本定义自定义操作来实现。

虽然您无法在默认容器化操作中使用

--entrypoint
(如此处所述),但您可以创建自己的操作并定义一个入口点脚本,您可以在其中捕获发送到容器的 SIGINT GitHub:

对于需要取消的步骤,运行器机器将 SIGINT/Ctrl-C 发送到步骤的入口进程(用于容器操作的 docker)。如果进程在 7500 毫秒内没有退出,运行程序将向进程发送 SIGTERM/Ctrl-Break,然后等待 2500 毫秒让进程退出。如果进程仍在运行,则运行程序会杀死进程树。

自定义操作

这是我的存储库中的自定义操作的示例。我有以下结构:

repository
├── .github
│   ├── actions
│   │   └── test-teri
│   │       ├── Dockerfile
│   │       ├── action.yml
│   │       └── entrypoint.sh
│   └── workflows
│       └── cd_workflow.yml

Dockerfile 只是 GH 操作文档的副本。

FROM alpine:3.10

COPY entrypoint.sh /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

在entrypoint.sh中我有这个过程的要点:

#!/bin/sh -l

trap cleanup SIGINT

cleanup() {
    sleep 2
    echo "Cleanup successful."
    exit
}

while true
do
    echo "Testing..."
    sleep 1
done

我将

SIGINT
信号捕获在入口点内,并在发生这种情况时调用清理函数。该脚本通常只是无限地打印
Testing...
到输出,但您可以定义入口点,使其根据工作流程中的
run:
指令或您想要的方式调用其他内容。我不会详细说明这一点。

记得给入口点脚本赋予执行权限,否则无法运行。

最后是我的 action.yml,您可以在其中定义用于运行此操作的 Dockerfile。

# action.yml
name: 'Hello World'
description: 'Test sigint'
runs:
  using: 'docker'
  image: 'Dockerfile'

运行工作流程

然后,您只需在工作流程中使用此自定义操作即可。

name: Test

on:
  push:
    branches:
      - so-test # <- Whatever branch you are using

jobs:
  build:
    name: "SO test build"
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Test action with sigint
        uses: ./.github/actions/test-teri

测试信号

现在,当我运行工作流程并在一段时间后取消它时,可以在日志中看到以下内容:

Testing...
Testing...
Testing...
Testing...
Testing...
Testing...
Testing...
Cleanup successful.
Error: The operation was canceled.

您注意到清理功能已被执行。但请注意,运行的时间限制是 7500 毫秒,因此它需要在这段时间内成功。我不知道您是否可以在 GH 操作中以任何方式自定义该时间。

© www.soinside.com 2019 - 2024. All rights reserved.