Date post: | 22-Mar-2017 |
Category: |
Technology |
Upload: | julien-pivotto |
View: | 773 times |
Download: | 4 times |
State of the Jenkins Automation
Julien Pivotto (@roidelapluie)
Floss Spring 2017
Manchester - March 15, 2017
whoamiJulien "roidelapluie" Pivotto
@roidelapluie
Sysadmin at Inuits
Automation, monitoring, HA
Jenkins user for 5+ years
inuits
JenkinsOpen Souce CI Server
Written in Java
First release in 2011
Fork of Hudson (2005)
What can you do with Jenkins?Testing, building, deploying software
Testing, building, deploying services
Testing, building, deploying infra (IaC)
Mission CriticalPublic Domain https://commons.wikimedia.org/wiki/File:Roaddamage59quake.JPG
Automating JenkinsCreative Commons Attribution-ShareAlike 2.0 https://www.flickr.com/photos/machu/3131057286
Why is it hard?For long, Jenkins has been UI-Driven
It is "easy" to deploy (.war file)
It has lots of plugins (and you need them)
Why is it needed?Security (high value target)
Bugfixes
Plugins
XML everywhere!Creative Commons Attribution 2.0 https://www.flickr.com/photos/generated/6035308729
Lot of things to automateJenkins Service
Jenkins configuration: security, plugins
Jenkins "data": Jobs/Views
Inside the jobs
Jenkins nodes
Automating the serviceCC0 Public Domain https://pixabay.com/en/butler-tray-beverages-wine-964007/
Automating the Jenkins ServiceChef: Jenkins in the supermarket
Puppet: module rtyler/jenkins
Playbooks/etc for other tools as well
Docker
Jenkins Master in DockerJenkins upstream images: alpine/ubuntu
Please no executors on master
How do you deploy the container?
Pipeline to build&upgrade it
Jenkins PluginsFetched from https://updates.jenkins-ci.org
Can be installed from the UI :(
Can be installed from the CLI
Packaging Jenkins PluginsPlugins have dependencies (against plugins &Jenkins core)
They have a fixed download path
They are listed in updates.jenkins.io/update-center.json
https://github.com/roidelapluie/Jenkins-Plugins-RPM
Mirroring Jenkins PluginsMirror http://updates.jenkins-ci.org
By default, "latest" will be fetched
Don't cache too much
github.com/jenkinsci/docker install-plugins.sh
Global configurationCC0 Public Domain https://commons.wikimedia.org/wiki/File:Waiting_room_bell.jpg
Modifying XML files
DON'T
system-config-dsl-pluginLike Job DSL, but for the system
https://github.com/jenkinsci/system-config-dsl-plugin
JENKINS-31094
Downside: it does not exist yet
Creative Commons Attribution-Share Alike 3.0https://commons.wikimedia.org/wiki/File:Groovy-logo.svg
GroovyYet another language to learn? yes.
Programming language for the Java platform
Scripting language
Fully integrated in Jenkins
Used by automation tools (chef cookbook,puppet module...)
The Jenkins Script ConsoleA groovy console is available at /script
http://jenkins.example.com/script
also with curl
Requires "Overall/Run Scripts" permission
Sample Groovy scriptsCreative Commons Attribution-Share Alike 2.0
https://www.flickr.com/photos/bjornb/88101376
Set number of executorsimport jenkins.model.Jenkins;Jenkins.instance.setNumExecutors(0)
Set HTML formatterimport jenkins.model.Jenkins;import hudson.markup.RawHtmlMarkupFormatter;
Jenkins.instance.setMarkupFormatter(new RawHtmlMarkupFormatter(false));
Set system messageimport jenkins.model.Jenkins;Jenkins.instance.setSystemMessage("""Welcome to <em>Jenkins</em>.""");
Configure simple-themeimport jenkins.model.Jenkins;
def simpleThemePlugin = \ Jenkins.instance.getDescriptor( "org.codefirst.SimpleThemeDecorator") simpleThemePlugin.cssUrl = \ "/userContent/example.css"simpleThemePlugin.save()
Everything in $JENKINS_HOME/userContentis served under /userContent
Emailimport jenkins.model.Jenkinsdef desc = Jenkins.instance.getDescriptor( "hudson.tasks.Mailer")desc.setSmtpHost("172.17.0.1")desc.save()
Disable usage statisticsimport hudson.model.UsageStatistics;hudson.model.UsageStatistics.DISABLED = true;
But also...Setup Authorization/Authentication
Setup prefix url
Setup slaves, clouds
Setup global libraries
Setup credentials
Setup first jobs
Bonusimport org.jenkinsci.plugins.pipeline.utility.steps.shaded.org.yaml.snakeyaml.YamlYaml reader = new Yaml()Map config = reader.load(text)
Thanks to pipeline utility step (readYaml()step), you can easily read yaml files
Scripts sourceshttps://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console
https://github.com/jenkinsci/jenkins-scripts/tree/master/scriptler
https://github.com/infOpen/ansible-role-jenkins/tree/master/files/groovy_scripts
https://github.com/samrocketman/jenkins-bootstrap-jervis/tree/master/scripts
https://github.com/jenkinsci/puppet-
jenkins/blob/master/files/puppet_helper.groovy
http://pghalliday.com/jenkins/groovy/sonar/chef/configuration/management/2014
/09/21/some-useful-jenkins-groovy-scripts.html
Jenkins Javadocshttps://jenkins.io/doc/developer/guides/
http://javadoc.jenkins.io/archive/jenkins-2.32/
http://javadoc.jenkins.io/
http://javadoc.jenkins.io/plugin/gerrit-trigger/
Now what?Creative Commons Attribution 2.0 https://www.flickr.com/photos/51029297@N00/5275403364
Jenkins init.groovy.dUpon startup, Jenkins will run $JENKINS_HOME/init.groovy.d/*.groovy
scripts
Meanwhile, "Jenkins is getting ready..."message is displayed
Drop files, restart Jenkins
Allows you to preconfigure everything --without the GUI
init.groovy.d directorybehaviour
Scripts executed sequentally (alphanumorder)
Scripts that throws exceptions make startupfail
Inside Jenkins
The Multiple ApproachesGUI .. but this talk is about automation, right?
init.groovy.d: to create your seed job
Jenkins Job Builder: declarative, python, yaml
Jenkins Job DSL: imperative, groovy
Jenkins Job BuilderAn Openstack Project
Python (not a Jenkins Plugin!)
Support templates
Extensible
Can do raw xml
Limited support for plugins and pipeline
Put Jobs config under SCM
init.groovy.ddef jobManagement = new JenkinsJobManagement( System.out, [:], new File('.'))
new DslScriptLoader(jobManagement).runScript("""folder('jenkins') displayName('Jenkins')pipelineJob("jenkins/seed") definition cpsScm scm git remote credentials('jenkinsgitna') url('git.example.com/seed.git') branches('master') scriptPath('Jenkinsfile') """)
Jenkins Job DSLA Jenkins Plugin
2012
Groovy DSL to create views & jobs
Put Jobs config under SCM
Creative Commons Attribution-Share Alike 3.0https://commons.wikimedia.org/wiki/File:Groovy-logo.svg
Job DSL supportLarge community of users
Lots of plugins supported
Create a jobjob('test') scm git('git://example.com/foo.git' 'master') steps shell('make test')
Create a Pipeline jobpipelineJob('test') definition cps script(buildScript)
Set job propertiespipelineJob('test') description('Test Build') parameters booleanParam('verbose', false, 'Be Verbose') logRotator numToKeep(10)
Read yamlimport org.jenkinsci.plugins.pipeline.utility.steps.shaded.org.yaml.snakeyaml.YamlYaml reader = new Yaml()Map config = reader.load( readFileFromWorkspace('cfg.yaml')
Just like in init.groovy.d scripts
readFileFromWorkspace()
Loopsconfig.each() jobConfig > pipelineJob(jobConfig.name) triggers if (jobConfig.triggers?.scm) scm(jobConfig.triggers.scm)
Create a viewlistView('Project A') recurse() jobs regex('myprj/[/]+') columns status() weather() name() lastSuccess() lastFailure() lastDuration() lastBuildConsole() buildButton() progressBar()
Work with pluginsbuildMonitorView("OnScreen Status") jobs name('WatchA')
$JENKINS_URL/plugin/job-dsl/api-viewer/
In PipelinejobDsl removedJobAction: 'DELETE', removedViewAction: 'DELETE', targets: 'seeds/*.groovy'
Load extra librariesjobDsl additionalClasspath: 'src/*.jar', removedJobAction: 'DELETE', removedViewAction: 'DELETE', targets: 'seeds/*.groovy'
Jenkins PipelineCreative Commons Attribution 2.0 https://www.flickr.com/photos/amerune/9294639633
Jenkins PipelineJenkins Jobs as Code
"Jenkins file"
Imperative (aka scripted) Pipeline
Declarative Pipeline (2017)
What is a Jenkinsfile (akaPipeline)
A file that contains the definition of a job
No need of Gui
Defines Steps, Reports, Environments,Nodes,...
Plugins can provide steps
Generic "step"
How to write Pipelines?Visual Pipeline editor (WIP)
"Pipeline Syntax" link in jobs
Scriped pipelinenode ("Ubuntu && amd64") stage('checkout') checkout scm stage('build') sh 'make' stage('test') sh 'make test'
Real World Scripted Pipelinenode ("Ubuntu && amd64") checkout scm
stage('build') try sh 'make' catch(err) currentBuild.result = 'UNSTABLE' publishArtifacts('err.log') throw err stage('test') sh 'make test' step([$class: 'JavadocArchiver', javadocDir: "target/site", keepAll: true])
Declarative Pipeline (1/2)pipeline agent label("Ubuntu && amd64") options timeout(time: 235, unit: 'MINUTES') timestamps() ansiColor('xterm') stages stage('build') steps sh('make')
Declarative Pipeline (2/2)pipeline post always junit params.jUnitReports
Declarative vs scriptedDeclarative checkout code by default
Declarative get a workspace "OOTB"
Declarative enforces everything in stages
Declarative allow Pipeline-wide wrappers (e.gansiColor, timestamps)
Going further with PipelineGlobal Libraries Plugins
Job DSL Plugin
Jenkins NodesCC0 Public Domain https://www.flickr.com/photos/133259498@N05/27077266322/
Docker Docker DockerRun jobs inside containers
Clean, short lived containers
Easy to update
Docker Plugin
Docker nodes patternBuild Container
Tag it with a tag "candidate"
Push it to your registry
Run normal testing
Run actual builds with that "candidate"
If success -> tag with "release" && push
In practiceDocker Plugin config automated with groovy
Candidate and Release tags are setup asslaves
They get two labels: "image" "tag" (e.g. "build-centos-7" "candidate")
Jobs get a parameter "tag"
In the build Jenkinsfilepipeline agent label("buildcentos7 && $params.tag")
In the docker-build JenkinsfiledockerImage = docker.build("buildcentos7", "nocache")dockerImage.tag('candidate')docker.withRegistry(url, credentials) dockerImage.push('candidate')
node("buildcentos7 && candidate") sh('testscript')build job: 'myjob', parameters: [string(name:'tag', value:'candidate')] dockerImage.tag('release')docker.withRegistry(url, credentials) dockerImage.push('release')
Pros/ConsUpdated containers won't block the builds (e.gon packages updates)
Containers stay up to date
Don't forget that builds release artifacts(sometime you don't want that in nodes tests)
ConclusionPublic Domain https://commons.wikimedia.org/wiki/File:YellowOnions.jpg
Jenkins can be FULLYautomated
My recommendations:
init.groovy.d
Jenkins Job DSL
Pipeline
You can go furtherI am happy to talk about:
Jenkins master in Docker container
BlueOcean
... I use that but did not fit in this timeslot