git 在 jenkinsfile 中使用来自 Jenkins 存储的凭据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39451345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 04:30:22  来源:igfitidea点击:

Using credentials from Jenkins store in a jenkinsfile

gitjenkinsgroovyjenkins-pipeline

提问by BRNTZN

I made a multibranch pipeline project in Jenkins. I need to use two repositories and both need credentials.

我在 Jenkins 中做了一个多分支管道项目。我需要使用两个存储库,并且都需要凭据。

I created a Jenkinsfile in repository1:

我在 repository1 中创建了一个 Jenkinsfile:

node ('label1'){
  stage 'sanity check'
  sh 'echo sanity check'
  stage 'checkout other repository'
  checkout([
      $class: 'GitSCM', branches: [[name: '*/master']],
      userRemoteConfigs: [[url: 'https://[email protected]/BRNTZN/repository2.git'],[credentialsId:'23b2eed1-2863-49d5-bc7b-bcccb9ad914d']]
  ])
  stage 'log results'
  sh 'echo result = OK'
 }

When I push this file onto a branch of repository1 and start the build I get the following error in Jenkins:

当我将此文件推送到 repository1 的分支并开始构建时,我在 Jenkins 中收到以下错误:

Branch indexing
Setting origin to https://[email protected]/BRNTZN/repository1.git
Fetching origin...
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url https://[email protected]/BRNTZN/repository1.git # timeout=10
Fetching upstream changes from https://[email protected]/BRNTZN/repository1.git
 > git --version # timeout=10
using .gitcredentials to set credentials
 > git config --local credential.username BRNTZN # timeout=10
 > git config --local credential.helper store --file=/tmp/git1367320661933193799.credentials # timeout=10
 > git -c core.askpass=true fetch --tags --progress https://[email protected]/BRNTZN/repository1.git +refs/heads/*:refs/remotes/origin/*
 > git config --local --remove-section credential # timeout=10
Checking out Revision d997a29e9d1f639d56eb425ec00e03309e099c7a (jenkinsfilebranch1)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f d997a29e9d1f639d56eb425ec00e03309e099c7a
 > git rev-list f81d0d366fd751857a2640c587817f4d047a15af # timeout=10
[Pipeline] node
Running on jenkins agent (i-07353fc08cb42f10e) in /var/jenkins/workspace/multiBranch/jenkinsfilebranch1
[Pipeline] {
[Pipeline] stage (sanity check)
Entering stage sanity check
Proceeding
[Pipeline] sh
[jenkinsfilebranch1] Running shell script
+ echo sanity check
sanity check
[Pipeline] stage (checkout other repository)
Entering stage checkout other repository
Proceeding
[Pipeline] checkout
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url https://[email protected]/BRNTZN/repository2.git # timeout=10
Fetching upstream changes from https://[email protected]/BRNTZN/repository2.git
 > git --version # timeout=10
 > git -c core.askpass=true fetch --tags --progress https://[email protected]/BRNTZN/repository2.git +refs/heads/*:refs/remotes/origin/*
ERROR: Error fetching remote repo 'origin'
hudson.plugins.git.GitException: Failed to fetch from https://[email protected]/BRNTZN/repository2.git
    at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:799)
    at hudson.plugins.git.GitSCM.retrieveChanges(GitSCM.java:1055)
    at hudson.plugins.git.GitSCM.checkout(GitSCM.java:1086)
    at org.jenkinsci.plugins.workflow.steps.scm.SCMStep.checkout(SCMStep.java:109)
    at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:83)
    at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:73)
    at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution.call(AbstractSynchronousNonBlockingStepExecution.java:52)
    at hudson.security.ACL.impersonate(ACL.java:213)
    at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution.run(AbstractSynchronousNonBlockingStepExecution.java:49)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: hudson.plugins.git.GitException: Command "git -c core.askpass=true fetch --tags --progress https://[email protected]/BRNTZN/repository2.git +refs/heads/*:refs/remotes/origin/*" returned status code 128:
stdout:
stderr: remote: Invalid username or password. If you log in via a third party service you must ensure you have an account password set in your account profile.
fatal: Authentication failed for 'https://[email protected]/BRNTZN/repository2.git/'

    at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:1723)
    at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandWithCredentials(CliGitAPIImpl.java:1459)
    at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.access0(CliGitAPIImpl.java:63)
    at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.execute(CliGitAPIImpl.java:314)
    at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler.call(RemoteGitImpl.java:152)
    at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler.call(RemoteGitImpl.java:145)
    at hudson.remoting.UserRequest.perform(UserRequest.java:153)
    at hudson.remoting.UserRequest.perform(UserRequest.java:50)
    at hudson.remoting.Request.run(Request.java:332)
    at hudson.remoting.InterceptingExecutorService.call(InterceptingExecutorService.java:68)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
    at ......remote call to jenkins agent (i-07353fc08cb42f10e)(Native Method)
    at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1416)
    at hudson.remoting.UserResponse.retrieve(UserRequest.java:253)
    at hudson.remoting.Channel.call(Channel.java:781)
    at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler.execute(RemoteGitImpl.java:145)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler.invoke(RemoteGitImpl.java:131)
    at com.sun.proxy.$Proxy75.execute(Unknown Source)
    at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:797)
    ... 13 more
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: null
Finished: FAILURE

The credentials should be correct:

凭据应该是正确的:

Enter image description here

在此处输入图片说明

And using those credentials for that repository in a freestyle project gives no error:

在自由式项目中使用该存储库的这些凭据不会出​​错:

Enter image description here

在此处输入图片说明

Update

更新

I created a freestyle project using SSH credentials and added that public key to my Bitbucket account to test if I can make SSH work:

我使用 SSH 凭据创建了一个自由式项目,并将该公钥添加到我的 Bitbucket 帐户以测试我是否可以使 SSH 工作:

freestylecredentials SSH

自由式证书 SSH

This worked:

这有效:

    Started by user admin
Building remotely on jenkins agent (i-039385e75b60d70f7) (label1) in workspace /var/jenkins/workspace/gitcredentials test
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url [email protected]:BRNTZN/repository2.git # timeout=10
Fetching upstream changes from [email protected]:BRNTZN/repository2.git
 > git --version # timeout=10
using GIT_SSH to set credentials jenkinsmaster key
 > git -c core.askpass=true fetch --tags --progress [email protected]:BRNTZN/repository2.git +refs/heads/*:refs/remotes/origin/*
 > git rev-parse refs/remotes/origin/master^{commit} # timeout=10
 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision 1d51064143e7337cbc0b1910918166facc9c2330 (refs/remotes/origin/master)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 1d51064143e7337cbc0b1910918166facc9c2330
First time build. Skipping changelog.
Finished: SUCCESS

However when updating the jenkinsfile in the following way:

但是,当以下列方式更新 jenkinsfile 时:

node ('label1'){
  stage 'sanity check'
  sh 'echo sanity check'
  stage 'checkout other repository'
  checkout([
      $class: 'GitSCM', branches: [[name: '*/master']],
      userRemoteConfigs: [[url: '[email protected]:BRNTZN/repository2.git'],[credentialsId:'jenkinsmaster']]
  ])
  stage 'log results'
  sh 'echo result = OK'
 }

I still get the same error:

我仍然收到相同的错误:

Started by user admin
Setting origin to [email protected]:BRNTZN/repository1.git
Fetching origin...
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url [email protected]:BRNTZN/repository1.git # timeout=10
Fetching upstream changes from [email protected]:BRNTZN/repository1.git
 > git --version # timeout=10
using GIT_SSH to set credentials jenkinsmaster key
 > git -c core.askpass=true fetch --tags --progress [email protected]:BRNTZN/repository1.git +refs/heads/*:refs/remotes/origin/*
Checking out Revision 29fc47911827d829f5abe9456bd8df78bc478fe7 (jenkinsfilebranch1)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 29fc47911827d829f5abe9456bd8df78bc478fe7
 > git rev-list 29fc47911827d829f5abe9456bd8df78bc478fe7 # timeout=10
[Pipeline] node
Running on jenkins agent (i-039385e75b60d70f7) in /var/jenkins/workspace/multiBranch/jenkinsfilebranch1
[Pipeline] {
[Pipeline] stage (sanity check)
Entering stage sanity check
Proceeding
[Pipeline] sh
[jenkinsfilebranch1] Running shell script
+ echo sanity check
sanity check
[Pipeline] stage (checkout other repository)
Entering stage checkout other repository
Proceeding
[Pipeline] checkout
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url [email protected]:BRNTZN/repository2.git # timeout=10
Fetching upstream changes from [email protected]:BRNTZN/repository2.git
 > git --version # timeout=10
 > git -c core.askpass=true fetch --tags --progress [email protected]:BRNTZN/repository2.git +refs/heads/*:refs/remotes/origin/*
ERROR: Error fetching remote repo 'origin'
hudson.plugins.git.GitException: Failed to fetch from [email protected]:BRNTZN/repository2.git
    at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:799)
    at hudson.plugins.git.GitSCM.retrieveChanges(GitSCM.java:1055)
    at hudson.plugins.git.GitSCM.checkout(GitSCM.java:1086)
    at org.jenkinsci.plugins.workflow.steps.scm.SCMStep.checkout(SCMStep.java:109)
    at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:83)
    at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:73)
    at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution.call(AbstractSynchronousNonBlockingStepExecution.java:52)
    at hudson.security.ACL.impersonate(ACL.java:213)
    at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution.run(AbstractSynchronousNonBlockingStepExecution.java:49)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: hudson.plugins.git.GitException: Command "git -c core.askpass=true fetch --tags --progress [email protected]:BRNTZN/repository2.git +refs/heads/*:refs/remotes/origin/*" returned status code 128:
stdout:
stderr: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

    at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:1723)
    at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandWithCredentials(CliGitAPIImpl.java:1459)
    at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.access0(CliGitAPIImpl.java:63)
    at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.execute(CliGitAPIImpl.java:314)
    at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler.call(RemoteGitImpl.java:152)
    at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler.call(RemoteGitImpl.java:145)
    at hudson.remoting.UserRequest.perform(UserRequest.java:153)
    at hudson.remoting.UserRequest.perform(UserRequest.java:50)
    at hudson.remoting.Request.run(Request.java:332)
    at hudson.remoting.InterceptingExecutorService.call(InterceptingExecutorService.java:68)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
    at ......remote call to jenkins agent (i-039385e75b60d70f7)(Native Method)
    at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1416)
    at hudson.remoting.UserResponse.retrieve(UserRequest.java:253)
    at hudson.remoting.Channel.call(Channel.java:781)
    at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler.execute(RemoteGitImpl.java:145)
    at sun.reflect.GeneratedMethodAccessor1180.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler.invoke(RemoteGitImpl.java:131)
    at com.sun.proxy.$Proxy75.execute(Unknown Source)
    at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:797)
    ... 13 more
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: null
Finished: FAILURE

回答by MarkRx

Your GitSCM class instantiation is incorrect. You have created two UserRemoteConfig objects - one with a URL of '[email protected]:BRNTZN/repository2.git' and one with a credentialsId of 'jenkinsmaster'. Instead you want one object with both properties set.

您的 GitSCM 类实例化不正确。您已经创建了两个 UserRemoteConfig 对象 - 一个的 URL 为“[email protected]:BRNTZN/repository2.git”,一个的凭据 ID 为“jenkinsmaster”。相反,您需要一个同时设置两个属性的对象。

checkout([
  $class: 'GitSCM', branches: [[name: '*/master']],
  userRemoteConfigs: [[url: '[email protected]:BRNTZN/repository2.git'],[credentialsId:'jenkinsmaster']]
])

Should be:

应该:

checkout([
  $class: 'GitSCM', branches: [[name: '*/master']],
  userRemoteConfigs: [[url: '[email protected]:BRNTZN/repository2.git',credentialsId:'jenkinsmaster']]
])

Notice there are no brackets around the comma in the "userRemoteConfigs" section in the second case.

请注意,在第二种情况下,“userRemoteConfigs”部分中的逗号周围没有括号。

I had just ran into the same issue and connected up an Eclipse debugger to Jenkins to find the issue.

我刚刚遇到了同样的问题,并将 Eclipse 调试器连接到 Jenkins 以查找问题。

See git-plugin GitSCM does not support ssh credentials when using checkout in a Jenkinsfile(45007).

请参阅git-plugin GitSCM 在 Jenkinsfile(45007) 中使用 checkout 时不支持 ssh 凭证

回答by rdeboo

I've had the exact same issue: checkout using credentials in a freestyle project works fine, checkout in a shell (as the jenkinsuser) works fine, and checkout in the pipeline fails. I've updated Jenkins + plugins to the latest version.

我遇到了完全相同的问题:在自由式项目中使用凭据结帐工作正常,在 shell 中结帐(作为jenkins用户)工作正常,并且在管道中结帐失败。我已将 Jenkins + 插件更新到最新版本。

I finally managed to get it to work by placing the correct key in /var/lib/jenkins/.ssh/id_rsa. It looks like the GitSCM plugin completely ignores the provided credentialsId, and just uses the key in /var/lib/jenkins/.ssh/id_rsa. I generated a keypair without passphrase for this.

我终于通过在 /var/lib/jenkins/.ssh/id_rsa 中放置正确的密钥设法让它工作。看起来 GitSCM 插件完全忽略了提供的凭据 ID,而只使用/var/lib/jenkins/.ssh/id_rsa. 我为此生成了一个没有密码的密钥对。

It is a workaround, and I suspect that GitSCM has a bug, but at least you can use the pipeline plugin.

这是一种解决方法,我怀疑 GitSCM 有一个错误,但至少您可以使用管道插件。

回答by Pom12

What kind of credentials do you use?

你使用什么样的凭据?

I suggest that you use SSH credentials (i.e. private/public keys):

我建议您使用 SSH 凭据(即私钥/公钥):

  1. Generatea SSH key pair (make sure you generate it for the correct username!)
  2. Add your public SSH key to your Bitbucket account
  3. Configure your Jenkins to use your newly created SSH private key, as shown in the example below:
  1. 生成SSH 密钥对(确保为正确的用户名生成它!)
  2. 将您的公共SSH 密钥添加到您的 Bitbucket 帐户
  3. 配置您的 Jenkins 以使用您新创建的 SSH 私钥,如下例所示:

Enter image description here

在此处输入图片说明

Then you need to use SSH URL as connection to your Git your credentials in your pipeline (instead of HTTP URL), as follows:

然后,您需要使用 SSH URL 作为连接到您的 Git 您的管道中的凭据(而不是 HTTP URL),如下所示:

checkout([
    $class: 'GitSCM', branches: [[name: '*/master']],
    userRemoteConfigs: [[url:'ssh://[email protected]:BRNTZN/repository2.git'],[credentialsId:'jenkins_ssh_key']]
])

Also, note that you might want to set a specific id for your credentials (e.g. jenkins_ssh_keyor BRNTZN_ssh_key) to improve readability and simplify pipeline configuration.

另请注意,您可能希望为您的凭据(例如jenkins_ssh_keyBRNTZN_ssh_key)设置特定的 id以提高可读性并简化管道配置。

回答by SillentTroll

As stated in Pipeline plugin tutorial, for a multibranch project, you don't have to specify the repository in the node. Just use checkout scm.

Pipeline plugin tutorial 所述,对于多分支项目,您不必在节点中指定存储库。只需使用checkout scm.