diff options
author | Bjørn Forsman <bjorn.forsman@gmail.com> | 2015-10-08 22:15:15 +0200 |
---|---|---|
committer | Bjørn Forsman <bjorn.forsman@gmail.com> | 2015-11-03 16:32:31 +0100 |
commit | 27f41d8c0afd2e1380bbab4eea45a16f9345f90c (patch) | |
tree | ffe2f8d26407ca85dd5f5f677c6f5d2404c0253b /nixos/modules/services/continuous-integration/jenkins | |
parent | a487b3326b3eb31c6fbd38ddd394932031ad000e (diff) | |
download | nixlib-27f41d8c0afd2e1380bbab4eea45a16f9345f90c.tar nixlib-27f41d8c0afd2e1380bbab4eea45a16f9345f90c.tar.gz nixlib-27f41d8c0afd2e1380bbab4eea45a16f9345f90c.tar.bz2 nixlib-27f41d8c0afd2e1380bbab4eea45a16f9345f90c.tar.lz nixlib-27f41d8c0afd2e1380bbab4eea45a16f9345f90c.tar.xz nixlib-27f41d8c0afd2e1380bbab4eea45a16f9345f90c.tar.zst nixlib-27f41d8c0afd2e1380bbab4eea45a16f9345f90c.zip |
nixos: add services.jenkins.jobBuilder option
This option allows to define (declarative) Jenkins jobs, using Jenkins Job Builder (JJB) as backend. Example: services.jenkins = { enable = true; jobBuilder = { enable = true; yamlJobs = '' - job: name: jenkins-job-test builders: - shell: echo 'Hello world!' ''; }; }; Jobs can be defined using YAML, JSON and Nix. Note that it really is declarative configuration; if you remove a previously defined job, the module will remove the jobdir under $JENKINS_HOME. Jobs managed through the Jenkins WebUI (or by other means) are not touched by this module. Changes v1 -> v2: * add nixJobs * let jsonJobs take a list of strings (allows merge) * 4 space indent in shell code
Diffstat (limited to 'nixos/modules/services/continuous-integration/jenkins')
-rw-r--r-- | nixos/modules/services/continuous-integration/jenkins/job-builder.nix | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/nixos/modules/services/continuous-integration/jenkins/job-builder.nix b/nixos/modules/services/continuous-integration/jenkins/job-builder.nix new file mode 100644 index 000000000000..ec15a6a3d706 --- /dev/null +++ b/nixos/modules/services/continuous-integration/jenkins/job-builder.nix @@ -0,0 +1,155 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + jenkinsCfg = config.services.jenkins; + cfg = config.services.jenkins.jobBuilder; + +in { + options = { + services.jenkins.jobBuilder = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether or not to enable the Jenkins Job Builder (JJB) service. It + allows defining jobs for Jenkins in a declarative manner. + + Jobs managed through the Jenkins WebUI (or by other means) are left + unchanged. + + Note that it really is declarative configuration; if you remove a + previously defined job, the corresponding job directory will be + deleted. + + Please see the Jenkins Job Builder documentation for more info: + <link xlink:href="http://docs.openstack.org/infra/jenkins-job-builder/"> + http://docs.openstack.org/infra/jenkins-job-builder/</link> + ''; + }; + + yamlJobs = mkOption { + default = ""; + type = types.lines; + example = '' + - job: + name: jenkins-job-test-1 + builders: + - shell: echo 'Hello world!' + ''; + description = '' + Job descriptions for Jenkins Job Builder in YAML format. + ''; + }; + + jsonJobs = mkOption { + default = [ ]; + type = types.listOf types.str; + example = literalExample '' + [ + ''' + [ { "job": + { "name": "jenkins-job-test-2", + "builders": [ "shell": "echo 'Hello world!'" ] + } + } + ] + ''' + ] + ''; + description = '' + Job descriptions for Jenkins Job Builder in JSON format. + ''; + }; + + nixJobs = mkOption { + default = [ ]; + type = types.listOf types.attrs; + example = literalExample '' + [ { job = + { name = "jenkins-job-test-3"; + builders = [ + { shell = "echo 'Hello world!'"; } + ]; + }; + } + ]; + ''; + description = '' + Job descriptions for Jenkins Job Builder in Nix format. + + This is a trivial wrapper around jsonJobs, using builtins.toJSON + behind the scene. + ''; + }; + }; + }; + + config = mkIf (jenkinsCfg.enable && cfg.enable) { + systemd.services.jenkins-job-builder = { + description = "Jenkins Job Builder Service"; + # JJB can run either before or after jenkins. We chose after, so we can + # always use curl to notify (running) jenkins to reload its config. + after = [ "jenkins.service" ]; + wantedBy = [ "multi-user.target" ]; + + path = with pkgs; [ jenkins-job-builder curl ]; + + # Q: Why manipulate files directly instead of using "jenkins-jobs upload [...]"? + # A: Because this module is for administering a local jenkins install, + # and using local file copy allows us to not worry about + # authentication. + script = + let + yamlJobsFile = builtins.toFile "jobs.yaml" cfg.yamlJobs; + jsonJobsFiles = + map (x: (builtins.toFile "jobs.json" x)) + (cfg.jsonJobs ++ [(builtins.toJSON cfg.nixJobs)]); + jobBuilderOutputDir = "/run/jenkins-job-builder/output"; + # Stamp file is placed in $JENKINS_HOME/jobs/$JOB_NAME/ to indicate + # ownership. Enables tracking and removal of stale jobs. + ownerStamp = ".config-xml-managed-by-nixos-jenkins-job-builder"; + in + '' + rm -rf ${jobBuilderOutputDir} + cur_decl_jobs=/run/jenkins-job-builder/declarative-jobs + rm -f "$cur_decl_jobs" + + # Create / update jobs + mkdir -p ${jobBuilderOutputDir} + for inputFile in ${yamlJobsFile} ${concatStringsSep " " jsonJobsFiles}; do + HOME="${jenkinsCfg.home}" "${pkgs.jenkins-job-builder}/bin/jenkins-jobs" --ignore-cache test -o "${jobBuilderOutputDir}" "$inputFile" + done + + for file in "${jobBuilderOutputDir}/"*; do + test -f "$file" || continue + jobname="$(basename $file)" + jobdir="${jenkinsCfg.home}/jobs/$jobname" + echo "Creating / updating job \"$jobname\"" + mkdir -p "$jobdir" + touch "$jobdir/${ownerStamp}" + cp "$file" "$jobdir/config.xml" + echo "$jobname" >> "$cur_decl_jobs" + done + + # Remove stale jobs + for file in "${jenkinsCfg.home}"/jobs/*/${ownerStamp}; do + test -f "$file" || continue + jobdir="$(dirname $file)" + jobname="$(basename "$jobdir")" + grep --quiet --line-regexp "$jobname" "$cur_decl_jobs" 2>/dev/null && continue + echo "Deleting stale job \"$jobname\"" + rm -rf "$jobdir" + done + + echo "Asking Jenkins to reload config" + curl --silent -X POST http://localhost:${toString jenkinsCfg.port}/reload + ''; + serviceConfig = { + User = jenkinsCfg.user; + RuntimeDirectory = "jenkins-job-builder"; + }; + }; + }; +} |