Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-44142

Step jobDsl can be used at most once in pipeline with DELETE

    XMLWordPrintable

    Details

    • Similar Issues:

      Description

      The example for the jobDsl pipeline step shows usage that cannot actually be used:

      https://github.com/jenkinsci/job-dsl-plugin/wiki/User-Power-Moves#use-job-dsl-in-pipeline-scripts

      node {
          jobDsl scriptText: 'job("example-2")'
      
          jobDsl targets: ['jobs/projectA/*.groovy', 'jobs/common.groovy'].join('\n'),
                 removedJobAction: 'DELETE',
                 removedViewAction: 'DELETE',
                 lookupStrategy: 'SEED_JOB',
                 additionalClasspath: ['libA.jar', 'libB.jar'].join('\n')
      }
      

      This will always delete the job "example-2" because the second step DELETEs all unfreferenced items, unless of course one of the scripts also happens to create a job named "example-2".

       

      From my brief look at the source, I don't think this would be easy to implement. However, it would still be incredibly useful to be able to call jobDsl multiple times with different arguments.

       

        Attachments

          Issue Links

            Activity

            Hide
            vqrs Christian V added a comment -

            I've taken another look at this.

            When multiple job-dsl scripts are run, job-dsl will attach multiple "actions" to the build. The current code seems to assume that there is only a single one.

             

            To find the last generated objects, it's probably a simple change, maybe something like this:

             

             

            Set<T> findLastGeneratedObjects() {
                for (Run run = job.lastBuild; run != null; run = run.previousBuild) {
                    // We need to fetch all actions because job-dsl could habe been run multiple times in a single build.
            
                    // Previously, it would use the first build, whose first buildAction's modifiedObjects was set
                    // Now, it chooses the first build, where at least one buildAction's modifiedObjects is set
                    List<B> actions = run.getActions(buildActionClass)
                    Set<T> result = []
                    boolean useThisResult = false
                    for (B action : actions) {
                        if (action.modifiedObjects != null) {
                            useThisResult = true
                            result += action.modifiedObjects
                        }
                    }
            
                    if (useThisResult) {
                        return result
                    }
                }
                []
            }
            

            Further, job-dsl needs to be made aware of previous invocations during the same build run.

             

            Currently, it compares the "new items" against the items items from the first suitable previous run. Here's a simple idea:

            GeneratedItems generatedItems = dslScriptLoader.runScripts(scriptRequests);
            mergeWithCurrentRun(generatedItems, run); // <-- this would be the only change
            Set<GeneratedJob> freshJobs = generatedItems.getJobs();
            Set<GeneratedView> freshViews = generatedItems.getViews();
            Set<GeneratedConfigFile> freshConfigFiles = generatedItems.getConfigFiles();
            Set<GeneratedUserContent> freshUserContents = generatedItems.getUserContents();

             

            One could simply pretend that a subsequent invocation also "generated" the items that were generated previously in the same run.

             

            The last invocation's log output would then summarize everything that job-dsl did.

             

            Finally, one could check whether a build action is already appened to the current run and replace it it instead, instead of unconditionally doing run.addAction:

             

            // Save onto Builder, which belongs to a Project.
            run.addAction(new GeneratedJobsBuildAction(freshJobs, getLookupStrategy()));
            run.addAction(new GeneratedViewsBuildAction(freshViews, getLookupStrategy()));
            run.addAction(new GeneratedConfigFilesBuildAction(freshConfigFiles));
            run.addAction(new GeneratedUserContentsBuildAction(freshUserContents));

             

            This might affect JENKINS-29784

             

            Daniel Spilker Thoughts?

             

            Show
            vqrs Christian V added a comment - I've taken another look at this. When multiple job-dsl scripts are run, job-dsl will attach multiple "actions" to the build. The current code seems to assume that there is only a single one.   To find the last generated objects, it's probably a simple change, maybe something like this:     Set<T> findLastGeneratedObjects() { for (Run run = job.lastBuild; run != null ; run = run.previousBuild) { // We need to fetch all actions because job-dsl could habe been run multiple times in a single build. // Previously, it would use the first build, whose first buildAction's modifiedObjects was set // Now, it chooses the first build, where at least one buildAction's modifiedObjects is set List<B> actions = run.getActions(buildActionClass) Set<T> result = [] boolean useThisResult = false for (B action : actions) { if (action.modifiedObjects != null ) { useThisResult = true result += action.modifiedObjects } } if (useThisResult) { return result } } [] } Further, job-dsl needs to be made aware of previous invocations during the same build run.   Currently, it compares the "new items" against the items items from the first suitable previous run. Here's a simple idea: GeneratedItems generatedItems = dslScriptLoader.runScripts(scriptRequests); mergeWithCurrentRun(generatedItems, run); // <-- this would be the only change Set<GeneratedJob> freshJobs = generatedItems.getJobs(); Set<GeneratedView> freshViews = generatedItems.getViews(); Set<GeneratedConfigFile> freshConfigFiles = generatedItems.getConfigFiles(); Set<GeneratedUserContent> freshUserContents = generatedItems.getUserContents();   One could simply pretend that a subsequent invocation also "generated" the items that were generated previously in the same run.   The last invocation's log output would then summarize everything that job-dsl did.   Finally, one could check whether a build action is already appened to the current run and replace it it instead, instead of unconditionally doing run.addAction:   // Save onto Builder, which belongs to a Project. run.addAction( new GeneratedJobsBuildAction(freshJobs, getLookupStrategy())); run.addAction( new GeneratedViewsBuildAction(freshViews, getLookupStrategy())); run.addAction( new GeneratedConfigFilesBuildAction(freshConfigFiles)); run.addAction( new GeneratedUserContentsBuildAction(freshUserContents));   This might affect JENKINS-29784   Daniel Spilker Thoughts?  
            Hide
            vqrs Christian V added a comment - - edited

            Hmm, Generated*BuildActions also contains the lookup strategy. One would have to have up to two actions per type, one per possible strategy.

             

            Then, JENKINS-29784 should also be solved, hopefully.

            Show
            vqrs Christian V added a comment - - edited Hmm, Generated*BuildActions also contains the lookup strategy. One would have to have up to two actions per type, one per possible strategy.   Then, JENKINS-29784 should also be solved, hopefully.
            Hide
            markus_b_b Markus Baur added a comment -

            This problem took me by surprise and removed history of many jobs. It would be great if it gets addressed soon. It should at least be documented with the DELETE action.

            Show
            markus_b_b Markus Baur added a comment - This problem took me by surprise and removed history of many jobs. It would be great if it gets addressed soon. It should at least be documented with the DELETE action.

              People

              • Assignee:
                daspilker Daniel Spilker
                Reporter:
                vqrs Christian V
              • Votes:
                5 Vote for this issue
                Watchers:
                7 Start watching this issue

                Dates

                • Created:
                  Updated: