Last active
September 19, 2024 13:48
-
-
Save taherbs/6d03b4d56ac4f1e7a119e64cf5d17f4c to your computer and use it in GitHub Desktop.
jenkins safe auto update plugins
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//List all active plugins and save them into a file | |
def list_jenkins_plugins(directory, fileName) { | |
File pluginsListFile = new File("$directory/$fileName") | |
jenkins.model.Jenkins.instance.pluginManager.activePlugins.findAll { plugin -> | |
pluginsListFile.append("${plugin.getDisplayName()} (${plugin.getShortName()}): ${plugin.getVersion()}" + System.getProperty("line.separator")) | |
} | |
} | |
//Perform jenkins plugin update in a safe manner | |
def jenkins_safe_plugins_update() { | |
//Refresh plugins updates list | |
jenkins.model.Jenkins.getInstanceOrNull().getUpdateCenter().getSites().each { site -> | |
site.updateDirectlyNow(hudson.model.DownloadService.signatureCheck) | |
} | |
hudson.model.DownloadService.Downloadable.all().each { downloadable -> | |
downloadable.updateNow(); | |
} | |
//Get the list of plugins | |
def pluginsToUpdate = [] | |
def pluginsToReviewManually = [] | |
def pluginsDeprecated = [] | |
jenkins.model.Jenkins.instance.pluginManager.activePlugins.findAll { plugin -> | |
if (!(plugin.getDeprecations().isEmpty())) { | |
pluginsDeprecated.add(plugin.getDisplayName()) | |
} else if (plugin.hasUpdate()) { | |
if (plugin.getActiveWarnings().isEmpty()) { | |
pluginsToUpdate.add(plugin.getShortName()) | |
} | |
else { | |
pluginsToReviewManually.add(plugin.getDisplayName()) | |
} | |
} | |
} | |
println "Plugins to upgrade automatically: ${pluginsToUpdate}" | |
println "Plugins to review and update manually: ${pluginsToReviewManually}" | |
println "Plugins depricated: ${pluginsDeprecated}" | |
long count = 0 | |
jenkins.model.Jenkins.instance.pluginManager.install(pluginsToUpdate, false).each { f -> | |
f.get() | |
println "${++count}/${pluginsToUpdate.size()}.." | |
} | |
if(pluginsToUpdate.size() != 0 && count == pluginsToUpdate.size()) { | |
jenkins.model.Jenkins.instance.safeRestart() | |
} | |
return [ pluginsToReviewManually, pluginsDeprecated ] | |
} | |
return this |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def DATETIME = new Date().format('yyyy_MM_dd_HH_mm_ss', TimeZone.getTimeZone('Canada/Eastern')) | |
def pluginsToReviewManually = [] | |
def pluginsDeprecated = [] | |
pipeline { | |
agent { label 'master' } | |
options { | |
//Build options | |
disableConcurrentBuilds() | |
buildDiscarder( | |
logRotator ( | |
artifactDaysToKeepStr: '10', | |
artifactNumToKeepStr: '1', | |
daysToKeepStr: '30', | |
numToKeepStr: '30' | |
) | |
) | |
} | |
triggers { cron('TZ=Canada/Eastern\n0 0 * * 7') } | |
environment { | |
GOOGLE_CHAT_TOKEN = 'XXX-XXX-XXX-XXX' | |
} | |
stages { | |
stage('Update_Plugins') { | |
steps { | |
script { | |
def safePluginUpdateModule = load("${WORKSPACE}/jenkins_auto_update_plugins/jenkins-plugins-uptodate.groovy") | |
safePluginUpdateModule.list_jenkins_plugins("${WORKSPACE}/jenkins_auto_update_plugins", "plugins_list_BEFORE-UPDATE_${DATETIME}.txt") | |
(pluginsToReviewManually, pluginsDeprecated) = safePluginUpdateModule.jenkins_safe_plugins_update() | |
safePluginUpdateModule.list_jenkins_plugins("${WORKSPACE}/jenkins_auto_update_plugins", "plugins_list_AFTER-UPDATE_${DATETIME}.txt") | |
} | |
} | |
} | |
} | |
post { | |
always { | |
script { | |
archiveArtifacts "jenkins_auto_update_plugins/plugins_list_*_${DATETIME}.txt" | |
if (!(pluginsToReviewManually.isEmpty())) { | |
hangoutsNotify message: "IMPORTANT!!! The following plugins need to get reviewed and updated manually: ${pluginsToReviewManually}",token: "${env.GOOGLE_CHAT_TOKEN}",threadByJob: true | |
} else if (!(pluginsDeprecated.isEmpty())) { | |
hangoutsNotify message: "IMPORTANT!!! The following plugins are deprecated and need to be deleted: ${pluginsDeprecated}",token: "${env.GOOGLE_CHAT_TOKEN}",threadByJob: true | |
} | |
} | |
} | |
failure { | |
hangoutsNotify message: "${JOB_BASE_NAME} faild!",token: "${env.GOOGLE_CHAT_TOKEN}",threadByJob: true | |
} | |
} | |
} |
@radnov did not look into that use case for the moment.
@raphperrin I have those 2 checks:
plugin.getActiveWarnings() -> to check if we have warning
plugin.getDeprecations() -> check if the plugin got deprecated
if we hit one of those conditions a notificatation get sent and a manual review is required, I did not find a way to fully automate that part
Thank you for providing this useful script. We use the plugin Script-Security which is complaining all the insecure methods that are used in this script. Do you know any other way to approve script security instead of whitelisting all method calls? Thank you in advice.
Thank you very much for this!!
Here you have the list of signatures used by this script you need to approve:
field hudson.PluginManager activePlugins
method hudson.PluginManager install java.util.Collection boolean
method hudson.PluginWrapper getActiveWarnings
method hudson.PluginWrapper getDeprecations
method hudson.PluginWrapper getShortName
method hudson.PluginWrapper getVersion
method hudson.PluginWrapper hasUpdate
method hudson.model.DownloadService$Downloadable updateNow
method hudson.model.UpdateCenter getSites
method hudson.model.UpdateSite updateDirectlyNow boolean
method java.util.concurrent.Future get
method jenkins.model.Jenkins getPluginManager
method jenkins.model.Jenkins getUpdateCenter
method jenkins.model.Jenkins safeRestart
new java.io.File java.lang.String
staticField hudson.model.DownloadService signatureCheck
staticMethod hudson.model.DownloadService$Downloadable all
staticMethod java.lang.System getProperty java.lang.String
staticMethod jenkins.model.Jenkins getInstance
staticMethod jenkins.model.Jenkins getInstanceOrNull
staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods append java.io.File java.lang.Object
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey @taherbs
By any chance did you implement a compatibility check ? In my case it updated all plugins even the one with warning and "not compatible".