Can I tell jenkins agent to execute job under a configured user? - jenkins

I'm training a MacBook to be a jenkins agent for automation testing. On the MacBook, I logged in as user bob and installed everything needed (npm, yarn, xcode etc). Then I connected to a remote master using Java Web Start.
Because I launched the java thing in user bob, I assume jenkins pipeline jobs will also be under bob, which seems true - whoami command in pipeline echos bob. However, all dependencies cannot be found. If I echo $PATH I see a completely different result compared to echo $PATH directly on the MacBook.
I googled a bit, the problem might be that Jenkins create a new shell on everyjob. Can I tell jenkins pipeline to not to do this? I want the pipeline to use everything I configured manually for bob.
EDIT:
The main problem is jenkins pipeline's user has a different PATH. I ended up using environment directives to specify which path to use.
environment {
PATH = "/Users/bappo/.nvm/versions/node/v8.11.3/bin:$PATH"
}

What where you trying to configure? If you have parameters/configuration for your pipeline I strongly recommend to use pipeline parameters. They can either configured manually (including default values) or from the jenkinsfile.
example

Related

Using ssh credentials in post-build of Jenkins matrix job

We have a Jenkins matrix job with "SSH Agent" enabled in "Build Environment" with SSH credentials and a post-build action of "Execute Scripts On Matrix" with a shell command that runs ssh expecting to use the credentials stored by ssh-agent.
We recently upgraded from Jenkins v2.249.3 to v2.263.1 (and potentially upgraded some plugins at the same time, though I don't believe that we upgraded any of the ssh-related ones.) The aforementioned shell command now fails because it no longer has access to the ssh credentials it requires.
Comparing the build logs, we see a new call to ssh-agent -k in the Jenkins v2.263.1 parent job log immediately after the matrix children complete and before "[PostBuildScript] - [INFO] Executing post build scripts." that wasn't present with Jenkins v2.249.3.
It would appear that the agent is being killed before running the post-build operations by Jenkins v2.263.1 whereas it wasn't with Jenkins v2.249.3. I was unable to find a setting that controls this.
I entered JENKINS-64394 for this, but I wasn't really sure which components to label it with which I suspect mean that the right people haven't seen it. Does anyone here have any ideas?

Is there a way we can download archived artifacts in jenkins based on build name (Create a formatted version number)

We are setting up the job to generate executable file by gathering different components (All these tagged) , We need a way to get these components based on the name of the build, I know copy artifacts will do but i would like to put this on script, Is there way (Api or something else) can download archived artifacts? once all these components present it is easy to create a installer
I have tried there are multiple curl and wget commands which accept username and password , But I need something without username and password as script runs on jenkins workspace we dont need to pass the password
If you want to interact with Jenkins via scripts there are two ways:
1. Jenkinspipeline
With Jenkinspipelines you can define the builds with Groovy scripts whereby you can use copyArtifact via the Groovy DSL. Its not actually a script its a build definition defined with a Groovy DSL. This should be the way when a Jenkins Job is gathering stuff from other Jobs.
https://jenkins.io/doc/book/pipeline/
2. Jenkins CLI
With the Jenkins CLI you can interact with Jenkins via a shell script. This should be the way when you want to gather stuff from outside of Jenkins.
https://wiki.jenkins.io/display/JENKINS/Jenkins+CLI
If Jenkins is secured then I think you will have to provide credentials when using the Jenkins CLI. With Jenkinspipelines you don't need credentials, because they are executed in Jenkins. But you need to define permissions on the Jenkins Jobs (or in the Pipelines) so that Jenkins Jobs can access Artifacts of other Jobs. (CopyArtifactPermission)

Is it possible to place a breakpoint inside of a Jenkinsfile for debugging?

Right now sorting out a good workflow using Jenkinsfiles is a bit slow since I have to create a job, and run it from the UI in order to get feedback on whether or not it works.
I was wondering if there was a way to place a breakpoint inside of a Jenkinsfile that way I could toy around and get a feel for the libraries / methods / variables that are available.
Is this something that is possible? Or do I have to stick to my current process of editing a Jenkinsfile in the Jenkins UI and then re-running the build?
--Edit--
I've found a workflow that works a little faster than making changes through the UI. The SSH server within Jenkins exposes a command called declarative-linter and one called replay-pipeline. Now I just develop the script locally and rerun these commands after I make an edit.
So basically, my workflow is like this:
Edit the script to my liking
Run the lint check. I have jenkins setup in my ssh config file, so basically I run this using Powershell:
gc Jenkinsfile | ssh jenkins declarative-linter
Run the newly changed script by replaying a pipeline build:
gc Jenkinsfile | ssh jenkins replay-pipeline <name of my job with branch name>
Run the console command to tail the logs:
ssh jenkins console <name of my job with branch name>
All I did was wrap these lines into a PowerShell function and after I edit the script locally I run one command to perform all this to validate the change. It's definitely more complicated, but the turn around time is a bit faster than it was using the Jenkins UI, plus I get to edit the script using my favorite editor. Hopefully, in the future, there will be better tooling around debugging Jenkinsfiles.
This is the only way currently. Although I know that there requests for future additions in this direction (Pipeline debugger). Probably there are some options to debug this directly from Java, but this is not a trivial setup to be done.
Add an user input
input message: "Continue?"
pipeline input step,
Read interactive input in Jenkins pipeline to a variable

Deploy web app via Jenkins

I have recently started to mess about with Jenkins and am unsure how to deploy my web app to a basic server. I've gotten into the Pipeline (https://jenkins.io/doc/book/pipeline/) and it seems like a fantastic way to work.
Where I'm a bit stuck is in two spots:
Once my repo is in my workspace within Jenkins, how do I prep it so I am only deploying the files necessary for the application? For example, I don't need my src/ directory or my Vagrantfile when I'm deploying things.
How do I deploy my app to the server? I see examples all over the place, but I am getting a bit lost since there seems to be so many ways to do this. I'm assuming scp or something like that...?
To build off of #2, is there a way to deploy web apps as transactions (in one shot) rather than file-by-file?
Please let me know if I can provide any information for potential answers!
I can't speak to your specific use case but a common way to do this is the build-and-deploy model, where you will have 2 Jenkins jobs. The "build" job will check out from source, run build commands such as maven or make, and lastly will "archive" the build artifacts. The latter is an option under the 'post-build actions' tab at the bottom.
In the "deploy" job, you will grab the artifacts of your choice. You can fetch a single file, all of them, and everything in between. This requires use of the 'Copy Artifact' plug-in and it allows you to copy files generated by other jobs. Now you can run your usual deploy script in the 'Execute Command' box. Most command line paradigms are supported out of the box such as setting environment variables.
The instructions above assume that you want to run your application off of a host that you've provisioned as a Jenkins slave.
Use artifacts as mentioned by Paul Back, or a 3rd party artifactory server as in video
This is always tricky and error-prone. Why not spin up a fresh server with new release (humanly verified once)
Jenkins & Ansible is the answer here. This is how I deploy to production, since I am in no need to use anything like Docker (too many issues with particular app) so have to run the app natively. Quick example would be
You monitor a specific branch in gitlab / github or whatever else and then call a webhook on push / merge etc on that branch, at this point you deal with anything you need to do by running a playbook on the jenkins job that monitors that branch (jenkins).
in my case jenkins and ansible run on the same server. Jenkins runs the ansible playbook that does whatever I need to do.
for example with ansible, I copy certain files that need to be there, run configs / change filenames etc. setup nginx, run composer,
you get the point.

Jenkins: how to test the slaves

I am creating a list of Jenkins jobs for sanity test of our Jenkins build environment. I want to create layers of jobs. The first layer of jobs will check the environment, e.g. if all slaves are up, the 2nd layer then can check the integration to other tools such as GitHub, TFS, SonarQube, then the 3rd layer can run some typical build projects. This sanity test can also be used to verify the environment after any major changes to the Jenkins servers.
We have about 10 slaves created on two servers, one Windows and one Linux. I know I can create a job to run on a specific slave, therefore test if the slave is online, but this way I need to create 10 jobs just to test all slaves. Is there a best approach to check if all slaves are online?
One option is to use Jenkins Groovy scripting for a task like this. The Groovy plugin provides the Jenkins Script Console (a useful way to experiment) and the ability to run groovy scripts as build steps. If you're going to use the Script Console for periodic maintenance, you'll also want the Scriptler plugin which allows you to manage the scripts that you run.
From Manage Jenkins -> Script Console, you can write a groovy script that iterates through the slaves and checks whether they are online:
for (node in Jenkins.instance.nodes) {
println "${node.name}, ${node.numExecutors}"
def computer = node.computer
println "Online: ${computer.online}, ${computer.connectTime} (${computer.offlineCauseReason})"
}
Once you have the basic checks worked out, you can create either a standalone script in Scriptler, or a special build to run these checks periodically.
It often takes some iteration to figure out the right set of properties to examine. As I describe in another answer, you can write functions to introspect the objects available to scripting. And so with some trial and error, you can develop a script performs the checks you want to run.

Resources