10

I'm using one of the shared runners on GitLab.com currently. Is it possible to set up the .gitlab-ci.yaml file such that a build can SCP files from a remote server onto the runner? My goal is to SCP files that are necessary dependencies for my build, but they are not tracked in any Git repositories.

I've marked the line where I would like to be able to perform the transfer, but I don't know how to express it properly.

Note: CodeA has dependencies in CodeB and CodeC, which must be built before CodeA can compile, so I need to have access to CodeB and CodeC to build them first on the ubuntu image.

image: ubuntu:12.04

before_script:

build_CodeC:
  stage: build
  allow_failure: true
  script:
-->- scp user@remoteServer:/home/user/file.tar . <---
   - sh ./continuous_integration/build_CodeC_dependency.sh

build_CodeB:
  stage: build
  script:
    - sh ./continuous_integration/build_CodeB_dependency.sh

build_CodeA:
  stage: build
  script:
    - sh ./continuous_integration/build_CodeA.sh
Anthon
  • 69,918
  • 32
  • 186
  • 246
wandadars
  • 1,113
  • 4
  • 19
  • 37

1 Answers1

17

From your question here, I think that getting your dependencies through http is not possible, so here's what you need to do in order to use scp:

  • Generate a key pair
  • Copy the private key to a gitlab CI variable (let's call it SSH_PRIVATE_KEY)
  • Copy the public key to the server gitlab will connect to and add it to your ~/.ssh/authorized_keys file
  • Tell your CI pipeline to use the private key that is stored in the Gitlab CI variable

In order to do that last step, just add the following to your .gitlab-ci.yml in the script or before_script section of the job of interest:

- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
# Run ssh-agent (inside the build environment)
- eval $(ssh-agent -s)
# Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
- ssh-add <(echo "$SSH_PRIVATE_KEY")
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'

You may also want to specify that CodeA is dependent on B and C. In order for that to work, build_CodeB and build_CodeC need to be in a different stage than build_CodeA.

Besides that, you need a way to carry the built files from build_CodeB and build_CodeC jobs to the build_CodeA job. One way to do that is to use artifacts.

In the end, your .gitlab-ci.yml file should look something like this:

image: ubuntu:12.04

stages:
  - deps
  - build

build_CodeC:
  stage: deps
  allow_failure: true
  script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    # Run ssh-agent (inside the build environment)
    - eval $(ssh-agent -s)
    # Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
    - ssh-add <(echo "$SSH_PRIVATE_KEY")
    - mkdir -p ~/.ssh
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
    - scp user@remoteServer:/home/user/file.tar .
    - sh ./continuous_integration/build_CodeC_dependency.sh
  artifacts:
    paths:
      - path_to_built_codeC

build_CodeB:
  stage: deps
  script:
    - sh ./continuous_integration/build_CodeB_dependency.sh
  artifacts:
    paths:
      - path_to_built_codeB

build_CodeA:
  stage: build
  dependencies:
    - build_CodeB
    - build_CodeC
  script:
    - sh ./continuous_integration/build_CodeA.sh

I only put the SSH key setup part in build_CodeC because that's where you are using scp. You would need to copy this over to any job that would require to use scp. I'm thinking you may need to do this in build_codeB since your tar file will not be carried to the build_CodeB job.

Community
  • 1
  • 1
Jawad
  • 4,457
  • 1
  • 26
  • 29
  • Thank you again Jawad. You are correct that scp is necessary for this particular build. The necessary order of building is: CodeC, CodeB, CodeA. So should I have something like a stage for each step? stages: deps1, deps2, build? – wandadars Apr 26 '17 at 16:34
  • 1
    If CodeB is dependent on CodeC then yes. – Jawad Apr 26 '17 at 16:36
  • 1
    I was reading the GitLab notes on [SSH keys](https://docs.gitlab.com/ee/ci/ssh_keys/README.html) and I see that they mention what you have suggested for the case of using the Docker executor. How can I know if I'm running the Docker executor or a shell executor on my local GitLab runner? Is that specified in the gitlab-ci.yaml file somehow? – wandadars Apr 26 '17 at 16:54
  • 1
    Well, since you're starting your yaml file with `image: ubuntu:12.04` I assumed you were running on docker runners. You decide that when you register your runner through gitlab-ci-multi-runner. – Jawad Apr 26 '17 at 18:09
  • Ok. That makes sense. Are the stage names important? When I committed my new yaml control file the pipeline status in GitLab said it skipped the deps stage for some reason. – wandadars Apr 26 '17 at 18:34
  • 1
    The names shouldn't make any difference – Jawad Apr 26 '17 at 18:46