Jenkins: Start remote VM and keep it running - windows

I am trying to get Jenkins to start a virtual machine on a Jenkins slave. The VM itself will then act as a Jenkins slave.
In order to do so I need to boot the VM and keep it running, even after the Jenkins job terminates. I have tried to create a freestyle project which runs a batch script on the slave and checks if the VM is running:
"C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe" -T ws start "D:\VM\MyVM.vmx"
"C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe" list
The second command shows me that the VM is actually up and running, but apparently it directly shuts down again since I can't see the node that corresponds to the VM as online.
The Jenkins Slave agent is installed as a Windows service on the VM's host and logs in as a domain user.
If I switch the first command to
"C:\Program Files (x86)\VMware\VMware Workstation\vmware.exe" -x "D:\VM\MyVM.vmx"
the VM powers on, the node gets connected to Jenkins. This is because somehow the batch script gets stuck after this command and does not terminate, so the VM remains powered on. However, if I log on the host with the same user the Jenkins service uses, I cannot see the VM running.
Ironically, I can in fact power OFF any virtual machine that I have started locally on the host from Jenkins by creating a project with the batch command
"C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe" -T ws stop "D:\VM\MyVM.vmx" soft
So, to summarize:
I want to create a Jenkins job that powers on a VM so I can use it as a slave agent. The VM has to remain powered on even after the job is done, I will shut it down with a different job as needed.
But only the shutdown job is working as intended.

try to start your VM with START command:
START "C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe" -T ws start "D:\VM\MyVM.vmx"

After playing around with VMs and Jenkins today I learned that vmrun works perfectly if the Jenkins slave does not run as a Windows service but is launched via the Java Webstart application.
Besides, one can prevent processes from getting killed by altering the BUILD_ID env. variable since Jenkins is using this variable to track the processes the build launched. So by changing the value of BUILD_ID before spawning processes they won't get killed after the Job finishes.

Related

Starting jenkins Slave agent using Jnlp using Task Scheduler always starts as headless

I am trying to find solution for the jenkins nodes to automatically connect to master in non headleass mode.
Here is what I have done so far
I have written batch script which calls the powershell script. Powershell script has series of commands to start the jenkins slave agent using jnlp.
This batch script is configured in Task Scheduler to run at the startup. The jenkins slave node is connected to master as soon as node starts up.
But execution of GUI test is not visible in the node when the test starts.
When I manually run this batch script from command line, it works fine i.e non headless mode and I can see the execution of GUI test.
I've read few articles about this kind of setup and none worked.
I also wrote a small piece of powershell script to allow a Windows Service to Interact with Desktop. This script runs after the batch script to start jenkins slave agent.
Task scheduler job is configured to Run as Administrator and I login as administrator to see the execution.
Since this batch script is running via Task scheduler I am guessing its running in a different session.
How do I solve it.
Try to put your script into shell:startup.
On a Windows 10 machine with the Jenkins slave under the user you need, press Windows+R (Run...) and type shell:startup and put your script into opened folder. It will run once the user logged in.
This is how you'll see console and any windows it spawns.

Using a Windows VM from Jenkins through vsphere

I'm trying to reset-and-launch a Windows VM (in vsphere) during a Jenkins job. I successfully installed the vSphere Cloud Plugin. I've followed instructions to setup the Windows machine as a jenkins-mvn-slave, and have it setup to run as a service.
If I click on the button in Jenkins for Launch Slave Agent, I can see (in vsphere) that the VM does a revert snapshot, and then it does a power on virtual machine. If I attach to the machine, I can see that the Jenkins service starts automatically. However, back in Jenkins, it tells me that the Slave did not come online in allowed time.
Some key settings for my slave:
Force VM launch: Checked
Wait for VMTools: Not checked
Delay between launch and boot complete: 120
Secondary launch method: Launch slave agents view Java Web Start
Versions:
Jenkins: 1.596.2
vSphere: 5.5.0
Windows: Server 2012 R2 Standard, Build 9600
vSphere plugin: 2.7
What am I missing?
I've done a lot of messing around since I posted, but I think the following is what I was doing wrong. I first got the VM working as a normal slave agent. Once I had that working, then I tried to setup the same as a vsphere-cloud-slave-agent. I wasn't realizing that setting up a host as a slave agent is "agent-name specific".
So, I uninstalled the Jenkins service, launched the "vsphere cloud slave agent", logged into the machine, and ran javaws (as specified in the previously mentioned instructions.
A couple of other gotchas that I encountered (not relevant to the initial post, but maybe relevant to someone who reads this):
I originally installed git with a password manager. Unfortunately, since jenkins jobs aren't interactive, it was hanging on the git clone command. I tried uninstalling and re-installing git, but it didn't fix the problem for whatever user the jenkins slave was running as. I ended up having to revert to a previous slave image and install git from there. (I probably could have also figured out what user was running the jenkins slave, and entered the desired password there.)
I wanted to run a clean VM for each job. I never figured out this one. If I set Availability to Take this slave on-line when in demand and off-line when idle, that was a good start. However, if I set the times to 0 and 0, then the machine was constantly rebooting. If I set the times to 1 and 1, then the machine does mostly what I want, unless there are back-to-back jobs queued to run.

Running a batch file from Jenkins hangs and does not return to the Jenkins job

I am using the "Send files or execute commands over SSH after the build runs" option in my Jenkins job configuration. I am running a .bat file on a remote server. The .bat file is starting an authentication server. The authentication server needs to remain up and running on the remote server.
The authentication server is delivered with a .bat file to start and stop the server. When I run the delivered .bat file my jenkins job hangs and never completes. The delivered .bat file named startAuth.bat looks like this:
call java -jar Auth.jar db migrate Auth.yml
call java -jar Auth.jar server Auth.yml
Based on some end user restrictions, I cannot modify the startAuth.bat file, so I have create another .bat file to call startAuth.bat named runStartAuth.bat. It looks like this:
cd c:\tmp
start runStartAuth.bat
exit /b
My thinking was by using "start" the .bat should be run in a separate process, one that could remain up and running until the next Jenkins job run, and the calling .bat would exit with the exit /b line. Unfortunately, the Jenkins job seems to ignore the exit and just spins and spins.
What am I doing wrong?
I'm not really an expert with Jenkins ... but I think since the slave agent JVM wrapper over your batch file knows that the child process has not yet finished, it will not return control to the executor.
Instead, can you try having the same commands on the Jenkins slave node configuration ? I believe you will have slave launcher prefix command in the Advanced section of the slave node.

Remotely running "vmrun command" on server machine from jenkins

I have windows 7_x64 Virtual Machine on Server machine running on Windows Server 2008 R2. I want to run this VM from jenkins (CI tool which executes batch file, running on same server).
I am using vmrun utility to do so.
When i run
vmrun -T ws -gu *** -gp *** start "vmx file path.vmx"
this executes fine on server command prompt (locally). but when i try to exceute the same from any of the client machine (by visiting jenkins site) I get
Error: There was an error in communication
After some troubleshooting, I can say vmrun command is not responding whenever it is evoked remotely. but it is confusing me, because I have jenkins which is running those commands is installed on same server. i am just running job from thin client. how does that make any difference?
Could anyone help me troubleshooting this issue?
Thanks!
For reference:
*Server machine(host): Windows Server 2008 R2
*Virtual machine(guest): Windows 7 x64
*Jenkins : Installed on same server (host)
*client : remote windows machine, accesses the jenkins instance from browser and triggers the job
*problem/error : vmrun commands dont execute.
Jenkins does not execute anything on "client" (i.e. the machine with the browser from which you accessed Jenkins instance). Jenkins will only execute anything on Master (what you called "server machine") or Slave nodes.
Now, there can be several differences between running the command from your local command prompt (on server) and through Jenkins. The primary difference is that Jenkins runs under a separate session, usually under a separate user, which may have different permissions, however that depends on how you have installed and configured the Jenkins session.
To identify if there are any Environment variable differences, type set on your local command prompt, and then execute Jenkins with just set in the build step. Compare the two. Other than Jenkins specific variables, everything else should be same.
Also, verify that your Jenkins user (the one running the service) has permissions to do whatever your are doing.

start daemon on remote server via Jenkins SSH shell script exits mysteriously

I have a build job on jenkins that is building my project and after it is done, it opens an ssh shell script on a remote server and transfers files and then stop and starts a daemon.
When I stop and start the daemon from the command line on a RHEL server, it executes just fine. When the job executes in jenkins, there are no errors.
The daemon stops fine and it starts fine. But shortly after starting, the daemon dies suddenly.
sudo service daemonName stop
# transfer files.
sudo service daemonName start
I'm sure that the problem isn't pathing
Does anyone know what could be special about the way Jenkins is executing the ssh shell script that would cause the daemon start to not fully complete?
The problem:
When executing a build through jenkins, the command to start the daemon process was clearly successfully executing, yet after the build job was done, the daemon would suddenly quit.
The solution:
I thought for this whole time that it was jenkins killing the daemon. So I tried many different incarnations and permutations of disabling the ProcessTree module that goes through and cleans up zombie child processes. I tried fooling it by resetting the BUILD_ID environment variable. Nothing worked.
Thanks to this thread I found out that that solution only works for child processes executed on the BUILD machine. I.E. not applicable to my problem.
More searching led me here: Run a persistent process via ssh
The solution? Nohup.
So now the build successfully restarts the daemon by executing the following:
sudo nohup service daemonname start
Jenkins watches for processes spawned by the job and kill them to avoid zombie processes.
See https://wiki.jenkins-ci.org/display/JENKINS/ProcessTreeKiller
The workaround is to override the BUILD_ID environment variable:
BUILD_ID=dontKillMe

Resources