GitLab CI запрещает доступ к push с использованием ключа развертывания с доступом на запись

#ssh #continuous-integration #gitlab #yaml #gitlab-ci-runner

#ssh #непрерывная интеграция #gitlab #yaml #gitlab-ci-runner

Вопрос:

Я добавил ключ развертывания с доступом на запись в мой репозиторий GitLab. Мой .gitlab-ci.yml файл содержит:

 - git clone git@gitlab.domain:user/repo.git
- git checkout master
- git add myfile.pdf
- git commit -m "Generated PDF file"
- git push origin master
  

Ключ развертывания работает при клонировании репозитория.
Нажатие невозможно, даже если ключ развертывания имеет доступ на запись.

 remote: You are not allowed to upload code.
fatal: unable to access 'https://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@domain/user/repo.git/': The requested URL returned error: 403
  

Комментарии:

1. Не уверен: docs.gitlab.com/ce/user/project/deploy_tokens /…

2. Речь идет о токенах развертывания, а не о ключах развертывания. Можно ли их использовать для описанной цели?

3. Хороший момент. Я не знаю наверняка.

Ответ №1:

Я только что столкнулся с той же проблемой и увидел этот вопрос без ответа, так что вот мое решение.

Проблема

Проблема вызвана тем фактом, что удаленный URL, используемый git для отправки кода, имеет форму http(s)://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@git.mydomain.com/group/project.git . Этот URL использует http(s) протокол, поэтому git не использует ssh настроенный вами ключ развертывания.

Решение

Решение состоит в том, чтобы изменить push URL удаленного, origin чтобы он соответствовал ssh://git@git.mydomain.com/group/project.git . Самый простой способ сделать это — использовать предопределенную переменную CI_REPOSITORY_URL .

Вот пример кода, делающего это с помощью sed :

 # Change url from http(s) to ssh
url_host=$(echo "${CI_REPOSITORY_URL}" | sed -e 's|https?://gitlab-ci-token:.*@|ssh://git@|g')
echo "${url_host}"
# ssh://git@git.mydomain.com/group/project.git

# Set the origin push url to the new one
git remote set-url --push origin "${url_host}"
  

Кроме того, те, кто использует docker executor, могут захотеть проверить ключ хоста SSH, как предложено документацией gitlab о ключах развертывания для docker executor.

Итак, я привожу более полный пример для docker executor. Код в основном взят из документации gitlab по ключам развертывания ssh. В этом примере закрытый ключ развертывания хранится внутри переменной с именем SSH_PRIVATE_KEY .

 create:push:pdf:
  before_script:
    - 'which ssh-agent || ( apt-get update -y amp;amp; apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "${SSH_PRIVATE_KEY}" | tr -d 'r' | ssh-add - > /dev/null
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - git config --global user.email "email@example.com"
    - git config --global user.name "User name"
    - gitlab_hostname=$(echo "${CI_REPOSITORY_URL}" | sed -e 's|https?://gitlab-ci-token:.*@||g' | sed -e 's|/.*||g')
    - ssh-keyscan "${gitlab_hostname}" >> ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
  script:
    - git checkout master
    - git add myfile.pdf
    - git commit -m "Generated PDF file"
    - url_host=$(echo "${CI_REPOSITORY_URL}" | sed -e 's|https?://gitlab-ci-token:.*@|ssh://git@|g')
    - git remote set-url --push origin "${url_host}"
    - git push origin master

  

Комментарии:

1. Извините за поздний ответ, но мне понадобилось некоторое время, чтобы протестировать это. Это работает! Большое вам спасибо. Он идеально подходит для генерации PDF-файлов с помощью LaTeX.

2. К моему удовольствию, я был рад обнаружить, что я не единственный, кто задает себе этот вопрос. Однако ошибка не совсем очевидна. Со своей стороны, я использую его ежедневно для управления версиями программного обеспечения и выпуска журнала изменений уже месяц без проблем.

3. Пожалуйста, обратите внимание, если у вас runner в Windows, формат переменной среды примерно такой: %CI_REPOSITORY_URL% . Используемые версии: Gitlab: 11.x и Gitlab CI Runner: 11.x