Skip to content

docker actions never complete in kubernetes mode if hooktemplate has a sidecar #183

@oradwell

Description

@oradwell

It is a known limitation that Actions that point to Dockerfile don't work in Kubernetes mode.

Actions that use docker (container image from a registry) work fine in Kubernetes mode, except when a long-running sidecar container is defined in a hooktemplate as documented in the examples.

Internally runner-container-hooks create a Kubernetes Job object to manage docker actions, so until all the containers complete, the job is not completed. The step that uses the docker action never finishes because the sidecar never completes.

A solution to this is to use the sidecar containers feature released in Kubernetes 1.29. The sidecar containers feature terminates the init containers defined with restartPolicy=Always once the main containers complete. This method does not work because the restartPolicy field was introduced in Kubernetes 1.29, available in @kubernetes/client-node 0.21.0, but the we're using 0.18.1.

When I try to set restartPolicy=Always, I get the following error:

Error: failed to create job pod: Pod "test-tc2xb-runner-9dr5m-workflow" is invalid:
[spec.initContainers[0].livenessProbe: Forbidden: may not be set for init containers without restartPolicy=Always,
spec.initContainers[0].readinessProbe: Forbidden: may not be set for init containers without restartPolicy=Always]

The library seems to be stripping any unsupported attributes. I've confirmed this solution by upgrading kubernetes/client-node to 0.22.0 and testing it. The job completed successfully without any problems.

hooktemplate:

spec:
  containers:
    - name: "$job"
    - name: sidecar
      image: busybox:1.37.0
      command:
        - sleep
        - "3600"

hooktemplate utilising k8s 1.29 sidecar containers (not working without kubernetes/client-node > 0.21.0):

    spec:
      initContainers:
        - name: sidecar
          image: busybox:1.37.0
          restartPolicy: Always
          command:
            - sleep
            - "3600"
      containers:
        - name: "$job"
Reproduction details

Sample Docker action:

name: 'yq - portable yaml processor'
description: 'create, read, update, delete, merge, validate and do more with yaml'
inputs:
  cmd:
    description: 'The Command which should be run'
    required: true
outputs:
  result:
    description: "The complete result from the yq command being run"
runs:
  using: 'docker'
  image: 'docker://mikefarah/yq:4-githubaction'
  args:
    - ${{ inputs.cmd }}

kubectl output for the runner pods:
image

workflow:

on: push
jobs:
  working-workflow:
    runs-on: arc-runner
    container: ubuntu:22.04
    steps:
      - uses: actions/checkout@v4
      - run: echo "Bob's your uncle"
  docker-action:
    runs-on: arc-runner
    container: ubuntu:22.04
    steps:
      - uses: actions/checkout@v4
      - name: Read pre-commit config
        uses: ./yq-action
        with:
          cmd: yq . .pre-commit-config.yaml
        # never completes

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions