I am trying to create multiple dynamic jobs from within one of the pipeline job that should run in parallel. I want my jenkins pipeline script to download and install my software binary based on user input. Below are my sample stages:
Below are my sample script that I have managed to create
def SETUP_DIR = ""
Map<String, ?> myMap = [:]
Map<String, List<String>> minionMap = [:]
pipeline {
agent any
parameters {
string(name: 'RELEASE_VERSION', defaultValue: '1.0.0', description: 'Define build to use')
string(name: 'Cloud_IP', defaultValue: 'xxx.xx.x.xx', description: 'Central IP')
choice(name: 'No_Of_Edges', choices: ['1', '2', '3', '4', '5'], description: 'Total Edges to Deploy')
}
stages {
stage('Identify Installation Parameters') {
steps {
script {
// Retrieve the parameter values
def RELEASE_VERSION = params.RELEASE_VERSION
def Cloud_IP = params.Cloud_IP
def No_Of_Edges = params.No_Of_Edges
}
}
}
stage('Download Build') {
steps {
script {
def dirname = sh(returnStdout: true, script: 'date +"%d-%m-%Y_%H:%M:%S"').trim()
sh """
sudo mkdir -p /root/Automation/${dirname}
echo $dirname
SETUP_DIR=$dirname
cd /root/Automation/${SETUP_DIR}/
VER=${RELEASE_VERSION}
echo \${VER}
sudo curl -u cicd:cicd -X GET url\${VER}.tar.gz --output installer.tar.gz
sleep 60
sudo tar -vxf installer.tar.gz
sleep 30
sudo rm -rf installer.tar.gz
sleep 5
sudo chmod 777 installer
cd installer
<some-tasks>
"""
}
}
}
stage('Install Cloud') {
steps {
script {
echo "Installing IEAP Central"
printf "\n \n Updating all files \n \n"
sh """
<some-tasks>
printf "\n \n Deployed cloud successfully \n \n"
"""
}
}
}
stage('Deploy Edge Cluster') {
steps {
script {
echo "Installing Edge Control"
def loopCount = No_Of_Edges.toInteger()
for (int i = 1; i <= loopCount; i++) {
def paramInput = input(
id: "paramInput-${i}",
message: "Enter Edge${i} Value",
parameters: [
string(name: "Edge_Control_IP_${i}", defaultValue: '10.139.9.178', description: "Edge Control IP"),
]
)
def jobName = "Dynamic-Job-${i}"
def jenkinsfileContent = generateJenkinsfileContent(jobName, paramInput)
// Create dynamic pipeline job
createPipelineJob(jobName, jenkinsfileContent)
}
}
}
}
}
}
def generateJenkinsfileContent(String jobName, Map<String, String> params) {
def edgeControlIp = params["Edge_Control_IP"]
return """
pipeline {
agent any
stages {
stage('Dynamic Job') {
steps {
script {
echo "This is the dynamic job ${jobName}"
echo "Edge Control IP: ${edgeControlIp}"
}
}
}
}
}
"""
}
@NonCPS
def createPipelineJob(String jobName, String jenkinsfileContent) {
def jobFolder = "Installation" // Folder to store dynamic jobs
def jobFullName = "${jobFolder}/${jobName}" // Full name of the dynamic job
// Create or update the Jenkinsfile for the dynamic job
writeFile file: "${jobFullName}/Jenkinsfile", text: jenkinsfileContent
// Trigger the dynamic job by loading the Jenkinsfile
build job: "${jobFullName}"
}
Output received:
expected to call WorkflowScript.createPipelineJob but wound up catching writeFile; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/
I put the example here instead of the comment for better clarity. This is how can one use jenkins cli in the pipeline: downloading cli, downloading existing job and sending specification back to Jenkins to create the same job with different name. This is good starting point to modify specification xml in order to create desired job or do other needed stuff.
def response = sh(script: "curl.exe -O http://localhost:8080/jnlpJars/jenkins-cli.jar", returnStdout: true)
sh "java -jar jenkins-cli.jar -s http://localhost:8080/ -auth user:pass get-job existingJob > existingJob_downloaded"
sh "java -jar jenkins-cli.jar -s http://localhost:8080/ -auth user:pass -webSocket create-job GeneratedJob<existingJob_downloaded"