Jenkins way to generate config files - jenkins

Does Jenkins provide a way to generate per-environment (dev/qa/staging/prod) deployment config files based on some templates using substitution variables? Kind of like template task in Ansible?

No, Jenkins does not provide this itself. There might be some plugin, which actually does this, but Jenkins in general just executes commands. These commands could then call Ansible, some other templating engine or even sed to replace tokens in files.

Related

Jenkins/Groovy move variables out to a config file

I've been asked to move some variable from a Groovy script out into a configuration file. I'm fine using something like :-
readFile('../xx-software.cfg').split('\n').each { fileName ->
sh "wget ${theURL}${fileName}"
}
However, even though I have added xx-software.cfg into the same directory as my Groovy script it does become available for use within that groovy script.
I hope this makes sense!?
How can I move my variables out into a config file to make it easier for the application support team to make future edits without changing the code?
There are a few approaches you could use.
Firstly, file format for the configuration and how to read the data into variables. You could use Java Properties format, YAML or JSON and these are all handled by the Pipeline Utility Steps plugin with steps here. You can read the file with these steps:
readProperties
readYaml
readJSON
Next problem, how to get the file available to your pipeline so it can be read from the workspace using these steps. Possibilities are:
In source control with your pipeline code. It can be fetched with the pipeline.
In a separate source control for configuration, your pipeline will need a step to fetch it.
Use the Jenkins Config File Provider plugin. It has a step to provide a config file managed in Jenkins.
Provide it as a Custom Tool zipped archive from a binary server like Artifactory. You can use custom tool definition pipeline steps to make this available to the pipeline.
The Config File Provider option might provide any easy way to have a file that can be updated, but there won't be any version control of it.

Jenkins environment variables

I am a novice to Jenkins administration, trying to help a friend set up Jenkins for his startup.
I know there are plugins in Jenkins but not quite familiar on how to achieve his requirements.
He has a spring application which uses dispatcher.xml to reference jdbc.properties (one for each environment eg: jdbc_dev, jdbc_test, jdbc_prod.
How do I setup environment variables in Jenkins so the respective jdbc.properties is picked when the war file is built ?
I think following plugins will help your friend a lot.
1) EnvInject Plugin:- To inject environment variables depending on the requirements.
2) Role strategy :- To manage authorization and permissions of various users. For eg: Admin,Tester,Developer,guest.
For more info on configuration on this plugin read this Answer
3) JobConfigHistory Plugin:- To revert changes if you screw anything.
Hope it helps.
See Parameterized Build:
Sometimes, it is useful/necessary to have your builds take several "parameters".
...
The parameters are available as environment parameters variables. So e.g. a shell ($FOO, %FOO%) or Ant (${env.FOO}) can access these values.
[Corrections by me.]
See also the Matrix Project Plugin:
A multi-configuration project is useful for instances where your builds will make many similar build steps, and you would otherwise be duplicating steps.

How to declare a global variable in Jenkins and use it in an MSBuild task within each individual project

I am converting our CI platform from CruiseControl to Jenkins, and can't seem to figure something out that seems like it should be relatively simple to do (Disclaimer - I'm no CI or build automation expert, but this was dumped into my lap and I find it interesting)
In CruiseControl, I am able to declare variables like this:
<cb:define rootdir="J:\SOURCES\" />
<cb:define logdir="J:\SOURCES\buildlogs" />
<cb:define iisdir="J:\IIS\" />
<cb:define artifacts="artifacts\" />
Then use them as part of an MSBuild task
<msbuild>
<executable>C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</executable>
<workingDirectory>$(rootdir)$(ProjectName)</workingDirectory>
<projectFile>$(ProjectName).sln</projectFile>
<buildArgs>/p:BuildDate="1";OutDir="$(iisdir)$(ProjectName)\bin\\";WebProjectOutputDir="$(iisdir)$(ProjectName)\\"</buildArgs>
<targets>Rebuild;$(ProjectName)</targets>
<timeout>180</timeout>
<logger>C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>
If the root or IIS directories change, it can easily be applied to all projects at once. We have ~60 projects setup, so doing this project by project would be very time consuming. Migrating this to Jenkins, the MSBuild command line arguments now look like this (partial sample but includes what is relevant):
OutDir="J:\IIS\ProjectName\bin\\";WebProjectOutputDir="J:\IIS\ProjectName\\"
The IIS directory is hard coded. I need that to be something more like this:
OutDir="${IIS_DIR}\ProjectName\bin\\";WebProjectOutputDir="${ITEM_ROOTDIR}\ProjectName\\"
Is there a way to do that? I tried the configuration slicing plugin, which is useful, but doesn't fit this need from what I see
You can do this with built-in Jenkins' functionality:
Then you need to expand your variable. This, actually, depends on where you would use it.
For example: %MSBuild% and %IIS_DIR% for "Execute windows batch command" build step. Other build steps (and plugins) may use it differently.
For global variables, you need EnvInject plugin. This allows you (among other things) to setup variables at the Global (node) level, at job level or as a step. You can set variables directly, or from properties file, or from scripts.
Once set, the variables are available as environment variables to the rest of Jenkins and its steps (within scope).
For passing arguments to MSBuild, when you configure an MSBuild step, there is an option to pass "Command line arguments" in the format /p:Param=Value.
The "value" could be an environment variable. On Windows environment you would reference it as %myvar%
So, if you configure a global GLOBAL_IIS_DIR=C:\path\to\IIS using EnvInject, you can then reference it on command line with /p:IIS_DIR=%GLOBAL_IIS_DIR%

Jenkins EnvInject from a file which is a Job parameter by itself

I've got a Job Parameter, for example PROPERTIES_FILE.
I want to inject all Env Variables from that file into my job session, using the EnvInject plugin.
Is there a way to do that?
I managed to inject variables
only for a hard coded file path, and not from a parameter.
EnvFile plugin (not EnvInject) seems to support variables in the properties file path (as it uses $WORKSPACE in the example).
Also, if you are on Windows, maybe all you need for EnvInject plugin to work is to use $param for variable, not %param%. While the scripts need %% notation, inside Jenkins still uses $

hudson CI: how to delete all jobs?

I have about 100 jobs on my hudson CI, possible to mass delete them ?
The easiest way, IMHO, would be to use script. Go to http://your.hudson.url/script/
Delete jobs by running:
for(j in hudson.model.Hudson.theInstance.getProjects()) {
j.delete();
}
And this way gives you an option to easily use condition to filter out jobs to delete.
FOR JENKINS
Current versions (2.x):
for(j in jenkins.model.Jenkins.theInstance.getAllItems()) {
j.delete()
}
Older versions:
for(j in jenkins.model.Jenkins.getInstance().getProjects()) {
j.delete();
}
Just delete the job directories:
cd $HUDSON_HOME/jobs
rm -rf <JOB_NAME>
See: Administering Hudson
You can programmatically use the XML api (or use the JSON flavor if you prefer that):
http://your.hudson.url/api/xml?xpath=//job/name&wrapper=jobs
Returns:
<jobs>
<name>firstJob</name>
<name>secondJob</name>
<!-- etc -->
</jobs>
Now iterate over the job names and do a post request to
http://your.hudson.url/job/your.job.name/doDelete
(You can do this with any programming language you like that supports XML and HTTP)
I had similar manageability problems with a Hudson instance that was running 500+ build jobs - it was impractical to manually maintain that many jobs using the gui. However, you can provision jobs in Hudson remotely and programatically by using the CLI - which is supplied as a jar file [http://wiki.hudson-ci.org/display/HUDSON/Hudson+CLI].
The command to delete a job would be something like:
**java -jar hudson-cli.jar -s http://host:port/ delete-job jobname**
And the rest of the commands you will need are here:
**java -jar hudson-cli.jar -s http://host:port/** help
I wrapped the cli in python and created an XML file from which to hold the build configuration - then I could use this to manipulate my running instances of Hudson. This also provided the ability to 'reset' the CI instance back to a known configuration - handy if you suspect build failures were caused by manual changes in the UI or if you are using a different CI server for each environment you deploy to (ie dev, test, prod) and need to provision a new one.
This has also got me out of a few binds when badly written plugins have mangled Hudson's own XML and I've needed to rebuild my instances. Hudson is also I/O bound and for really loaded instances it is often faster to boot Hudson from scratch and populate it's configuration this way.

Resources