|
Containerized CI/CD allows you to build containers and run them at scale on CSCS systems. The basic idea is that you provide a Dockerfile with build instructions and run the newly created container. Most of the boilerplate work is being taken care by the CI implementation such that you can concentrate on providing build instructions and testing. The important information is provided to you from the CI side for the configuration of your repository.
We support any git provider that supports webhooks. This includes GitHub, GitLab and Bitbucket. A typical pipeline consists of at least one build job and one test job. The build job makes sure that a new container with your most recent code changes is built. The test step uses the new container as part of an MPI job; e.g., it can run your tests on multiple nodes with GPU support.
Building your software inside a container requires a Dockerfile
and a name for the container in the registry where the container will be stored. Testing your software then requires the commands that must be executed to run the tests. No explicit container spawning is required (and also not possible). Your test jobs need to specify the number of nodes and tasks required for the test and the test commands.
Here is an example of a full helloworld project.
It is also helpful to consult the GitLab CI yaml reference documentation and the predefined pipeline variables reference.
In this example we are using the containerized hello world repository. This is a sample Hello World CMake project. The application only echos Hello from $HOSTNAME
, but this should demonstrate the idea of how to run a program on multiple nodes. The pipeline instructions are inside the file ci/cscs.yml
. Let's walk through the pipeline bit by bit.
include: - remote: 'https://gitlab.com/cscs-ci/recipes/-/raw/master/templates/v2/.ci-ext.yml' |
This block includes a yaml file which contains definitions with default values to build and run containers. Have a look inside this file to see available building blocks.
stages: - build - test |
Here we define two different stages, named build
and test
. The names can be chosen freely.
variables: PERSIST_IMAGE_NAME: $CSCS_REGISTRY_PATH/helloworld:$CI_COMMIT_SHORT_SHA |
This block defines variables that will apply to all jobs. See CI variables.
build_job: stage: build extends: .container-builder-cscs-zen2 variables: DOCKERFILE: ci/docker/Dockerfile.build |
This adds a job named build_job
to the stage build
. This runner expects a Dockerfile as input, which is specified in the variable DOCKERFILE
. The resulting container name is specified with the variable PERSIST_IMAGE_NAME
, which has been defined already above, therefore it does not need to be explicitly mentioned in the variables
block, again. There is further documentation of this runner at gitlab-runner-k8s-container-builder
test_job: stage: test extends: .container-runner-eiger-mc image: $PERSIST_IMAGE_NAME script: - /opt/helloworld/bin/hello variables: SLURM_JOB_NUM_NODES: 2 SLURM_NTASKS: 2 |
This block defines a test job. The job will be executed by the daint-container-runner
. This runner will pull the image on the vCluster Piz Daint and run the commands as specified in the script
tag. In this example we are requesting 2 nodes with 1 task on each node, i.e. 2 tasks total. All Slurm environment variables are supported. The commands will be running inside the container specified by the image
tag. The runner is hosted here and supports several other variables.
While the procedure to enable CSCS CI for your repository consists of only a few outlined below, many of them require features in GitHub, GitLab or Bitbucket. The links in the text contain additional steps which may be needed. Some of those documents are non-trivial, especially if you do not have considerable background in the repository features. Plan sufficient time for the setup and contact a GitHub/GitLab/Bitbucket professional, if needed.
Admin config
, and follow the guide (click on the small black triangle next to Firecrest client ID
). Enter all fields for FirecREST, i.e., client-id, client-secret and default Slurm account for job submission.Private repository
box and follow the instructions to add an SSH key to your Git repository.Notification token
. The token is live tested, and you will see a green checkmark when the token is valid and can be used by the CI. It is mandatory to add a token so that your Git repository will be notified about the status of the build jobs. You cannot save anything as long as the notification token is invalid. (Click on the small triangle to get further instructions)Setup webhook details
button. If you click on it you will see all the entries which have to be added to a new webhook in your Git repository. Follow the link given there to your repository, and add the webhook with the given entries.default
. Click on Pipeline default
to see the pipeline setup details. The name can be chosen freely but it cannot contain whitespaces (a short descriptive name). Update the entry point, trusted users and CI-enabled branches.This paragraph applies to GitHub. Other git providers have equivalent settings, but the labels are different. |
The procedure above is deceptively simple: under the hood extremely complicated middleware is being configured. Some of the steps assume an extensive knowledge of GitLab/GitHub functionality: the pointers to the documentation therein may require extensive reading and preparation. If the steps are not completed rigorously, errors in the middleware will occur which are extremely difficult to debug. Here are some points to avoid the key pitfalls
Add webhook: Here you need to click on Webhook setup details (top of page) which then contains a pointer to the repository settings and below it the information which needs to be added when you click on that link. Follow the link and click on Add webhook.
Add notification token: This field will start out with three asterisks (i.e., a hidden token) with a checkmark/red-cross, indicating whether the token is valid/invalid and can write commit statuses.
Clicking on the little triangle will lead you to well-written but voluminous GitHub documentation. We discourage the use of fine-grained tokens. Fine-grained tokens are unsupported, and come with many pitfalls. They can work, but must be enabled at the organization level by an admin, and must be created in the correct organization.
You must choose the correct resource owner, i.e., the organization that the project belongs to. If the organization is not listed, then it has disabled fine-grained tokens at the organization level. It can only be enabled globally on an organization by an admin. As for the repository you can restrict it to only the repository that you want to notify with this token or all repositories. Even if you choose "All repositories", it is still restricted to the organization, and does not grant the access to any repository outside of the resource owner.
Once the token is generated, you will see it exactly once, so copy it immediately into your setup. You will not be able to go back later on to pick it up, and if you do miss the opportunity, the best procedure is to delete existing tokens and generate new ones.
cscs-ci run
commentcscs-ci run PIPELINE_NAME_1,PIPELINE_NAME_2
cscs-ci run
cscs-ci run
command is possible to inject variables into the pipeline (exposed as environment variables)cscs-ci run PIPELINE_NAME;MY_VARIABLE=some_value;ANOTHER_VAR=other_value
, this will trigger the pipeline PIPELINE_NAME
, and in your jobs there will be the environment variables MY_VARIABLE
and ANOTHER_VAR
available.,;=
, because they serve as separators of the different components.data.yaml
, with the contentref: main pipeline: pipeline_name variables: MY_VARIABLE: some_value ANOTHER_VAR: other_value |
curl -X POST -u 'repository_id:webhook_secret' --data-binary @data.yaml https://cicd-ext-mw.cscs.ch/ci/pipeline/trigger
- replace repository_id
and webhook_secret
with your credentialsTypical users do not need to know the underlying workflow behind the scenes, so you can stop reading here. However, it might put the above-mentioned steps into perspective. It also can give you background for inquiring if and when something in the procedure does not go as expected.
cicd-ext-mw.cscs.ch
(CI middleware)GIT_SUBMODULE_STRATEGY: recursive
has to be specified (see GitLab documentation)DOCKERFILE
), will take this Dockerfile and execute docker build -f $DOCKERFILE .
, where the build context is the whole (recursively) cloned repositoryMany variables exist during a pipeline run, they are documented at Gitlab's predefined variables. Additionally to CI variables available through Gitlab, there are a few CSCS specific pipeline variables:
Variable | Value | Additional information |
---|---|---|
CSCS_REGISTRY | jfrog.svc.cscs.ch | CSCS internal registry, preferred registry to store your container images |
CSCS_REGISTRY_PATH | jfrog.svc.cscs.ch/docker-ci-ext/<repository-id> | The prefix path in the CSCS internal container image registry, to which your pipeline has write access. Within this prefix, you can choose any directory structure. Images that are pushed to a path matching |
CSCS_CI_MW_URL | https://cicd-ext-mw.cscs.ch/ci | The URL of the middleware, the orchestrator software. |
CSCS_CI_DEFAULT_SLURM_ACCOUNT | d123 | The project to which accounting will go to. It is set up on the CI setup page in the Admin section. It can be overwritten via |
CSCS_CI_ORIG_CLONE_URL | https://github.com/my-org/my-project (public project) git@github.com:my-org/my-project (private project) | Clone URL for git. This is needed for some implementation details of the gitlab-runner custom executor. This is the clone URL of the registered project, i.e. this is not the clone URL of the mirror project. |
Here are a couple of projects which use this CI setup. Please have a look there for more advanced usage:
ci/prototype.yml
ci/cscs/mc/gitlab-daint.yml
and ci/cscs/gpu/gitlab-daint.yml
ci/gitlab/cscs/gpu/gitlab-daint.yml
and ci/gitlab/cscs/mc/gitlab-daint.yml
ci/pipeline.yml
ci/cscs-ci.yml
ci/cscs-daint.yml
ci/pipeline.yml