Jenkins pipeline + Artifactory download not downloading - jenkins

I'm having trouble downloading a build from my artifactory server to my windows jenkins slave node using the jenkins pipeline plugin. It all appears to be going fine, but it doesn't actually download the file. Am I doing something wrong?
I don't see any requests in my Artifactory system logs to download, just to upload.
(2017-04-25 18:39:48,096 [http-nio-8081-exec-2] [INFO ] (o.a.e.UploadServiceImpl:516) - Deploy to 'BUILDS:windows/5840/build.tar.gz' Content-Length: 278600525)
I've been using this as a reference: https://wiki.jenkins-ci.org/pages/viewpage.action?pageId=99910084
Here's the output from my jenkins pipeline:
For pattern: build.tar.gz 1 artifacts were found.
Deploying artifact: http://myartifactory:8081/artifactory/BUILDS/windows/5840/build.tar.gz
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] timeout
Timeout set to expire in 3 min 0 sec
[Pipeline] {
[Pipeline] node
Running on test-windows-0 in C:/jenkinsroot/workspace/test-windows
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] echo
{
"files": [
{
"pattern": "BUILDS/windows/5840/build.tar.gz",
"target": "download/",
}
]
}
[Pipeline] echo
Artifactory Download: BUILDS/windows/5840/build.tar.gz -> download/
The file exists on artifactory.
Here's my jenkins code:
#NonCPS
def downloadArtifactory(String localPath, String repository, String remotePath) {
def downloadSpec = """{
"files": [
{
"pattern": "${repository}/${remotePath}",
"target": "${localPath}",
}
]
}"""
echo "${downloadSpec}"
echo "Artifactory Download: ${repository}/${remotePath} -> ${localPath}"
def server = Artifactory.server("MYARTIFACTORYSERVER")
def buildInfo = server.download spec: downloadSpec
return buildInfo
}
Called with:
downloadArtifactory("download/", "BUILDS", "windows/5840/build.tar.gz")

Removing the NonCPS annotation should solve the problem.
As you can see in this Jenkins issue, Artifactory Jenkins plugin does not support NonCPS.

Please remove the ,(comma) from the line "target": "${localPath}"
,
It works
make it,
def downloadArtifactory(String localPath, String repository, String remotePath) {
def downloadSpec = """{
"files": [
{
"pattern": "${repository}/${remotePath}",
"target": "${localPath}"
}
]
}"""
echo "${downloadSpec}"
echo "Artifactory Download: ${repository}/${remotePath} -> ${localPath}"
def server = Artifactory.server("MYARTIFACTORYSERVER")
def buildInfo = server.download spec: downloadSpec
return buildInfo
}

Related

Jenkins/groovy CPS issue : artifactoryUpload

I'm getting same issue listed as fixed here : https://issues.jenkins.io/browse/JENKINS-58643
We are using Jenkins 2.190.3.2
stage('upload artefactory') {
steps {
sh "touch /tmp/blabla"
sh "gzip /tmp/blabla"
script {
server = Artifactory.server('myid')
server.credentialsId = 'my-cred'
def uploadSpec = """{
"files": [
{
"pattern": "/tmp/blabla.gz",
"target": "pkg/com/myentreprise/mystuff/scm/dumps/solr/"
}
]
}"""
server.upload spec: uploadSpec, failNoOp: true
}
}
}
[Pipeline] artifactoryUpload
expected to call org.jfrog.hudson.pipeline.common.types.ArtifactoryServer.upload but wound up catching artifactoryUpload; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/
this was fixed in Pipeline Groovy 2.75
We have 2.74, thus why we still ahve this bug.
Only solution seems to be to upgrade.

jenkins passing AmazonWebServicesCredentialsBinding to slave node

I have a Jenkins pipeline which needs to run on a slave node. I curently have issues with passing Variables set by plugin withCredentials. When I try to use them on the slave node they are empty, but they work on the master.
Here is the pipeline snippet.
#!groovy
#Library('sharedPipelineLib#master') _
pipeline {
agent { node
{ label 'jenkins-slave-docker' }
}
options {
skipDefaultCheckout(true)
}
environment {
sonar = credentials('SONAR')
}
stages {
stage('Checkout') {
steps {
cleanWs()
script {
checkout scm
}
}
}
stage('Deploy backend') {
steps {
script {
withCredentials([
[
$class : 'AmazonWebServicesCredentialsBinding',
credentialsId : 'AWS_ACCOUNT_ID_DEV',
accessKeyVariable: 'AWS_ACCESS_KEY_ID_DEV',
secretKeyVariable: 'AWS_SECRET_ACCESS_KEY_DEV'
],
[
$class : 'AmazonWebServicesCredentialsBinding',
credentialsId : 'AWS_ACCOUNT_ID_DNS',
accessKeyVariable: 'AWS_ACCESS_KEY_ID_DNS',
secretKeyVariable: 'AWS_SECRET_ACCESS_KEY_DNS'
]
]){
sh '''
echo "$AWS_ACCESS_KEY_ID_DEV\\n$AWS_SECRET_ACCESS_KEY_DEV\\n\\n" | aws configure --profile profile_705229686812
echo "$AWS_ACCESS_KEY_ID_DNS\\n$AWS_SECRET_ACCESS_KEY_DNS\\n\\n" | aws configure --profile profile_417752960097
'''
}
}
}
}
}
}
And the log
[Pipeline] withCredentials
Masking supported pattern matches of $AWS_ACCESS_KEY_ID_DEV or $AWS_SECRET_ACCESS_KEY_DEV or $AWS_SECRET_ACCESS_KEY_DNS or $AWS_ACCESS_KEY_ID_DNS
[Pipeline] {
[Pipeline] sh
echo '\n\n\n'
aws configure --profile profile_705229686812
AWS Access Key ID [None]: AWS Secret Access Key [None]:
EOF when reading a line
the issue was again echo cmd. I had to uses printf instead, cause echo adds newline which causes to fail.

Jenkins Pipeline docker.withRegistry() push leads to endless loop

I managed to setup a jenkins on kubernetes and gitbucket on kubernetes. Now I am trying out to create my own first docker file for uploading on dockerhub. Unfortunately it fails while uploading to docker. Build is successfully, but I cant manage how to upload it to dockerhub (private repository).
Jenkinsfile
def label = "${BUILD_TAG}"
podTemplate(label: label, containers: [
containerTemplate(name: 'docker', image: 'docker:latest', command: 'cat', ttyEnabled: true)
],
volumes: [
hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock')
]) {
node(label) {
def app
def myRepo = checkout scm
def gitCommit = myRepo.GIT_COMMIT
def gitBranch = myRepo.GIT_BRANCH
def shortGitCommit = "${gitCommit[0..10]}"
def previousGitCommit = sh(script: "git rev-parse ${gitCommit}~", returnStdout: true)
stage('Decommission Infrastructure') {
container('kubectl') {
echo "Decmomission..."
}
}
stage('Build application') {
container('docker') {
app = docker.build("fasautomation/recon", ".")
}
}
stage('Run unit tests') {
container('docker') {
app.inside {
sh 'echo "Test passed"'
}
}
}
stage('Docker publish') {
container('docker') {
docker.withRegistry('https://registry.hub.docker.com', '<<jenkins store-credentials>>') {
echo "Pushing 1..."
// Push tagged version
app.push("${env.BUILD_NUMBER}")
echo "Pushing 2..."
// Push latest-tagged version
app.push("latest")
echo "Pushed!"
}
}
}
stage('Deployment') {
container('docker') {
// Deploy to Kubernetes
echo 'Deploying'
}
}
stage('Provision Infrastructure') {
container('kubectl') {
echo 'Provision...'
}
}
}
}
Jenkins Logs
[...]
[Pipeline] stage (hide)
[Pipeline] { (Docker publish)
[Pipeline] container
[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] withDockerRegistry
Executing sh script inside container docker of pod jenkins-recon-master-116-0ksw8-f7779
Executing command: "docker" "login" "-u" "*****" "-p" ******** "https://index.docker.io/v1/"
exit
<<endless loading symbol>>
Does anyone has a clue how to debug here? Credentials work. Not sure why there is the exit in the log without the logs for pushing afterwards... :-(

how to call parameters from groovy map script to Jenkins Pipeline

simply I need to write jenkinsfile pipeline which contains choices and this choices come come from another groovy script that provides a map in this map I can add environment name and 3 values DB , APP , WEB so when I start build a new job I get parameter build with choices to pick the environment name DEV, QA , UAT and according to this choice it will pass map/list of the three IPs for DB,APP, WEB so I can use this values during build
/env.groovy
def DEV = [ DB : 10.0.0.5 , APP : 10.0.0.10 , WEB : 10.0.0.15 ]
def UAT = [ DB : 10.0.0.20 , APP : 10.0.0.25 , WEB : 10.0.0.30 ]
def QA = [ DB : 10.0.0.35 , APP : 10.0.0.40 , WEB : 10.0.0.45 ]
take this values from env.groovy file and pass it to choice in Jenkinsfile so I can get drop down menu with ( DEV - UAT - QA )
before I click build
I do not want to add this values inside the Jenkinsfile , I need to added it to separate groovy script (env.groovy)
this is for new pipeline Jenkinsfile which is running on ubuntu Jenkins server
String[] env = env()
pipeline {
agent any
properties([
parameters([
choice(
choices: env,
description: 'Select the environment',
name: 'ENV',
)
])
])
stages {
stage('deploy') {
steps {
sh "echo ${ENV}"
}
}
}
}
expecting to echo list of environment variables DB , APP and WEB , so I can be sure I can pass this values to another shell script that I will add later to deploy , but I didn't get this menu in the 1st place and I get this error
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 5: The ‘properties’ section has been renamed as of version 0.8. Use ‘options’ instead. # line 5, column 5.
properties([
^
1 error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1085)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:133)
at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:126)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:561)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:522)
at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:320)
at hudson.model.ResourceController.execute(ResourceController.java:97)
at hudson.model.Executor.run(Executor.java:429)
Finished: FAILURE
IMHO there is no possibility to use variable as maps name directly, but we have switch statement.
Try this one:
def map
pipeline {
agent any
parameters {
choice( name: 'env', choices: ['DEV', 'UAT', 'QA'] , description: "Choose ENV?" )
}
stages {
//I'm a bit lazy, in Your case use regular file :)
stage('create file') {
steps {
script {
sh "echo \"DEV = [ DB : '10.0.0.5' , APP : '10.0.0.10' , WEB : '10.0.0.15' ]\" > env.groovy"
sh "echo \"UAT = [ DB : '10.0.0.20' , APP : '10.0.0.25' , WEB : '10.0.0.30' ]\" >> env.groovy"
sh "echo \"QA = [ DB : '10.0.0.35' , APP : '10.0.0.40' , WEB : '10.0.0.45' ]\" >> env.groovy"
}
}
}
stage('switch time') {
steps {
script{
load "$JENKINS_HOME/workspace/box1/env.groovy"
switch (params.env) {
case 'DEV':
map = DEV
break
case 'UAT':
map = UAT
break
case 'QA':
map = QA
break
default:
map = []
break
}
}
}
}
stage('deploy') {
steps {
println map.DB
println map.APP
println map.WEB
}
}
}
}
Expected output:
Started by user 3sky
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on Jenkins in /app/jenkins/home/workspace/box1
[Pipeline] {
[Pipeline] stage
[Pipeline] { (create file)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
[box1] Running shell script
+ echo 'DEV = [ DB : '\''10.0.0.5'\'' , APP : '\''10.0.0.10'\'' , WEB : '\''10.0.0.15'\'' ]'
[Pipeline] sh
[box1] Running shell script
+ echo 'UAT = [ DB : '\''10.0.0.20'\'' , APP : '\''10.0.0.25'\'' , WEB : '\''10.0.0.30'\'' ]'
[Pipeline] sh
[box1] Running shell script
+ echo 'QA = [ DB : '\''10.0.0.35'\'' , APP : '\''10.0.0.40'\'' , WEB : '\''10.0.0.45'\'' ]'
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (switch time)
[Pipeline] script
[Pipeline] {
[Pipeline] load
[Pipeline] { (/app/jenkins/home/workspace/box1/env.groovy)
[Pipeline] }
[Pipeline] // load
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (deploy)
[Pipeline] echo
10.0.0.5
[Pipeline] echo
10.0.0.10
[Pipeline] echo
10.0.0.15
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

Can I publish build info when when pushing a npm .tgz to Artifactory?

How can I publish build info when when pushing a npm registry to Artifactory?
I can do it with Maven using these steps
def rtMaven = Artifactory.newMavenBuild()
def buildInfo = rtMaven.run pom: 'maven-example/pom.xml', goals: 'clean install'
Currently I am just using npm publish
But I would like to have Builds info for my tgz files. Is it possible?
Thanks!
here a sample pipeline code doing simple build.
The only thouble with this script is that i can't figure out how to fill dependencies informations.
node {
stage('Cleaning') {
deleteDir()
}
stage('Preparing') { // for display purposes
// Get some code from Git
git credentialsId: 'MyGitCredential', url: 'http://gitRepourl/MyGitProject.git'
}
stage('Fetch Dependencies') {
// Run the node build
nodejs(nodeJSInstallationName: 'MyNode', configId: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa') {
sh 'npm install'
}
}
stage('Build') {
// Run the node build
nodejs(nodeJSInstallationName: 'MyNode', configId: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa') {
sh 'npm pack'
}
}
stage('Test') {
// Run the node build
nodejs(nodeJSInstallationName: 'MyNode', configId: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa') {
sh 'npm run test'
}
}
stage('Results') {
junit 'test-results.xml' // need to setup karma junit reporter
archive 'myArtefact-*.tgz'
}
stage('Artifactory') {
def uploadSpec = """{
"files": [
{
"pattern": "myArtefact-*.tgz",
"target": "artifactory-npm-repo/myArtefact/"
}
]
}"""
def server = Artifactory.server 'MyArtifactory'
def buildInfo = server.upload(uploadSpec)
buildInfo.retention maxBuilds: 2
server.publishBuildInfo(buildInfo)
}
}
But with this, you've got your build ans artifacts in artifactory

Resources