Issue
I have got the jenkins-cli working and able to create an agent. How can I dynamically get the secret key to start up the agent? The launch method is via Java Web Start.
Environment
-
CloudBees Jenkins Enterprise - Managed controller (CJE-MM)
-
CloudBees Jenkins Team (CJT)
-
cURL
Resolution
Only users with a certain level of permissions can retrieve this information:
-
as a Jenkins non-administrator user, a solution is to download the jenkins-agent.jnlp and parse it to get the secret
-
as a Jenkins administrator, a solution is to run a groovy script using the Jenkins CLI or the Jenkins REST API
For Any Jenkins Users
You can download the "jenkins-agent.jnlp" file at $NODE_URL/jenkins-agent.jnlp
. This file actually contains XML content that includes the secret. Here is an example of a JNLP file downloaded from a Jenkins instance at https://cje.example.com/computer/jnlpAgentTest/jenkins-agent.jnlp
- the secret is b8c80148ce36de10c9358384fac9e28fbba941055a9a6ab2277e75ddc29a8744
:
<jnlp codebase="https://cje.example.com/computer/jnlpAgentTest/" spec="1.0+"> <information> <title>Agent for jnlpAgentTest</title> <vendor>Jenkins project</vendor> <homepage href="https://jenkins-ci.org/"/> </information> <security> <all-permissions/> </security> <resources> <j2se version="1.8+"/> <jar href="https://cje.example.com/jnlpJars/remoting.jar"/> </resources> <application-desc main-class="hudson.remoting.jnlp.Main"> <argument>b8c80148ce36de10c9358384fac9e28fbba941055a9a6ab2277e75ddc29a8744</argument> <argument>jnlpAgentTest</argument> <argument>-workDir</argument> <argument>/tmp/jnlpAgenttest</argument> <argument>-internalDir</argument> <argument>remoting</argument> <argument>-url</argument> <argument>https://cje.example.com/</argument> </application-desc> </jnlp>
So the solution would be to download this file for a particular Jenkins node and extract the first argument under <application-desc main-class="hudson.remoting.jnlp.Main">
. This can be done with curl
and sed
:
$ curl -L -s -u $JENKINS_USER:$API_TOKEN -H "Jenkins-Crumb:${JENKINS_CRUMB}" $NODE_URL/jenkins-agent.jnlp | sed "s/.*<application-desc main-class=\"hudson.remoting.jnlp.Main\"><argument>\([a-z0-9]*\).*/\1/"
With the following variables:
Variable | Description |
---|---|
|
A Jenkins user with permissions to view nodes |
|
Password or API token of the Jenkins user |
|
The crumb issued by Jenkins (see CSRF Protection Explained) |
|
The URL of the Node (could be a Node or a Shared Agent |
Here is an example of the output:
$ curl -L -s -u admin:password -H "Jenkins-Crumb:dac7ce5614f8cb32a6ce75153aaf2398" -X GET https://CONTROLLER_URL/computer/jnlpAgentTest/jenkins-agent.jnlp | sed "s/.*<application-desc main-class=\"hudson.remoting.jnlp.Main\"><argument>\([a-z0-9]*\).*/\1/" b8c80148ce36de10c9358384fac9e28fbba941055a9a6ab2277e75ddc29a8744
Other solutions can be used to download the file and / or extract the secret. |
For Jenkins Administrators Only
As a Jenkins administrator, another solution is to use the Jenkins Script Console. The Jenkins CLI or the Jenkins REST API can also be used to execute script remotely.
Jenkins Nodes
To get the secret of a Jenkins Node, the following script can be used:
jenkins.model.Jenkins.getInstance().getComputer("$NODE_NAME").getJnlpMac()
CJOC Shared Agents
To get the secret of a Shared Agent, the following script can be used - in the Jenkins Script Console of the CJOC:
def sharedAgent = Jenkins.getInstance().getItems(com.cloudbees.opscenter.server.model.SharedSlave.class) .find { it.launcher != null && it.launcher.class.name == 'com.cloudbees.opscenter.server.jnlp.slave.JocJnlpSlaveLauncher' && it.name == "shared-dvilladiego"} return sharedAgent?.launcher.getJnlpMac(sharedAgent) }
See also: