Send environment key as part of job status update
What does this MR do?
Send environment key as part of job status update
With this change all suspended job will send environment key to rails as part of job update request.
Why was this MR needed?
Currently there is no way of sending environment key to the Rails server and this is needed because the orchestrator needs this key to trigger another job and resume the environment created by the suspended job.
What's the best way to test this MR?
-
Check out both branches
# GitLab repo — MR 239583 # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/239583 cd /path/to/gdk/gitlab git fetch origin git checkout ashvins/send-env-key-with-job-completion # Runner repo — MR 6813 # https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/6813 cd /path/to/gitlab-runner git fetch origin git checkout ashvins/send-env-key-to-runnerRun database migrations after checking out the GitLab branch:
cd /path/to/gdk gdk rails db:migrate -
Enable feature flags
There are two separate feature flags, one on each side.
GitLab FF (
ci_suspendable_environment_runner_routing) — enables Rails to persist the key. Open a Rails console (gdk rails console) and run:Feature.enable(:ci_suspendable_environment_runner_routing) Feature.enabled?(:ci_suspendable_environment_runner_routing) # should return true -
Build the runner binary
cd /path/to/gitlab-runner go build -o out/binaries/gitlab-runner ./main.go ./out/binaries/gitlab-runner --version -
Create a PAT
In a GDK Rails console:
token = User.find_by_username('root') .personal_access_tokens .create!(name: 'runner-test', scopes: ['api'], expires_at: 1.day.from_now) puts token.token # copy this value -
Register a runner and write
config.tomlFirst, create a project-scoped runner token via the API. Replace
<PAT>and<PROJECT_ID>:RUNNER_TOKEN=$(curl -s -X POST "https://gdk.test:3000/api/v4/user/runners" \ -H "PRIVATE-TOKEN: <PAT>" \ -H "Content-Type: application/json" \ -d '{"runner_type":"project_type","project_id":<PROJECT_ID>,"description":"env-key-test","tag_list":"env-key-test"}' \ | python3 -c 'import json,sys; print(json.load(sys.stdin)["token"])') echo "Runner token: $RUNNER_TOKEN"Then use
gitlab-runner registerto write the config. It contacts the GitLab instance, resolves the runneridautomatically, and writes the full[[runners]]block:DOCKER_SOCKET=$(docker context inspect --format '{{.Endpoints.docker.Host}}' | sed 's|unix://||') echo "Docker socket: $DOCKER_SOCKET" /path/to/gitlab-runner/out/binaries/gitlab-runner register \ --non-interactive \ --config /tmp/runner-test-config.toml \ --url "https://gdk.test:3000" \ --token "$RUNNER_TOKEN" \ --executor "docker" \ --docker-image "ubuntu:22.04" \ --docker-volumes "$DOCKER_SOCKET:/var/run/docker.sock" \ --docker-host "unix://$DOCKER_SOCKET" \ --tls-ca-file "<path to CA cert in case your GDK is TLS enabled>"After registration, append the runner feature flag to the generated config:
cat >> /tmp/runner-test-config.toml << 'EOF' [runners.feature_flags] FF_SUSPENDABLE_ENVIRONMENTS = true EOF -
One-time project setup
PAT="<PAT>" PROJECT=$(curl -s -X POST "https://gdk.test:3000/api/v4/projects" \ -H "PRIVATE-TOKEN: $PAT" \ -H "Content-Type: application/json" \ -d '{"name":"env-key-test","visibility":"private","initialize_with_readme":"true"}') PROJECT_ID=$(echo $PROJECT | python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])') echo "Project ID: $PROJECT_ID"This only needs to be done once. On repeat runs, skip to Step 7.
-
Trigger a suspendable pipeline from the Rails console
project = Project.find_by_full_path('root/env-key-test') user = User.find_by_username('root') ci_yaml = <<~YAML stages: - test env-key-test: stage: test tags: - env-key-test script: - echo "start" - date - echo "done" YAML result = Ci::CreatePipelineService.new(project, user, ref: 'main').execute( :web, content: ci_yaml, suspend_options: { suspend_on_success: true, suspend_on_failure: false } ) puts "Pipeline #{result.payload.id} status=#{result.payload.status}" # => Pipeline 215 status=pending -
Run the runner
/path/to/gitlab-runner/out/binaries/gitlab-runner run --config /tmp/runner-test-config.tomlThe runner will pick up the job, execute the script, and call
Suspend()on the Docker containers. Watch the log for:Job is set up job=<ID> runner=... ... Job environment suspended: ... ← Suspend() returned container IDs ... Submitting job to coordinator... ← final PUT /api/v4/jobs/:id with environment_key Job succeeded job=<ID> -
Verify the result
curl -s -X POST "https://gdk.test:3000/api/graphql" \ -H "PRIVATE-TOKEN: <PAT>" \ -H "Content-Type: application/json" \ -d "{\"query\": \"{ project(fullPath: \\\"root/env-key-test\\\") { jobs { nodes { id status environmentKey } } } }\"}"Expected response for the successful job:
{ "id": "gid://gitlab/Ci::Build/<JOB_ID>", "status": "SUCCESS", "environmentKey": "<runner_id>/<system_id>/build-container-id=<sha>&helper-id=<sha>" }
What are the relevant issue numbers?
Closes #39463