skip to Main Content

I am trying to set up GitLab CI for a project that has the following requirements:

  • Build a Docker container for a Python application using Flask.
  • Build a Rust binary with the thumbv7em-none-eabihf target.
  • Run tests that involve:
    • Starting the Docker container with the Flask Python application from
      step 1.
    • Mounting the artifacts from step 2.
    • Compiling a custom Rust library.
    • Running the cargo test command for the Rust library.

I’ve tried creating a .gitlab-ci.yml file, but I’m not sure if it’s working correctly, and I’m having trouble understanding how to properly start the Docker container and run the tests with the mounted artifacts.

Here is my files:

# .docker.gitlab-ci.yml file

.docker_init: &docker_init
  - docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} ${CI_REGISTRY}
  - echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}" >> ~/.git-credentials

.python_app_init: &python_app_init
  - // Do some git credential stuff
  - git clone https://github.com/username/python-app.git

# Base Docker job configuration
.docker:base: &base
  image: ${GITLAB_DOCKER_IMAGE}
  services:
    - ${GITLAB_DIND_IMAGE}
  tags:
    - docker

# Build Docker image and push to registry
.docker:build:
  <<: *base
  script:
    - *python_app_init
    - *docker_init
    - docker build -t ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG} .
    - docker push ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}

# Run Docker image
.docker:run:
  <<: *base
  script:
    - *python_app_init
    - *docker_init
    - docker pull ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}
    - docker run --rm ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG} -v ${CI_PROJECT_DIR}/rust-app/target/release/:/apps
# .rust.gitlab-ci.yml

# Base Rust job configuration
.rust:base: &base
  image: ${RUST_BUILD_IMAGE}
  cache:
    key: ${RUST_CACHE_KEY}
    paths:
      - .cache/

.rust_toolchain: &rust_toolchain
  - rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
  - rustup target add thumbv7em-none-eabihf

# Build Embedded Rust application
.rust:build:
  extends: .rust:base
  script:
    - *rust_toolchain
    - cd ${CI_PROJECT_DIR}/rust-app
    - cargo build --release --target thumbv7em-none-eabihf
  artifacts:
    paths:
      - ${CI_PROJECT_DIR}/rust-app/target/release/

# Test Embedded Rust application loaded on python docker image
.rust:test:
  extends: .rust:base
  script:
    - *rust_toolchain
    - cargo test
include:
  - local: '/.docker-ci.yml'
  - local: '/.rust-ci.yml'

stages:
  - build
  - test

# Build rust binary
build:rust:
  stage: build
  extends: .rust:build

# Build docker image
build:docker:
  stage: build
  extends: .docker:build

# Test
test:
  stage: test
  extends: 
    - .docker:run
    - .rust:test
  dependencies:
    - build:rust

The actual CI error output indicates that the .docker:run command is being ignored, preventing the tests from running correctly.

Could someone please help me create a working .gitlab-ci.yml file that meets the requirements above?

UPDATE:
The actual error message you are asking about in your comment is /bin/sh: eval: line xxx: cargo not found.

2

Answers


  1. First of all, I think your post lacks some helpful debugging information. Specifically, an image of the pipeline from the browser would be very helpful in order to see where precisely the error occurs.

    I would however guess from the error message that the "build:rust" job is the first to fail. The message is quite clear, the cargo executable, i.e., the rust make / dependency management system was not found, causing the build to fail. It would also cause the test to fail, but I don’t think you even reach that point.

    What makes this a little difficult to analyze further is that the image which you are using is stored in the variable ${RUST_BUILD_IMAGE}, which you (hopefully) set in you project settings. If you could tell us which image is being used that would again help with the debugging.

    My guess is however that the $PATH is not set up correctly to include the installed cargo. rustup installs into ~/.cargo/bin, so adding the path may help:

    .rust_toolchain: &rust_toolchain
      - rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
      - rustup target add thumbv7em-none-eabihf
      - export PATH="${PATH}:${HOME}/.cargo/bin"
    

    But for something more definitive, we would need to know which image you are using…

    Login or Signup to reply.
  2. The Docker container started in the .docker:run job does not have the Rust toolchain installed.

    To fix this issue, you can modify your .docker:run job to install the Rust toolchain before running the tests. Also, added YAML anchors to avoid duplication of executions and added cache key to build:rust and build:docker. Here’s updated .gitlab-ci.yml:

    # .gitlab-ci.yml
    
    # Define reusable YAML anchors
    .docker_init: &docker_init
      - docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} ${CI_REGISTRY}
      - echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}" >> ~/.git-credentials
    
    .python_app_init: &python_app_init
      - // Do some git credential stuff
      - git clone https://github.com/username/python-app.git
    
    .rust_toolchain: &rust_toolchain
      - rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
      - rustup target add thumbv7em-none-eabihf
    
    # Define Docker image and service names
    .gitlab_docker_image: &gitlab_docker_image
      name: docker:stable
      entrypoint: ["/bin/sh", "-c"]
      command: ["sleep infinity"]
    .gitlab_dind_image: &gitlab_dind_image
      name: docker:stable-dind
      command: ["--insecure-registry", "${CI_REGISTRY}"]
      privileged: true
    
    # Define Rust build image and cache key
    .rust_build_image: &rust_build_image
      name: rust:latest
    .rust_cache_key: &rust_cache_key
      prefix: rust-
      key: ${CI_COMMIT_REF_SLUG}
    
    # Define job stages
    stages:
      - build
      - test
    
    # Define jobs
    build:docker:
      stage: build
      image:
        name: ${GITLAB_DOCKER_IMAGE}
        entrypoint: ["/bin/sh", "-c"]
      services:
        - *gitlab_dind_image
      variables:
        DOCKER_BUILDKIT: "1"
      script:
        - *python_app_init
        - *docker_init
        - docker build -t ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG} .
        - docker push ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}
    
    build:rust:
      stage: build
      image:
        name: ${RUST_BUILD_IMAGE}
        entrypoint: ["/bin/sh", "-c"]
      cache:
        key: *rust_cache_key
        paths:
          - .cache/
      script:
        - *rust_toolchain
        - cd rust-app
        - cargo build --release --target thumbv7em-none-eabihf
      artifacts:
        paths:
          - rust-app/target/release/
    
    test:
      stage: test
      image:
        name: ${GITLAB_DOCKER_IMAGE}
        entrypoint: ["/bin/sh", "-c"]
      services:
        - *gitlab_dind_image
      variables:
        DOCKER_BUILDKIT: "1"
      dependencies:
        - build:docker
        - build:rust
      script:
        - *python_app_init
        - *rust_toolchain
        - docker pull ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}
        - docker run --rm -v ${CI_PROJECT_DIR}/rust-app/target/release:/apps ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG} /bin/sh -c "cd /apps && cargo test"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search