Jenkins: Automate CI Docker instance - docker

I'm trying to setup Jenkins to be fully automated once I launch it from a docker container.
My question is how do I automate the configuration of the global Jenkins settings. For example the items in manage jenkins and credentials?
I'm using this a reference:
https://wiki.jenkins.io/display/jenkins/remote+access+api
Currently, I have the set these items up manually. I would like to fully automate the CI server creation. Is this possible with Jenkins or is there some human intervention that is required?
Any help would be greatly appreciated.

we used chef to setup the master , and it run some groovy scripts to install all the plugin and configuration. it almost done fully automatically , beside 1 or 2 plugins that I didn't find the syntax to configure all others works fine.
I installed all the plugins using Jenkins CLI , check yourJenkins/cli/ for reference.
for the general configuration you can install all the tools
import jenkins.model.*
import hudson.model.*
def inst1 = Jenkins.getInstance()
def desc1 = inst1.getDescriptor("hudson.tools.JDKInstaller")
println desc1.doPostCredential('buildJenkins#gmail.com','JenkinsOracleXXXXX')
import jenkins.model.*
import hudson.model.*
import hudson.tools.*
// JDK installation
def inst = Jenkins.getInstance()
def desc = inst.getDescriptor("hudson.model.JDK")
def versions = [
"jdk-1.8.101": "jdk-8u101-oth-JPR",
// "jdk-1.8.102": "jdk-8u102-oth-JPR"
]
general variables
// general properties
instance = Jenkins.getInstance()
globalNodeProperties = instance.getGlobalNodeProperties()
envVarsNodePropertyList = globalNodeProperties.getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class)
newEnvVarsNodeProperty = null
envVars = null
if ( envVarsNodePropertyList == null || envVarsNodePropertyList.size() == 0 ) {
newEnvVarsNodeProperty = new hudson.slaves.EnvironmentVariablesNodeProperty();
globalNodeProperties.add(newEnvVarsNodeProperty)
envVars = newEnvVarsNodeProperty.getEnvVars()
} else {
envVars = envVarsNodePropertyList.get(0).getEnvVars()
}
envVars.put("ARTIFACTORY_URL", "artifactory-url")
envVars.put("ARTIFACTORY_USER", "jenkins")
envVars.put("DOCKER_USER", "docker-push")
instance.save()
email address
// admin Email
def jenkinsLocationConfiguration = JenkinsLocationConfiguration.get()
jenkinsLocationConfiguration.setAdminAddress('admin#yours.com')
jenkinsLocationConfiguration.save()
there a lot of examples , just look for groovy Jenkins configuration ..
if you have any specific question let me know.

Related

How can I add a variable to jenkins during the install on Amazon Linux

I have a variable that I need to add as Jenkins Environment Variable so that the $jenkins_home/init.d groovy scripts can use them. I have this variable set in the host machine(where iam installing jenkins) - Amazon linux EC2 via a .sh file in /etc/profile.d and sourceing the /etc/profile . This did not help as I am not able to access the variable from jenkins. Can anybody please help on how I can achieve this.
In Jenkins, you can setup the global variables using the below given groovy script. You will have to use this in a shell script that you use to provision a jenkins server. This should be executed right after install so that, jenkins can use then while running jobs.
The below given groovy script creates the environment variables one by one,
createGlobalEnvironmentVariables('Var1','DummyValue')
This adds a global variable with name as Var1 and value as DummyValue
If you have multiple values, you can use the ones given below.
envVars.put("Key1", "Value1)
envVars.put("Key2", "Value2)
before calling instance.save(). We have a shell script file that has this and many other functions to install and configure jenkins in a single shot.
import hudson.EnvVars;
import hudson.slaves.EnvironmentVariablesNodeProperty;
import hudson.slaves.NodeProperty;
import hudson.slaves.NodePropertyDescriptor;
import hudson.util.DescribableList;
import jenkins.model.Jenkins;
public createGlobalEnvironmentVariables(String key, String value){
Jenkins instance = Jenkins.getInstance();
DescribableList<NodeProperty<?>, NodePropertyDescriptor> globalNodeProperties = instance.getGlobalNodeProperties();
List<EnvironmentVariablesNodeProperty> envVarsNodePropertyList = globalNodeProperties.getAll(EnvironmentVariablesNodeProperty.class);
EnvironmentVariablesNodeProperty newEnvVarsNodeProperty = null;
EnvVars envVars = null;
if ( envVarsNodePropertyList == null || envVarsNodePropertyList.size() == 0 ) {
newEnvVarsNodeProperty = new hudson.slaves.EnvironmentVariablesNodeProperty();
globalNodeProperties.add(newEnvVarsNodeProperty);
envVars = newEnvVarsNodeProperty.getEnvVars();
} else {
envVars = envVarsNodePropertyList.get(0).getEnvVars();
}
envVars.put(key, value)
instance.save()
}
createGlobalEnvironmentVariables('Var1','DummyValue')

How to get values of env vars by writing groovy script on jenkins script console?

I searched a lot for this problem but couldn't find working solution anywhere. Can anybody please help me out? I want to get already existing env vars value through jenkins script console.
You need to distinguish:
build environment variables:
def myVar = build.getBuildVariables().get('myVar')
system environment variables:
System.getenv('MY_VARIABLE')
If you see
groovy.lang.MissingPropertyException: No such property: manager for class: Script1
Check this answer, and define build first:
import hudson.model.*
def build = Thread.currentThread().executable
def buildNumber = build.number
According to this answer, in order to access env vars from Jenkins script console, do as follows :
import jenkins.model.*;
import hudson.slaves.EnvironmentVariablesNodeProperty;
import hudson.EnvVars;
jenkins = Jenkins.instance;
EnvironmentVariablesNodeProperty prop = jenkins.getGlobalNodeProperties().get(EnvironmentVariablesNodeProperty.class)
EnvVars env = prop.getEnvVars()
def myVariable = env['MY_VAR']
The env vars listed in http://<JENKINS_URL>/env-vars.html are available for each build. In order to access these variables in the Jenkins script console you need to define first the build :
build = Jenkins.instance.getItemByFullName('JOB_NAME').getBuildByNumber(BUILD_NUMBER)
envvars = build.getEnvironment()
envvars.each{envvar ->
println envvar
}

Jenkins - check if specific job is running with hudson classes

I need to check if specific job is running from another job. I dont want use API or plugins. Just bare hudson model.
I already tried some properties of Jenkins.instance.getItemByFullName('folder/job').lastBuild but they either returning whole job status (stable/unstable) or there is no RUNNING results. I even seen that there is a script which finds current running executors. So i dont believe that there is no way of checking running jobs.
https://wiki.jenkins.io/display/JENKINS/Find+builds+currently+running+that+has+been+executing+for+more+than+N+seconds
import com.cloudbees.groovy.cps.NonCPS
import jenkins.model.*
import hudson.model.Result
#NonCPS
def getProject(projectName) {
def project = jenkins.model.Jenkins.instance.getItemByFullName(projectName)
if (!project) {error("Project not found: $projectName")}
return project
}
project = getProject('folder/job')
build = project.lastBuild
def checkStatus2(){
//return Jenkins.instance.getItemByFullName('folder/job').lastBuild.getResult()
return Jenkins.instance.getItemByFullName('folder/job').lastBuild.buildStatusSummary.message
}
stage('check Job A status'){
//def status = checkStatus2()
//echo status
//if(hudson.model.Result.RUNNING.equals(status)){
if(build.#result == hudson.model.Result.NOT_BUILT){
echo "running"
}else{
echo "not running"
}
}
I found a thread which gave me a hint
Jenkins workflow check if job is running or schedulled
So i tried ...
if(Jenkins.instance.getItemByFullName('folder/job').isBuilding())
... and it works.

Automate Jenkins Keycloak plugin with groovy script

i try to 100% automating the deployment of Jenkins with Keycloak plugin with Docker-compose. The objectiv is that we do not want to do anything but run a single command.
To automate Jenkins, I tried to use the Jenkins API but the Groovy script seems to be the best and easiest solution. The problem is that I am not a developper ...
I try something like this, but it's failed at Keycloak conf :
Failed to run script file:/var/jenkins_home/init.groovy.d/init.groovy groovy.lang.GroovyRuntimeException: Could not find matching constructor for: org.jenkinsci.plugins.KeycloakSecurityRealm(java.lang.Boolean)
import jenkins.model.*
import hudson.security.*
import org.jenkinsci.plugins.*
def instance = Jenkins.getInstance()
def env = System.getenv()
def hudsonRealm = new HudsonPrivateSecurityRealm(false)
String password = env.JENKINS_PASSWORD
hudsonRealm.createAccount("admin", password)
instance.setSecurityRealm(hudsonRealm)
instance.save()
def keycloak_realm = new KeycloakSecurityRealm(true)
instance.setSecurityRealm(keycloak_realm)
instance.setAuthorizationStrategy(new FullControlOnceLoggedInAuthorizationStrategy())
instance.save()
In the end, i want to
create an admin user
configure the Keycloak plugin
set the users autorisations.
Thanks you in advance for your help :)
A possibly outdated issue, but I would like to share that I also had problems using Groovy scripts in the init.groovy.d to maintain the configurations in Jenkins, including Keycloak configurations. And the best way to solve it was through a declarative model using the Jenkins Configuration as Code (JCasC) plugin.
Examples:
Keycloak
jenkins:
securityRealm: keycloak
unclassified:
keycloakSecurityRealm:
keycloakJson: |-
{
"realm": "my-realm",
"auth-server-url": "https://my-keycloak-url/auth",
"ssl-required": "all",
"resource": "jenkins",
"public-client": true,
"confidential-port": 0
}
source: https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos/keycloak
Credentials
credentials:
system:
domainCredentials:
- domain:
name: "test.com"
description: "test.com domain"
specifications:
- hostnameSpecification:
includes: "*.test.com"
credentials:
- usernamePassword:
scope: SYSTEM
id: sudo_password
username: root
password: ${SUDO_PASSWORD}
source: https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos/credentials
Following solution works for me.
#!/usr/bin/env groovy
import jenkins.model.Jenkins
import hudson.security.*
import org.jenkinsci.plugins.KeycloakSecurityRealm
Jenkins jenkins = Jenkins.get()
def desc = jenkins.getDescriptor("org.jenkinsci.plugins.KeycloakSecurityRealm")
// JSON based on the keycloak configuration
desc.setKeycloakJson( "{\n" +
" \"realm\": \"myRealm\",\n" +
" \"auth-server-url\": \"https://keycloak/auth/\",\n" +
" \"ssl-required\": \"external\",\n" +
" \"resource\": \"jenkins\",\n" +
" \"public-client\": true,\n" +
" \"confidential-port\": 0\n" +
"}")
desc.save()
jenkins.setSecurityRealm(new KeycloakSecurityRealm())
def strategy = new FullControlOnceLoggedInAuthorizationStrategy()
strategy.setAllowAnonymousRead(false)
jenkins.setAuthorizationStrategy(strategy)
jenkins.save()

Triggering a Job on start up in Jenkins

I am trying to get a new job to run every time my Jenkins restarts. I want to do this through "init.groovy" script. For example let's say if I restart my jenkins server it will execute a job that says "Hello world". And I have to create this job from my init.groovy script.
I have this code so far
import jenkins.model.Jenkins
import org.jenkinsci.plugins.workflow.job.WorkflowJob
WorkflowJob job = Jenkins.instance.createProject(WorkflowJob, 'my-pipeline2')
now I don't know how to configure this job instance without getting into the GUI. I want to add pipeline scripts to it. Like echo "Hello world". And then I want to finally build this job. I want to do all that from this one init.groovy script. I couldn't find any solution to this over internet. So any help is greatly appreciated. Thanks
You could also try the Startup Trigger plugin.
Once installed, go the Job that you want to trigger after startup and in the section 'Build Triggers', check 'Build when Jenkins first starts'
(This question may be old, but hope my answer helps someone)
So I have finally done this with the following groovy script.
#!groovy
import jenkins.model.*
import hudson.security.*
import jenkins.install.*;
import hudson.triggers.SCMTrigger;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
def instance = Jenkins.getInstance()
println "--> creating local user 'admin'"
def hudsonRealm = new HudsonPrivateSecurityRealm(false)
hudsonRealm.createAccount('admin','admin')
instance.setSecurityRealm(hudsonRealm)
def strategy = new FullControlOnceLoggedInAuthorizationStrategy()
instance.setAuthorizationStrategy(strategy)
instance.save()
jenkins = Jenkins.instance;
workflowJob = new WorkflowJob(jenkins, "workflow2");
jobName = "create-dsl-job2";
gitTrigger = new SCMTrigger("* * * * *");
dslProject = new hudson.model.FreeStyleProject(jenkins, jobName);
dslProject.addTrigger(gitTrigger);
jenkins.add(dslProject, jobName);
job = jenkins.getItem(jobName)
builders = job.getBuildersList()
hudson.tasks.Shell newShell = new hudson.tasks.Shell("echo \"Hello\" ")
builders.replace(newShell)
gitTrigger.start(dslProject, true);

Resources