i have example code below to create user and add user to globalRoles, but in Jenkins RoleBasedAuthorizationStrategy, i want to assign more detail, so i create item roles and grant each role to each folder belong.
Summary, i want to add user to item roles, can anyone help me?
#!/bin/bash
set -e
role=user
user=$1
echo "Create user: $user"
java -jar /var/lib/jenkins/jenkins-cli.jar -auth user***:111************** -s http://localhost:8080/ groovy = <<EOF
jenkins.model.Jenkins.instance.securityRealm.createAccount("$user", "$user")
com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy.getInstance().doAssignRole("globalRoles", "$role", "$user" )
EOF
I run this:
curl "$JENKINS_URL/job/simple_starter/build?token=$TOKEN_NAME"
but I got this message:
Authentication required You are authenticated as: anonymous Groups
that you are in: Permission you need to have (but didn't):
hudson.model.Hudson.Read ... which is implied by:
hudson.security.Permission.GenericRead ... which is implied by:
hudson.model.Hudson.Administer
I figure I can login using something like this:
java -jar jenkins-cli.jar --password x --username y
but how do I pass my creds with the curl command so that I can trigger a Jenkins job manually?
All I had to do was add my Jenkins username/password to the curl command like so:
curl -u "${jenkins_username}:${jenkins_password}" "$JENKINS_URL/xyz"
I have created a jenkins node using jenkins-cli create node command. The node gets created successfully and I could see it in the web interface.
NODE_NAME=$1
LABEL=$2
cat <<EOF | java -jar jenkins-cli.jar -s http://myjenkins/jenkins/ create-node --username userId --password testPwd $1
<?xml version='1.0' encoding='UTF-8'?>
<slave>
<name>${NODE_NAME}</name>
<description></description>
<remoteFS>/Users/jenkins1/Desktop/workspace</remoteFS>
<numExecutors>1</numExecutors>
<mode>EXCLUSIVE</mode>
<retentionStrategy class="hudson.slaves.RetentionStrategy$Always"/>
<launcher class="hudson.plugins.sshslaves.SSHLauncher" plugin="ssh-slaves#1.22">
<host>test</host>
<port>22</port>
<credentialsId>test</credentialsId>
<maxNumRetries>0</maxNumRetries>
<retryWaitTime>0</retryWaitTime>
<sshHostKeyVerificationStrategy class="hudson.plugins.sshslaves.verifiers.KnownHostsFileKeyVerificationStrategy"/>
</launcher>
<label>${LABEL}</label>
<nodeProperties>
<hudson.slaves.EnvironmentVariablesNodeProperty>
<envVars serialization="custom">
<unserializable-parents/>
<tree-map>
<default>
<comparator class="hudson.util.CaseInsensitiveComparator"/>
</default>
<int>1</int>
<string>MVN_REPOS</string>
<string>/Users/jenkins1/Desktop/workspace</string>
</tree-map>
</envVars>
</hudson.slaves.EnvironmentVariablesNodeProperty>
</nodeProperties>
</slave>
EOF
But when I try to get the node after it has been created using jenkins-cli I get no such node error. However, I am able to get the node after saving the configuration through Jenkins UI. Could you please help me to fix this error.
java -jar jenkins-cli.jar -s http://myjenkins/jenkins/ get-node 'tests' --username userId --password testPwd
ERROR: No such node 'tests'
When you create a node or job from the cli, most times you have to return to Jenkins UI and run "Manage Jenkins >> Reload Configuration From Disk", otherwise cli changes sometime remain ineffective. Have you already tried doing this?
#funkfan As I have mentioned in my post, I am able to get the node after saving the configuration through Jenkins UI. I have even tried jenkins-cli reload-configuration command before saving the configuration from the Jenkins UI without any luck.
I am able to create a new node via the Jenkins web GUI and then have the node running in a container connect back to the Jenkins master via the name and -secret value
ex.
docker run jenkinsci/jnlp-slave -url http://jenkins-server:port <secret> <slave name>
Is there a way to programmatically create a Jenkins node and get the secret and slave name so I don't have to do it via the GUI?
Creating an agent programmatically
You can use the create-node CLI command to create new agents with a given configuration.
For example, given this minimal JNLP agent configuration in a file config.xml:
<slave>
<remoteFS>/opt/jenkins</remoteFS>
<numExecutors>2</numExecutors>
<launcher class="hudson.slaves.JNLPLauncher" />
</slave>
you can run the create-node command via the CLI client, or the SSH interface:
cat config.xml | java -jar jenkins-cli.jar -s https://jenkins/ create-node my-agent
Viewing agent configuration
To see what the XML configuration looks like for an existing agent, you can append config.xml to an agent URL, e.g. https://jenkins/computer/some-agent-name/config.xml, or you can use the get-node CLI command.
Fetching the per-agent secret programmatically
To fetch the secret hex value without using the Jenkins web UI, you can run a script via the groovy CLI command:
echo 'println jenkins.model.Jenkins.instance.nodesObject.getNode("my-agent")?.computer?.jnlpMac' \
| java -jar ~/Downloads/jenkins-cli.jar -s https://jenkins/ groovy =
This will return the secret value directly. Note that in order to use the groovy command via the SSH interface, you need Jenkins 2.46 or newer. In earlier versions, it only works via the CLI client.
You can also create an agent using the REST API. This is especially useful when having an apache proxy in front (see issue JENKINS47279) and no direct access to the jenkins otherwise (e.g. in a corporate network) where CLI will not work.
I recommend to create an API token for this purpose. Then you can do something like this
Linux (Bash)
export JENKINS_URL=https://jenkins.intra
export JENKINS_USER=papanito
export JENKINS_API_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx
export NODE_NAME=testnode
export JSON_OBJECT="{ 'name':+'${NODE_NAME}',+'nodeDescription':+'Linux+slave',+'numExecutors':+'5',+'remoteFS':+'/home/jenkins/agent',+'labelString':+'SLAVE-DOCKER+linux',+'mode':+'EXCLUSIVE',+'':+['hudson.slaves.JNLPLauncher',+'hudson.slaves.RetentionStrategy\$Always'],+'launcher':+{'stapler-class':+'hudson.slaves.JNLPLauncher',+'\$class':+'hudson.slaves.JNLPLauncher',+'workDirSettings':+{'disabled':+true,+'workDirPath':+'',+'internalDir':+'remoting',+'failIfWorkDirIsMissing':+false},+'tunnel':+'',+'vmargs':+'-Xmx1024m'},+'retentionStrategy':+{'stapler-class':+'hudson.slaves.RetentionStrategy\$Always',+'\$class':+'hudson.slaves.RetentionStrategy\$Always'},+'nodeProperties':+{'stapler-class-bag':+'true',+'hudson-slaves-EnvironmentVariablesNodeProperty':+{'env':+[{'key':+'JAVA_HOME',+'value':+'/docker-java-home'},+{'key':+'JENKINS_HOME',+'value':+'/home/jenkins'}]},+'hudson-tools-ToolLocationNodeProperty':+{'locations':+[{'key':+'hudson.plugins.git.GitTool\$DescriptorImpl#Default',+'home':+'/usr/bin/git'},+{'key':+'hudson.model.JDK\$DescriptorImpl#JAVA-8',+'home':+'/usr/bin/java'},+{'key':+'hudson.tasks.Maven\$MavenInstallation\$DescriptorImpl#MAVEN-3.5.2',+'home':+'/usr/bin/mvn'}]}}}"
curl -L -s -o /dev/null -v -k -w "%{http_code}" -u "${JENKINS_USER}:${JENKINS_API_TOKEN}" -H "Content-Type:application/x-www-form-urlencoded" -X POST -d "json=${JSON_OBJECT}" "${JENKINS_URL}/computer/doCreateItem?name=${NODE_NAME}&type=hudson.slaves.DumbSlave"
In order to get the agent secret via REST API checkout this, which would look something like this:
curl -L -s -u ${JENKINS_USER}:${JENKINS_API_TOKEN} -X GET ${JENKINS_URL}/computer/${NODE_NAME}/slave-agent.jnlp | sed "s/.*<application-desc main-class=\"hudson.remoting.jnlp.Main\"><argument>\([a-z0-9]*\).*/\1/"
Windows (PS)
And here my solution for Windows using Powershell:
$JENKINS_URL="https://jenkins.intra"
$JENKINS_USER="papanito"
$JENKINS_API_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxx"
$NODE_NAME="testnode-ps"
# https://stackoverflow.com/questions/27951561/use-invoke-webrequest-with-a-username-and-password-for-basic-authentication-on-t
$bytes = [System.Text.Encoding]::ASCII.GetBytes("${JENKINS_USER}:${JENKINS_API_TOKEN}")
$base64 = [System.Convert]::ToBase64String($bytes)
$basicAuthValue = "Basic $base64"
$headers = #{ Authorization = $basicAuthValue; }
$hash=#{
name="${NODE_NAME}";
nodeDescription="Linux slave";
numExecutors="5";
remoteFS="/home/jenkins/agent";
labelString="SLAVE-DOCKER linux";
mode="EXCLUSIVE";
""=#(
"hudson.slaves.JNLPLauncher";
'hudson.slaves.RetentionStrategy$Always'
);
launcher=#{
"stapler-class"="hudson.slaves.JNLPLauncher";
"\$class"="hudson.slaves.JNLPLauncher";
"workDirSettings"=#{
"disabled"="true";
"workDirPath"="";
"internalDir"="remoting";
"failIfWorkDirIsMissing"="false"
};
"tunnel"="";
"vmargs"="-Xmx1024m"
};
"retentionStrategy"=#{
"stapler-class"= 'hudson.slaves.RetentionStrategy$Always';
'$class'= 'hudson.slaves.RetentionStrategy$Always'
};
"nodeProperties"=#{
"stapler-class-bag"= "true";
"hudson-slaves-EnvironmentVariablesNodeProperty"=#{
"env"=#(
#{
"key"="JAVA_HOME";
"value"="/docker-java-home"
};
#{
"key"="JENKINS_HOME";
"value"="/home/jenkins"
}
)
};
"hudson-tools-ToolLocationNodeProperty"=#{
"locations"=#(
#{
"key"= 'hudson.plugins.git.GitTool$DescriptorImpl#Default';
"home"= "/usr/bin/git"
};
#{
"key"= 'hudson.model.JDK\$DescriptorImpl#JAVA-8';
"home"= "/usr/bin/java"
};
#{
"key"= 'hudson.tasks.Maven$MavenInstallation$DescriptorImpl#MAVEN-3.5.2';
"home"= "/usr/bin/mvn"
}
)
}
}
}
#https://stackoverflow.com/questions/17929494/powershell-convertto-json-with-embedded-hashtable
$JSON_OBJECT = $hash | convertto-json -Depth 5
$JSON_OBJECT
Invoke-WebRequest -Headers $headers -ContentType "application/x-www-form-urlencoded" -Method POST -Body "json=${JSON_OBJECT}" -Uri "${JENKINS_URL}/computer/doCreateItem?name=${NODE_NAME}&type=hudson.slaves.DumbSlave"
Just chiming in a bit late to the party here, but I would highly recommend looking at the Jenkins Client plugin instead. Once the plugin is installed, you need only to start the client JAR from the build node and give it the IP address of the master.
As far as the master goes, you don't need to bother configuring anything. Nodes that register with the master are available automatically to start executing jobs. This is much easier than any of the slave.jar-based approaches.
We have an application that we would like to run a script on just like we do in the console window with access to the applications libraries and context, but we need to run it periodically like a cron job.
While the permanent answer is obviously a Quartz job, we need to the do this before we are able to patch the application.
Is there something available that gives us the same environment as the console-plugin but can be run via command-line or without a UI?
you can run a console script like the web interface does but just with a curl like this:
curl -F 'code=
class A {
def name
}
def foo = new A(name: "bar")
println foo.name
' localhost:8080/console/execute
You'll get the response as the console would print below.
With regard to #mwaisgold 's solution above, I made a couple of quick additions that helped. I added a little bit more to the script to handle authentication, plus the -F flag for curl caused an ambiguous method overloading error with the GroovyShell's evaluate method, so I addressed that by using the -d instead:
#/bin/bash
curl -i -H "Content-type: application/x-www-form-urlencoded" -c cookies.txt -X POST localhost:8080/myapp/j_spring_security_check -d "j_username=admin&j_password=admin"
curl -i -b cookies.txt -d 'code=
int iterations = 0
while (iterations < 10) {
log.error "********** Console Cron Test ${iterations++} ***********"
}
log.error "********** Console Cron Test Complete ***********"
' localhost:8080/myapp/console/execute