Update git mirror to work with http creds
Support case when both source repositories are
cloned via http/https and have different credentials
PROD-32066
Change-Id: I59adaa533797a19405e1ea0c9be8f3aeca244f76
diff --git a/src/com/mirantis/mk/Git.groovy b/src/com/mirantis/mk/Git.groovy
index 9d2bdb7..5743a61 100644
--- a/src/com/mirantis/mk/Git.groovy
+++ b/src/com/mirantis/mk/Git.groovy
@@ -158,8 +158,7 @@
*
* @param sourceUrl Source git repository
* @param targetUrl Target git repository
- * @param credentialsId Credentials id to use for accessing source/target
- * repositories
+ * @param credentialsId Credentials id to use for accessing target repositories
* @param branches List or comma-separated string of branches to sync
* @param followTags Mirror tags
* @param pushSource Push back into source branch, resulting in 2-way sync
@@ -167,25 +166,54 @@
* @param gitEmail Email for creation of merge commits
* @param gitName Name for creation of merge commits
*/
-def mirrorGit(sourceUrl, targetUrl, credentialsId, branches, followTags = false, pushSource = false, pushSourceTags = false, gitEmail = 'jenkins@localhost', gitName = 'Jenkins') {
+def mirrorGit(sourceUrl, targetUrl, credentialsId, branches, followTags = false, pushSource = false, pushSourceTags = false, gitEmail = 'jenkins@localhost', gitName = 'Jenkins', sourceRemote = 'origin') {
def common = new com.mirantis.mk.Common()
def ssh = new com.mirantis.mk.Ssh()
if (branches instanceof String) {
branches = branches.tokenize(',')
}
+ // If both source and target repos are secured and accessible via http/https,
+ // we need to switch GIT_ASKPASS value when running git commands
+ def sourceAskPass
+ def targetAskPass
- ssh.prepareSshAgentKey(credentialsId)
- ssh.ensureKnownHosts(targetUrl)
+ def sshCreds = common.getCredentialsById(credentialsId, 'sshKey') // True if found
+ if (sshCreds) {
+ ssh.prepareSshAgentKey(credentialsId)
+ ssh.ensureKnownHosts(targetUrl)
+ sh "git config user.name '${gitName}'"
+ } else {
+ withCredentials([[$class : 'UsernamePasswordMultiBinding',
+ credentialsId : credentialsId,
+ passwordVariable: 'GIT_PASSWORD',
+ usernameVariable: 'GIT_USERNAME']]) {
+ sh """
+ set +x
+ git config --global credential.${targetUrl}.username \${GIT_USERNAME}
+ echo "echo \${GIT_PASSWORD}" > ${WORKSPACE}/${credentialsId}_askpass.sh
+ chmod +x ${WORKSPACE}/${credentialsId}_askpass.sh
+ git config user.name \${GIT_USERNAME}
+ """
+ sourceAskPass = env.GIT_ASKPASS ?: ''
+ targetAskPass = "${WORKSPACE}/${credentialsId}_askpass.sh"
+ }
+ }
sh "git config user.email '${gitEmail}'"
- sh "git config user.name '${gitName}'"
def remoteExistence = sh(script: "git remote -v | grep ${TARGET_URL} | grep target", returnStatus: true)
- if(remoteExistence != 0){
- // silently try to remove target
- sh(script:"git remote remove target", returnStatus: true)
- sh("git remote add target ${TARGET_URL}")
+ if(remoteExistence == 0) {
+ // silently try to remove target
+ sh(script: "git remote remove target", returnStatus: true)
}
- ssh.agentSh "git remote update --prune"
+ sh("git remote add target ${TARGET_URL}")
+ if (sshCreds) {
+ ssh.agentSh "git remote update --prune"
+ } else {
+ env.GIT_ASKPASS = sourceAskPass
+ sh "git remote update ${sourceRemote} --prune"
+ env.GIT_ASKPASS = targetAskPass
+ sh "git remote update target --prune"
+ }
for (i=0; i < branches.size; i++) {
branch = branches[i]
@@ -201,21 +229,41 @@
sh "git ls-tree target/${branch} && git merge --no-edit --ff target/${branch} || echo 'Target repository is empty, skipping merge'"
followTagsArg = followTags ? "--follow-tags" : ""
- ssh.agentSh "git push ${followTagsArg} target HEAD:${branch}"
+ if (sshCreds) {
+ ssh.agentSh "git push ${followTagsArg} target HEAD:${branch}"
+ } else {
+ sh "git push ${followTagsArg} target HEAD:${branch}"
+ }
if (pushSource == true) {
followTagsArg = followTags && pushSourceTags ? "--follow-tags" : ""
- ssh.agentSh "git push ${followTagsArg} origin HEAD:${branch}"
+ if (sshCreds) {
+ ssh.agentSh "git push ${followTagsArg} origin HEAD:${branch}"
+ } else {
+ sh "git push ${followTagsArg} origin HEAD:${branch}"
+ }
}
}
if (followTags == true) {
- ssh.agentSh "git push -f target --tags"
+ if (sshCreds) {
+ ssh.agentSh "git push -f target --tags"
+ } else {
+ sh "git push -f target --tags"
+ }
if (pushSourceTags == true) {
- ssh.agentSh "git push -f origin --tags"
+ if (sshCreds) {
+ ssh.agentSh "git push -f origin --tags"
+ } else {
+ sh "git push -f origin --tags"
+ }
}
}
sh "git remote rm target"
+ if (!sshCreds) {
+ sh "set +x; rm -f ${targetAskPass}"
+ sh "git config --global --unset credential.${targetUrl}.username"
+ }
}