From 8a388e5d21cd07c2c497838f4f9e0e5f75231248 Mon Sep 17 00:00:00 2001 From: Joerg Flade Date: Mon, 4 May 2020 12:30:50 +0200 Subject: [PATCH] * Adding LogRotator for history --- README.md | 15 +++++- src/JenkinsJobDslRemote.groovy | 14 +++++ src/examples/jenkins-jobdsl-jobs.json | 8 +++ src/model/BaseJobDslPipelineModel.groovy | 22 +++++++- src/model/LogRotator.groovy | 20 +++++++ test/groovy/Json2ModelParserTest.groovy | 69 +++++++++++++++++++----- test/resources/jenkins-jobdsl-jobs.json | 23 ++++++++ 7 files changed, 155 insertions(+), 16 deletions(-) create mode 100644 src/model/LogRotator.groovy diff --git a/README.md b/README.md index 09b5833..e3be8ca 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,9 @@ The structure of the JSON looks like described in the example on buttom. | `repositoryUrl`| string | *Git* | defines the URL to the GIT repository. (`required`) | | `repositoryTrigger`| string | *Git* | defines a trigger in cron format at which time the SCM plugin should check for new commits. | | `credentialsId`| string | *MultibranchJob* or *PipelineJob* | defines the credentialsId, which are available through Jenkins to access a private repository. It is also possible to set a `GIT_CREDENTIALS_ID` environment variable at the build slave. If this is defined in the JSON, it overwrites the env variable. | +| `logRotator` | object | *MultibranchJob* or *PipelineJob* | object, that contains the log rotation parameter. Can be set to null, if no logs should be rotated. | +| `daysToKeep` | integer | *logRotator* | defines how many days the artifact and history should be kept. `Default: 10`. Can be set to null for unlimited. | +| `numToKeep` | integer | *logRotator* | defines how many entries of the history should be kept. `Default: 5`. Can be set to null for unlimited. | ## Example of the JSON for the job definition ## @@ -91,7 +94,11 @@ The structure of the JSON looks like described in the example on buttom. "repositoryUrl": "https://github.com/myProjects/myMultibranchProject.git", "repositoryTrigger": "* * * * *", "credentialsId": "myGitCredentialsId" - } + }, + "logRotator": { + "daysToKeep": 10, + "numToKeep": 5 + } } ], "pipelineJobs": [ @@ -107,7 +114,11 @@ The structure of the JSON looks like described in the example on buttom. "repositoryUrl": "https://github.com/myProjects/myPipelineJobProject.git", "repositoryTrigger": "* * * * *", "credentialsId": "myGitCredentialsId" - } + }, + "logRotator": { + "daysToKeep": 10, + "numToKeep": 5 + } } ] } diff --git a/src/JenkinsJobDslRemote.groovy b/src/JenkinsJobDslRemote.groovy index 3cc69b9..7326bcd 100644 --- a/src/JenkinsJobDslRemote.groovy +++ b/src/JenkinsJobDslRemote.groovy @@ -232,6 +232,14 @@ void createMultibranchPipelineJob(final MultibranchModel multibranchModel) { triggers { (multibranchModel.getGit().getRepositoryTrigger() != null) ? cron(multibranchModel.getGit().getRepositoryTrigger()) : "" } + if (pipelineJobModel.getLogRotator() != null && (pipelineJobModel.getLogRotator().getDaysToKeep() != null || pipelineJobModel.getLogRotator().getNumToKeep() != null)) { + orphanedItemStrategy { + discardOldItems { + (pipelineJobModel.getLogRotator().getDaysToKeep() != null) ? daysToKeep(pipelineJobModel.getLogRotator().getDaysToKeep()) : "" + (pipelineJobModel.getLogRotator().getNumToKeep() != null) ? numToKeep(pipelineJobModel.getLogRotator().getNumToKeep()) : "" + } + } + } } println("[INFO] finished creating multibranch job (${multibranchModel.getJobName()})") } @@ -266,6 +274,12 @@ void createPipelineJob(final PipelineJobModel pipelineJobModel) { scriptPath(pipelineJobModel.getPipelineScriptPath()) } } + if (pipelineJobModel.getLogRotator() != null && (pipelineJobModel.getLogRotator().getDaysToKeep() != null || pipelineJobModel.getLogRotator().getNumToKeep() != null)) { + logRotator { + (pipelineJobModel.getLogRotator().getDaysToKeep() != null) ? daysToKeep(pipelineJobModel.getLogRotator().getDaysToKeep()) : "" + (pipelineJobModel.getLogRotator().getNumToKeep() != null) ? artifactNumToKeep(pipelineJobModel.getLogRotator().getNumToKeep()) : "" + } + } } println("[INFO] finished creating pipeline job (${pipelineJobModel.getJobName()})") } \ No newline at end of file diff --git a/src/examples/jenkins-jobdsl-jobs.json b/src/examples/jenkins-jobdsl-jobs.json index 58368f3..166625b 100644 --- a/src/examples/jenkins-jobdsl-jobs.json +++ b/src/examples/jenkins-jobdsl-jobs.json @@ -10,6 +10,10 @@ "repositoryUrl": "https://github.com/myProjects/myMultibranchProject.git", "repositoryTrigger": "* * * * *", "credentialsId": "myGitCredentialsId" + }, + "logRotator": { + "daysToKeep": 10, + "numToKeep": 5 } } ], @@ -26,6 +30,10 @@ "repositoryUrl": "https://github.com/myProjects/myPipelineJobProject.git", "repositoryTrigger": "* * * * *", "credentialsId": "myGitCredentialsId" + }, + "logRotator": { + "daysToKeep": 10, + "numToKeep": 5 } } ] diff --git a/src/model/BaseJobDslPipelineModel.groovy b/src/model/BaseJobDslPipelineModel.groovy index cb4b4b9..1c0cbaf 100644 --- a/src/model/BaseJobDslPipelineModel.groovy +++ b/src/model/BaseJobDslPipelineModel.groovy @@ -4,9 +4,29 @@ import groovy.transform.ToString @ToString(includeNames = true, includeFields = true, ignoreNulls = true) class BaseJobDslPipelineModel { + /** + * Name of the job (mandatory) + */ String jobName + /** + * Description of the job (mandatory) + */ String jobDescription - String pipelineScriptPath + /** + * Path to the Jenkins pipeline script like Jenkinsfile (optional) + * Default: Jenkinsfile + */ + String pipelineScriptPath = "Jenkinsfile" + /** + * View to which this job should be assigned (optional) + */ String view + /** + * Log rotators for the job (optional) + */ + LogRotator logRotator = new LogRotator() + /** + * Git Model for the repository (mandatory) + */ GitModel git } diff --git a/src/model/LogRotator.groovy b/src/model/LogRotator.groovy new file mode 100644 index 0000000..0427024 --- /dev/null +++ b/src/model/LogRotator.groovy @@ -0,0 +1,20 @@ +package model + +import groovy.transform.ToString + +/** + * Represents the log rotation of the jobs + */ +@ToString(includeNames = true, includeFields = true, ignoreNulls = true) +class LogRotator { + /** + * represents the days to keep the logfiles. + * Default: 10 + */ + Integer daysToKeep = 10 + /** + * represents the number of artifacts to keep + * Default: 5 + */ + Integer numToKeep = 5 +} diff --git a/test/groovy/Json2ModelParserTest.groovy b/test/groovy/Json2ModelParserTest.groovy index c583ec4..248c860 100644 --- a/test/groovy/Json2ModelParserTest.groovy +++ b/test/groovy/Json2ModelParserTest.groovy @@ -14,7 +14,7 @@ class Json2ModelParserTest extends GroovyTestCase { // assert basic structure assertNotNull(jenkinsJobModel.multiBranchJobs) assertNotNull(jenkinsJobModel.pipelineJobs) - assertEquals(2, jenkinsJobModel.multiBranchJobs.size()) + assertEquals(3, jenkinsJobModel.multiBranchJobs.size()) assertEquals(1, jenkinsJobModel.pipelineJobs.size()) // validate multibranchModel @@ -27,6 +27,8 @@ class Json2ModelParserTest extends GroovyTestCase { "https://github.com/myProjects/firstMultiBranchJob.git", "* * * * *", "myGitCredentialsId", + null, + null, jenkinsJobModel.multiBranchJobs.get(0) as MultibranchModel ) assertEqualsMultiBranchJobModel( @@ -38,8 +40,23 @@ class Json2ModelParserTest extends GroovyTestCase { "https://github.com/myProjects/secondMultiBranchJob.git", "* * * * *", "myGitCredentialsId", + 10, + 15, jenkinsJobModel.multiBranchJobs.get(1) as MultibranchModel ) + assertEqualsMultiBranchJobModel( + "thirdMultiBranchJob", + "Third job", + null, + "Jenkinsfile", + "thirdMultiBranchJob", + "https://github.com/myProjects/thirdMultiBranchJob.git", + "* * * * *", + "myGitCredentialsId", + 5, + 10, + jenkinsJobModel.multiBranchJobs.get(2) as MultibranchModel + ) // validate pipelineJob assertEqualsPipelineJobModel( @@ -54,6 +71,8 @@ class Json2ModelParserTest extends GroovyTestCase { "https://github.com/myProjects/myPipelineJobProject.git", "* * * * *", "myGitCredentialsId", + 10, + 15, jenkinsJobModel.pipelineJobs.get(0) as PipelineJobModel ) } @@ -83,6 +102,8 @@ class Json2ModelParserTest extends GroovyTestCase { * @param gitRepositoryUrl expected repositoryUrl of the Git object of the multibranch job * @param gitRepositoryTrigger expected repositoryTrigger of the Git object of the multibranch job * @param gitCredentialsId expected credentialsId of the Git object of the multibranch job + * @param logRotatorNumToKeep expected logRotator.numToKeep of the multibranch job + * @param logRotatorDaysToKeep expected logRotator.daysToKeep of the multibranch job * @param multibranchModel filled instance of MultiBranchModel which should be compared (actual) */ private void assertEqualsMultiBranchJobModel( @@ -94,12 +115,22 @@ class Json2ModelParserTest extends GroovyTestCase { String gitRepositoryUrl, String gitRepositoryTrigger, String gitCredentialsId, + Integer logRotatorNumToKeep, + Integer logRotatorDaysToKeep, MultibranchModel multibranchModel ) { + // basic data assertEquals(jobName, multibranchModel.jobName) assertEquals(jobDescription, multibranchModel.jobDescription) assertEquals(view, multibranchModel.view) assertEquals(pipelineScriptPath, multibranchModel.pipelineScriptPath) + + // log rotate data + assertNotNull(multibranchModel.logRotator) + assertEquals(logRotatorDaysToKeep, multibranchModel.logRotator.daysToKeep) + assertEquals(logRotatorNumToKeep, multibranchModel.logRotator.numToKeep) + + // git data assertNotNull(multibranchModel.git) assertEquals(gitRepositoryId, multibranchModel.git.repositoryId) assertEquals(gitRepositoryUrl, multibranchModel.git.repositoryUrl) @@ -107,19 +138,21 @@ class Json2ModelParserTest extends GroovyTestCase { assertEquals(gitCredentialsId, multibranchModel.git.credentialsId) } /** - * Check the MultibranchModel + * Check the PipelineJobModel * - * @param jobName expected name of the multibranch job - * @param jobDescription expected description of the multibranch job - * @param view expected view of the multibranch job - * @param pipelineScriptPath expected pipeline scriptPath of the multibranch job - * @param cronTrigger expected cronTrigger of the multibranch job - * @param remoteTriggerUuid expected remoteTriggerUuid of the multibranch job - * @param remoteBranchName expected remoteBranchName of the multibranch job - * @param gitRepositoryId expected repositoryId of the Git object of the multibranch job - * @param gitRepositoryUrl expected repositoryUrl of the Git object of the multibranch job - * @param gitRepositoryTrigger expected repositoryTrigger of the Git object of the multibranch job - * @param gitCredentialsId expected credentialsId of the Git object of the multibranch job + * @param jobName expected name of the pipeline job + * @param jobDescription expected description of the pipeline job + * @param view expected view of the pipeline job + * @param pipelineScriptPath expected pipeline scriptPath of the pipeline job + * @param cronTrigger expected cronTrigger of the pipeline job + * @param remoteTriggerUuid expected remoteTriggerUuid of the pipeline job + * @param remoteBranchName expected remoteBranchName of the pipeline job + * @param gitRepositoryId expected repositoryId of the Git object of the pipeline job + * @param gitRepositoryUrl expected repositoryUrl of the Git object of the pipeline job + * @param gitRepositoryTrigger expected repositoryTrigger of the Git object of the pipeline job + * @param gitCredentialsId expected credentialsId of the Git object of the pipeline job + * @param logRotatorNumToKeep expected logRotator.numToKeep of the pipeline job + * @param logRotatorDaysToKeep expected logRotator.daysToKeep of the pipeline job * @param pipelineJobModel filled instance of MultiBranchModel which should be compared (actual) */ private void assertEqualsPipelineJobModel( @@ -134,8 +167,11 @@ class Json2ModelParserTest extends GroovyTestCase { String gitRepositoryUrl, String gitRepositoryTrigger, String gitCredentialsId, + Integer logRotatorNumToKeep, + Integer logRotatorDaysToKeep, PipelineJobModel pipelineJobModel ) { + // basic job data assertEquals(jobName, pipelineJobModel.jobName) assertEquals(jobDescription, pipelineJobModel.jobDescription) assertEquals(view, pipelineJobModel.view) @@ -143,6 +179,13 @@ class Json2ModelParserTest extends GroovyTestCase { assertEquals(cronTrigger, pipelineJobModel.cronTrigger) assertEquals(remoteTriggerUuid, pipelineJobModel.remoteTriggerUuid) assertEquals(remoteBranchName, pipelineJobModel.remoteBranchName) + + // log rotator data + assertNotNull(pipelineJobModel.logRotator) + assertEquals(logRotatorDaysToKeep, pipelineJobModel.logRotator.daysToKeep) + assertEquals(logRotatorNumToKeep, pipelineJobModel.logRotator.numToKeep) + + // git data assertNotNull(pipelineJobModel.git) assertEquals(gitRepositoryId, pipelineJobModel.git.repositoryId) assertEquals(gitRepositoryUrl, pipelineJobModel.git.repositoryUrl) diff --git a/test/resources/jenkins-jobdsl-jobs.json b/test/resources/jenkins-jobdsl-jobs.json index d82effb..96d2f2e 100644 --- a/test/resources/jenkins-jobdsl-jobs.json +++ b/test/resources/jenkins-jobdsl-jobs.json @@ -10,6 +10,10 @@ "repositoryUrl": "https://github.com/myProjects/firstMultiBranchJob.git", "repositoryTrigger": "* * * * *", "credentialsId": "myGitCredentialsId" + }, + "logRotator": { + "daysToKeep": null, + "numToKeep": null } }, { @@ -21,6 +25,21 @@ "repositoryUrl": "https://github.com/myProjects/secondMultiBranchJob.git", "repositoryTrigger": "* * * * *", "credentialsId": "myGitCredentialsId" + }, + "logRotator": { + "daysToKeep": 15, + "numToKeep": 10 + } + }, + { + "jobName": "thirdMultiBranchJob", + "jobDescription": "Third job", + "pipelineScriptPath": "Jenkinsfile", + "git": { + "repositoryId": "thirdMultiBranchJob", + "repositoryUrl": "https://github.com/myProjects/thirdMultiBranchJob.git", + "repositoryTrigger": "* * * * *", + "credentialsId": "myGitCredentialsId" } } ], @@ -38,6 +57,10 @@ "repositoryUrl": "https://github.com/myProjects/myPipelineJobProject.git", "repositoryTrigger": "* * * * *", "credentialsId": "myGitCredentialsId" + }, + "logRotator": { + "daysToKeep": 15, + "numToKeep": 10 } } ]