Jenkins:动态作业创建引发“Pipeline CPS Method Mismatches”错误。

huangapple go评论79阅读模式
英文:

Jenkins: Dynamic Job creation throws "Pipeline CPS Method Mismatches " error

问题

我正在尝试从管道作业中创建多个动态作业,这些作业应该并行运行。
我希望我的Jenkins管道脚本能够根据用户输入下载并安装我的软件二进制文件。以下是我的示例阶段:

  1. 阶段1:将下载构建
  2. 阶段2:接受参数并安装我的软件的“云”部分
  3. 阶段3:将接受用户输入“需要部署多少个边缘” (其中边缘是我的构建的第二个组件) 并根据边缘的数量创建动态作业。如果边缘计数为2,则在运行时将创建2个作业。如果边缘为3,则在运行时将创建3个作业。

以下是我成功创建的示例脚本:

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 {
                    // 检索参数值
                    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)

                        // 创建动态流水线作业
                        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" // 存储动态作业的文件夹
    def jobFullName = "${jobFolder}/${jobName}" // 动态作业的全名

    // 创建或更新动态作业的Jenkinsfile
    writeFile file: "${jobFullName}/Jenkinsfile", text: jenkinsfileContent

    // 通过加载Jenkinsfile触发动态作业
    build job: "${jobFullName}"
}

收到的输出:

期望调用WorkflowScript.createPipelineJob,但实际捕获到writeFile;请参阅:https://jenkins.io/redirect/pipeline-cps-method-mismatches/

英文:

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:

  1. stage 1: will download the build
  2. stage 2: take parameter and install my "cloud" portion of my software
  3. stage 3: will take user input "how many edges need to deploy" (wherein edges are my 2nd component of the build) and create dynamic jobs based on number of edges. If edges count is 2 then 2 jobs shall be created at runtime. If edges is 3 then 3 jobs shall be created at runtime

Below are my sample script that I have managed to create

def SETUP_DIR = &quot;&quot;
Map&lt;String, ?&gt; myMap = [:]
Map&lt;String, List&lt;String&gt;&gt; minionMap = [:]
pipeline {
agent any
parameters {
string(name: &#39;RELEASE_VERSION&#39;, defaultValue: &#39;1.0.0&#39;, description: &#39;Define build to use&#39;)
string(name: &#39;Cloud_IP&#39;, defaultValue: &#39;xxx.xx.x.xx&#39;, description: &#39;Central IP&#39;)
choice(name: &#39;No_Of_Edges&#39;, choices: [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39;], description: &#39;Total Edges to Deploy&#39;)
}
stages {
stage(&#39;Identify Installation Parameters&#39;) {
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(&#39;Download Build&#39;) {
steps {
script {
def dirname = sh(returnStdout: true, script: &#39;date +&quot;%d-%m-%Y_%H:%M:%S&quot;&#39;).trim()
sh &quot;&quot;&quot;
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
&lt;some-tasks&gt;
&quot;&quot;&quot;
}
}
}
stage(&#39;Install Cloud&#39;) {
steps {
script {
echo &quot;Installing IEAP Central&quot;
printf &quot;\n \n Updating all files \n \n&quot;
sh &quot;&quot;&quot;
&lt;some-tasks&gt;
printf &quot;\n \n Deployed cloud successfully \n \n&quot;
&quot;&quot;&quot;
}
}
}
stage(&#39;Deploy Edge Cluster&#39;) {
steps {
script {
echo &quot;Installing Edge Control&quot;
def loopCount = No_Of_Edges.toInteger()
for (int i = 1; i &lt;= loopCount; i++) {
def paramInput = input(
id: &quot;paramInput-${i}&quot;,
message: &quot;Enter Edge${i} Value&quot;,
parameters: [
string(name: &quot;Edge_Control_IP_${i}&quot;, defaultValue: &#39;10.139.9.178&#39;, description: &quot;Edge Control IP&quot;),
]
)
def jobName = &quot;Dynamic-Job-${i}&quot;
def jenkinsfileContent = generateJenkinsfileContent(jobName, paramInput)
// Create dynamic pipeline job
createPipelineJob(jobName, jenkinsfileContent)
}
}
}
}
}
}
def generateJenkinsfileContent(String jobName, Map&lt;String, String&gt; params) {
def edgeControlIp = params[&quot;Edge_Control_IP&quot;]
return &quot;&quot;&quot;
pipeline {
agent any
stages {
stage(&#39;Dynamic Job&#39;) {
steps {
script {
echo &quot;This is the dynamic job ${jobName}&quot;
echo &quot;Edge Control IP: ${edgeControlIp}&quot;
}
}
}
}
}
&quot;&quot;&quot;
}
@NonCPS
def createPipelineJob(String jobName, String jenkinsfileContent) {
def jobFolder = &quot;Installation&quot; // Folder to store dynamic jobs
def jobFullName = &quot;${jobFolder}/${jobName}&quot; // Full name of the dynamic job
// Create or update the Jenkinsfile for the dynamic job
writeFile file: &quot;${jobFullName}/Jenkinsfile&quot;, text: jenkinsfileContent
// Trigger the dynamic job by loading the Jenkinsfile
build job: &quot;${jobFullName}&quot;
}

Output received:

expected to call WorkflowScript.createPipelineJob but wound up catching writeFile; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/

答案1

得分: 0

我将示例放在这里,而不是在注释中,以更好地阐明。这是如何在流水线中使用Jenkins CLI的方法:下载CLI,下载现有作业,并将规范发送回Jenkins以创建具有不同名称的相同作业。这是修改规范XML以创建所需作业或执行其他必要操作的良好起点。

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"
英文:

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: &quot;curl.exe -O http://localhost:8080/jnlpJars/jenkins-cli.jar&quot;, returnStdout: true) 
sh &quot;java -jar jenkins-cli.jar -s http://localhost:8080/ -auth user:pass get-job existingJob &gt; existingJob_downloaded&quot; 
sh &quot;java -jar jenkins-cli.jar -s http://localhost:8080/ -auth user:pass -webSocket create-job GeneratedJob&lt;existingJob_downloaded&quot;

huangapple
  • 本文由 发表于 2023年6月5日 21:38:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76407000.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定