Jenkins2.0 pipeline script reject date arithmetic - jenkins

I have the following code in groovy Jenkinsfile:
def current = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss.SSSZ').parse(currenttime.trim())
println current
def end_date = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss.SSSZ').parse(scheduled_end_date.trim())
println end_date
schedule_grace_period_validity = current - end_date > 5 ? false : true
the output for this is :
Tue Feb 27 13:20:54 EST 2018
[Pipeline] echo
Mon Dec 18 18:00:00 EST 2017
[Pipeline] echo
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod org.codehaus.groovy.runtime.DateGroovyMethods minus java.util.Date java.util.Date
This works just fine in my local box but in sandbox mode in Jenkins, this fails and I can't turn off the sandbox mode in Jenkins.
IS there any workaround for this ?

The simplest way is to go to /scriptApproval/ page in your Jenkins instance and approve the signature. When you get this exception after running your script you will see something like this in the script approval page:
Just click Approve and run your script again.
Alternatively you could try calculating difference between two dates in days as:
int diff = BigDecimal.valueOf((current.time - end_date.time) / 86400000).setScale(0, java.math.RoundingMode.UP).intValue()
but in this case you may also run into RejectedAccessException. I tried to run it in Groovy sandbox in my local Jenkins instance and I got this:
[Pipeline] End of Pipeline
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method java.util.Date getTime
at org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.StaticWhitelist.rejectMethod(StaticWhitelist.java:175)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor$6.reject(SandboxInterceptor.java:261)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:381)
at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:284)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checke

Related

Can I schedule a build for onetime run in Jenkins ? Any solution without cron

I don't need cron job because the build is needed to run only once in production and not periodically.Is there a way to build the pipeline at a scheduled time without cron.
You can schedule a build using Groovy via script console or job using: scheduleBuild2:
def waittime = 100 // in secs
def jobName = 'folder/jobname' //aka it.fullName
Jenkins.instance.getItemByFullName(jobName).scheduleBuild2(waittime)
quietPeriod - seconds to wait before starting (normally 0)
public QueueTaskFuture<R> scheduleBuild2(int quietPeriod, Action... actions)
Description copied from interface:
ParameterizedJobMixIn.ParameterizedJob Provides a standard
implementation of SCMTriggerItem.scheduleBuild2(int,
hudson.model.Action...) to schedule a build with the ability to wait
for its result. That job method is often used during functional tests
(JenkinsRule.assertBuildStatusSuccess).
Specified by: scheduleBuild2 in interface
ParameterizedJobMixIn.ParameterizedJob<P extends
AbstractProject<P,R>,R extends AbstractBuild<P,R>> Parameters:
quietPeriod - seconds to wait before starting (normally 0) actions -
various actions to associate with the scheduling, such as
ParametersAction or CauseAction Returns: a handle by which you may
wait for the build to complete (or just start); or null if the build
was not actually scheduled for some reason
One way to do is - You can trigger it remotely
https://www.jenkins.io/doc/book/using/remote-access-api/
Let's say you got a Linux box, you can schedule it by using the "at" command
at 9:30 PM Fri
curl -X POST JENKINS_URL/job/JOB_NAME/build \
--data token=TOKEN \
--data-urlencode json='{"parameter": [{"name":"id", "value":"123"},\
{"name":"verbosity", "value":"high"}]}'
job 2 at Fri Jan 29 21:30:00 2016
Then look at it with
at -c 2

Jenkins - Writing variable to log file

Running my jenkins pipeline I am able to have it output the commit message correctly using
gitnotes = sh ("git log -1 --pretty=%h%x09%an%x09%ad%x09%s")
8c65c33 NAME HERE Tue Nov 13 16:30:00 2018 -0500 Adjusted search/reset buttons' size in dashboard panel
However I now want to store those commit notes to a log file, but even when I use an echo it comes back as null.
echo "${gitnotes}"
I might be losing my mind, but how would I go about writing the above notes to a log file? I'm having a super bad day apparently as this is something I am just not looking at correctly.
Try setting returnStdout: true
Eg: gitnotes = sh script: "git log -1 --pretty=%h%x09%an%x09%ad%x09%s" , returnStdout: true

Jenkins pipelines Jenkins.instance.getItemByFullName

I'm having problems with my Jenkinsfile.
I want to list all running workers in current job, but jenkins just fails without printing any error. Code snippet:
#NonCPS
def check_running_process() {
// Check if PR build already in progress to kill old one
def pull_id = env.ghprbPullId.toInteger()
println pull_id
def current_build_id = env.BUILD_ID.toInteger()
println current_build_id
def currentJob = Jenkins.instance.getItemByFullName('jobname')
println currentJob
}
Output:
[Pipeline] echo
2
[Pipeline] echo
47
So Jenkins stops at def currentJob = Jenkins.instance.getItemByFullName('jobname')
There is no error produced, just a build fail.
There are no errors in jenkins.log file.
This works in scripting console.
Did anyone had the same problem?
Thank you
Okay, this was my problem.
I was calling check_running_process() inside try handler.
This produced no error, but failed because
method jenkins.model.Jenkins getItemByFullName java.lang.String
signature was not approved
(nor it produced script approval request).

Jenkins exclude days from scheduled

How can I exclude specific days from a Jenkins scheduld?
For example: every 5 minutes from 7 to 17 and from monday to friday.
H/05 7-17 * * 1-5
But, if the day of the week is a public holiday, it should not run. How can I configure this?
Thx
Currently Jenkins crontab does not support a complicate logic such public holidays exclusion. However, there are some options out there you can use to accomplish that:
First
For my project I create my own holiday database, which it is a file containing the days I want to exclude eg.:
# /path/to/holidays
# New Year's Day
01-01-2017
# Christmas
12-25-2017
and I check it using a Jenkins shell script, as it was proposed here.
For example for the above file format:
#!/bin/bash
TODAY="`date +%m-%d-%Y`"
if grep -q $TODAY /path/to/holidays; then
echo Skipping holiday for $*
exit 0
fi
$*
Second
A more robust solution but more complicate is to create your own plugin based on the
Run Condition Example Plugin in which you exclude the public holidays of your Country such as this plugin.
There is another option now, with the Jenkins Working Hours Plugin.
Using the plugin, you can configure both working hours:
Or Holidays as 'Excluded Days':
The working hours plugin allows you to set up a schedule of allowable build times; projects can opt in to use the schedule to prevent them from running outside of configured allowable build times. If a build is scheduled during non-working hours then it is kept in the build queue until the next allowable time.
Jobs opt in via the enforceBuildSchedule job parameter, which is provided by this plugin. It can optionally take in a branches parameter to limit it's usage to only those branches. This only works in MultiBranchPipelines.
Usage
Sample job (scripted pipeline):
node {
properties([enforceBuildSchedule()])
stage('Do some stuff') {
echo 'this can wait til morning'
}
}
Sample job (declarative pipeline):
pipeline {
agent any
options {
enforceBuildSchedule()
}
stages {
stage('Do some stuff') {
steps {
echo 'this can wait til morning'
}
}
}
}
Sample job with branches parameter (works in both declarative and scripted):
node {
properties([enforceBuildSchedule(branches: ['dev', 'qa', 'prod')])
stage('Do some stuff') {
echo 'this can wait til morning'
}
}
Using the idea of one of the answers and using Declarative + Script block I created this:
stage('Check if Today is Holiday') {
steps {
// Based on idea from https://stackoverflow.com/a/41219757/7820857
script {
IS_HOLIDAY = sh(script: 'grep -q $(date +%Y-%m-%d) /etc/holidays', returnStatus: true)
if (IS_HOLIDAY == 0) {
currentBuild.result = 'ABORTED'
error ('Today is Holiday according to the file /etc/holidays inside the Jenkins server')
}
}
}
}
This will depend on the file /etc/holidays inside the Jenkins server. Adding this additional Stage before will help you to identify if the day mentioned is holiday and exit with error message, or not and continue with the rest of the stages.
I will like that the Working Hours Plugin worked for this but they queue the jobs in case that the day is inside the Excluded days, but I need to cancel the job execution. A feature request exist for that user case.

How to set the output of sh to a Groovy variable? [duplicate]

This question already has answers here:
Is it possible to capture the stdout from the sh DSL command in the pipeline
(7 answers)
Closed 6 years ago.
Is it possible to have the output of the sh command be set to a Groovy variable? It seems to be setting it to the status of the command instead.
Example input:
node {
stage "Current Date"
def curDate = sh "date"
echo "The current date is ${curDate}"
}
Results in the following output:
Entering stage Current Date
Proceeding
[Pipeline] sh
[workspace] Running shell script
+ date
Tue May 10 01:15:05 UTC 2016
[Pipeline] echo
The current date is 0
It is showing The current date is 0, I want it to show The current date is Tue May 10 01:15:05 UTC 2016 which you can see has been output by the sh command. Am I going about this all wrong?
Yes, sh is returning the exit status. Currently your best bet is:
sh 'date > outFile'
curDate = readFile 'outFile'
echo "The current date is ${curDate}"
ADDENDUM: after this answer was written a new option was added to the sh step, use returnStdout: true to get the result string from the sh call.

Resources