From 10ef9d68018ddd9b001499cb0bbb72ce1cffb4da Mon Sep 17 00:00:00 2001 From: Thierry Martinez <Thierry.Martinez@inria.fr> Date: Wed, 15 Feb 2023 17:31:42 +0100 Subject: [PATCH] Fix #2: Unique state and runner for a given pipeline This commit makes state filename unique for a given pipeline (and remove this state in the cleaning phase), and adds a unique tag to the runners created for the pipeline for jobs not to be run in runners from other pipelines that run in parallel. --- .gitlab-ci.yml | 72 +++++++++----------------------------- cloud-init.sh.tftpl | 2 +- dynamic-pipeline.yml | 70 ++++++++++++++++++++++++++++++++++++ generate-child-pipeline.sh | 6 ++++ main.tf | 13 +++---- 5 files changed, 100 insertions(+), 63 deletions(-) create mode 100644 dynamic-pipeline.yml create mode 100644 generate-child-pipeline.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1affdae..2f6e6ac 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,63 +1,23 @@ -variables: - CI_TEMPLATE_REGISTRY_HOST: registry.gitlab.inria.fr - TF_STATE_NAME: default +workflow: + rules: + - if: $CLOUDSTACK_API_KEY -include: - - template: Terraform/Base.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml - -stages: - - validate - - deploy - - execute - - cleanup - -fmt: +generate-child-pipeline: tags: - linux - small - extends: .terraform:fmt - -validate: - tags: - - linux - - small - extends: .terraform:validate - before_script: - - cp $SSH_PRIVATE_KEY id_rsa - -deploy: - stage: deploy - tags: - - linux - - small - script: - - cp $SSH_PRIVATE_KEY id_rsa - - gitlab-terraform plan -var runner_count=0 - - gitlab-terraform apply - - gitlab-terraform plan -var runner_count=3 - - gitlab-terraform apply - -execute: - stage: execute image: alpine - parallel: - matrix: - - index: [0, 1, 2] - tags: - - terraform - - docker - - runner-$index script: - - echo Greetings from runner $index! + - sh generate-child-pipeline.sh > generated-child-pipeline.yml + artifacts: + paths: + - generated-child-pipeline.yml -cleanup: - stage: cleanup - tags: - - linux - - small - script: - - cd "${TF_ROOT}" - - cp $SSH_PRIVATE_KEY id_rsa - - gitlab-terraform plan -var runner_count=0 - - gitlab-terraform apply - when: always +execute-child-pipeline: + needs: + - generate-child-pipeline + trigger: + include: + - artifact: generated-child-pipeline.yml + job: generate-child-pipeline + diff --git a/cloud-init.sh.tftpl b/cloud-init.sh.tftpl index 2b4d6de..4111b67 100644 --- a/cloud-init.sh.tftpl +++ b/cloud-init.sh.tftpl @@ -16,7 +16,7 @@ # We install docker.io to be able to register a docker executor apt-get install --yes gitlab-runner docker.io gitlab-runner register --non-interactive \ - --tag-list terraform,docker,runner-${index} \ + --tag-list terraform,docker,pipeline-${CI_PARENT_PIPELINE_ID},runner-${index} \ --executor docker --docker-image alpine --url https://gitlab.inria.fr \ --registration-token ${REGISTRATION_TOKEN} ) >>/root/log.txt 2>&1 diff --git a/dynamic-pipeline.yml b/dynamic-pipeline.yml new file mode 100644 index 0000000..6296b34 --- /dev/null +++ b/dynamic-pipeline.yml @@ -0,0 +1,70 @@ +# Workaround for child pipeline to work in merge requests +# See: https://gitlab.com/gitlab-org/gitlab/-/issues/222370#note_662695503 +workflow: + rules: + - if: $CI_MERGE_REQUEST_IID + - if: $CI_COMMIT_BRANCH + +variables: + CI_TEMPLATE_REGISTRY_HOST: registry.gitlab.inria.fr + TF_STATE_NAME: pipeline-$CI_PARENT_PIPELINE_ID + TF_VAR_CI_PARENT_PIPELINE_ID: $CI_PARENT_PIPELINE_ID + +include: + - template: Terraform/Base.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml + +stages: + - validate + - deploy + - execute + - cleanup + +fmt: + tags: + - linux + - small + extends: .terraform:fmt + +validate: + tags: + - linux + - small + extends: .terraform:validate + before_script: + - cp $SSH_PRIVATE_KEY id_rsa + +deploy: + stage: deploy + tags: + - linux + - small + script: + - cp $SSH_PRIVATE_KEY id_rsa + - gitlab-terraform plan + - gitlab-terraform apply + +execute: + stage: execute + image: alpine + parallel: + matrix: + - index: [0, 1, 2] + tags: + - terraform + - docker + - pipeline-$CI_PARENT_PIPELINE_ID + - runner-$index + script: + - echo Greetings from runner $index! + +cleanup: + stage: cleanup + tags: + - linux + - small + script: + - cd "${TF_ROOT}" + - cp $SSH_PRIVATE_KEY id_rsa + - gitlab-terraform destroy + - 'curl --user "gitlab-ci-token:$CI_JOB_TOKEN" --request DELETE "$CI_API_V4_URL/projects/$CI_PROJECT_ID/terraform/state/$TF_STATE_NAME"' + when: always diff --git a/generate-child-pipeline.sh b/generate-child-pipeline.sh new file mode 100644 index 0000000..b127e0f --- /dev/null +++ b/generate-child-pipeline.sh @@ -0,0 +1,6 @@ +set -ex +cat <<EOF +include: "dynamic-pipeline.yml" +variables: + CI_PARENT_PIPELINE_ID: "$CI_PIPELINE_ID" +EOF diff --git a/main.tf b/main.tf index 7683dcf..86bb8b4 100644 --- a/main.tf +++ b/main.tf @@ -24,13 +24,13 @@ variable "SSH_PUBLIC_KEY" { type = string } -variable "runner_count" { +variable "CI_PARENT_PIPELINE_ID" { type = number } resource "cloudstack_instance" "runner" { - count = var.runner_count - name = "gitlabcigallery-terraform-runner-${count.index}" + count = 3 + name = "gitlabcigallery-terraform-pipeline-${var.CI_PARENT_PIPELINE_ID}-${count.index}" service_offering = "Custom" template = "ubuntu-20.04-lts" zone = "zone-ci" @@ -40,9 +40,10 @@ resource "cloudstack_instance" "runner" { } expunge = true user_data = templatefile("cloud-init.sh.tftpl", { - index = count.index - REGISTRATION_TOKEN = var.REGISTRATION_TOKEN - SSH_PUBLIC_KEY = var.SSH_PUBLIC_KEY + index = count.index + REGISTRATION_TOKEN = var.REGISTRATION_TOKEN + SSH_PUBLIC_KEY = var.SSH_PUBLIC_KEY + CI_PARENT_PIPELINE_ID = var.CI_PARENT_PIPELINE_ID }) connection { type = "ssh" -- GitLab