2

I have a jenkins master and a separate slave server. I using swarm plugin to connect the slaves to the master. Everything works fine before I configured LDAP authetication and revoke the grants from the anonymous user.

enter image description here Obviously now I have to autheticate swarm client but I cannot able to do this. If anyone has experience with swarm plugin please let me know.

Console from slave machine:

$ java -jar swarm-client-2-0.jar -master http://x.x.x.x:8080/ -username 'exxxx' -password common.pwd
Discovering Jenkins master
Oct 01, 2015 2:14:51 PM org.apache.commons.httpclient.auth.AuthChallengeProcessor selectAuthScheme
INFO: basic authentication scheme selected
Oct 01, 2015 2:14:51 PM org.apache.commons.httpclient.HttpMethodDirector processWWWAuthChallenge
INFO: Failure authenticating with BASIC 'Jenkins'@x.x.x.x:8080
Failed to fetch slave info from Jenkins CODE: 401
Retrying in 10 seconds

Br,

AKS
  • 16,482
  • 43
  • 166
  • 258
eszik.k
  • 1,729
  • 4
  • 17
  • 40
  • 1
    What version of Jenkins are you using? It turned out that swarm-client requires password to be single quoted. tried -disableSslVerification : Disables SSL verification in the HttpClient.? – AKS Dec 02 '15 at 16:52
  • You need the pass the user in Jenkins who has Create Slave access. Look Manage Users/Roles in Jenkins OR try creating a user in Jenkins and assign him create slave access and use command. – AKS Dec 03 '15 at 20:39

2 Answers2

11

You need at least Create Slave permission or higher to create the slave using Swarm plugin.

You have the following options:

  1. Open a request and have your network team create a new LDAP/service account (generic) so that you don't have to worry about it's password getting changed within next N no. of days.

  2. Assign that user or grant it Create Slave permission or all access that see within (Slave section as per your image snapshot).

  3. Use that user's userid/password. You can create a global variable / use manage credential section in Jenkins to define the user/password and it'll be available to use an ENV variable or for doing credential based authentication.

  4. Run your command to create the slave and it'll work, something like:

$ java -jar swarm-client-2.0-jar-with-dependencies.jar \
    -name "$(hostname -a)_01" \
    -fsroot "$(pwd)/$(hostname -a)_01" \
    -master http://my_jenkins_server.my.company.com:8081 \
    -disableSslVerification \
    -username c123456_or_slaveSpecialUser \
    -password $p \
    -description "$(hostname -a) " \
    -executors 5 \
    -labels "Linux CentOS ANSIBLE" \
    -mode 'normal' \
    -retry 3 \
    -showHostName \
    -t java=~/tools/jdk1.8.0_45 \
    -t gradle=~/tools/gradle-2.9 \
    -t Maven=~/tools/apache-maven-3.3.3 \
    -t Groovy2=~/tools/groovy-2.4.5 \
    --showHostName \
    -disableClientsUniqueId

Note:
Mode can be -mode 'exclusive'
Using -disableClientsUniqueId option will create slave with the name as per your -name parameter (instead of suffixing it with a unique/alphanumeric ID).

Addition: To create Tool locations within the slave's configuration, I initially used -t **Java=~/tools/jdk1.8.0_45 -t Gradle=~/tools/gradle-2.9** and the command gave me an error No tool 'Java' is defined on Jenkins.

javax.servlet.ServletException: java.lang.RuntimeException: No tool 'Java' is defined on Jenkins.

After researching, I found this is because in my Jenkins Master (that I used), it's JDK Installations section in Jenkins global settings had this tool Name value set as "java" (all lower).

Trying -t java=~/tools/jdk1.8.0_45 resolved the issue and now I can see (JDK) java tool with value ~/tools/jdk1.8.0_45 in the slave's configuration.

NOTE:
If you are connecting or want to connect your slave to your Jenkins master using "Anonymous" user (i.e. then you don't have to provide -username c123456_or_slaveSpecialUser -password $p parameters), then in Jenkins Master's (with admin level permission do this one time only setup) > Under Manage Roles and Users > Under GLOBAL Roles section, create a role (or change existing Viewer role) and assign "Overall + Read" and "Slave + Create" access.

Then, on the same page, under "Slave Roles", create a Role for ex: autoslave or something like that and assign all access (Connect, Configure, ..., Delete) and MAKE sure assign a pattern(regex) for ex: "swarm_slave.*" in it. What this will do is, from now onwards, you can run java -jar slave-client-...depedencies.jar without using -username and -password paramters and if you are creating swarm slaves with name starting with "swarm_slave...." then, they will auto-create/connect/delete (as long as the swarm slave java process will run/exist on the slave server).

Following a standard name pattern for slaves will also give you more control if you'd use Jenkins Rest/API (groovy) scripts to maintain the swarm slaves.

Also look here for more (how to add ENVIRONMENT variables to the newly created node): Jenkins Slave - How to add or update ENVIRONMENT variables

Using Docker for creating containers on slave nodes is the next step. Don't forget to read more about these here:

http://dockins.github.io/ and https://wiki.jenkins.io/display/JENKINS/Docker+Slaves+Plugin https://github.com/jenkinsci/docker-slaves-plugin

Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
AKS
  • 16,482
  • 43
  • 166
  • 258
  • How exactly does one perform #3? – Florian Straub Dec 08 '16 at 16:15
  • @FlorianStraub What that means is in Jenkins, there's a way you can create masked variables (in Global setting/configuration of Jenkins, i.e. not at the job level). Go to Jenkins > Manage Jenkins > Configure System > Look for "Masked passwords - ... " sections(there are 2, automatically and global password variablename/value pairs). In default/automatically section, tick mark the one you want (for ex: Password parameters, non-stored password..etc) but what you want is in the 2nd section, add a variable "myUser_SomeName" & provide its password/value. Now you can use it in any job as $myUser... – AKS Dec 08 '16 at 23:39
  • In other words: -username $myUser -password $myUserPassword (if you created. You may only do it for just the password variable (myUserPassword) as that's the main variable you want to mask. For -username $myUser, you don't actually have to as one can give -username c123user (hardcoded) as well (in a Jenkins job), but it's upto you. – AKS Dec 08 '16 at 23:42
  • Thanks for the fast reply. In "Configure System" on my Jenkins v. 2.35 I only have a section called "Global Passwords", but nothing with "automatically". Am I lacking a plugin? – Florian Straub Dec 09 '16 at 11:49
  • 1
    Yep. See the docs in the plugin (under After section): https://wiki.jenkins-ci.org/display/JENKINS/Mask+Passwords+Plugin – AKS Dec 10 '16 at 01:03
  • Thanks! Got a little further: In "Global name/password pairs" I created a variable SWARM_PWD, but it seems that I don't succeed receiving it in the shell of my mac slave. I tried '$SWARM_PWD', '\$SWARM_PWD' and $SWARM_PWD but without any luck. Do you have any hints on this? – Florian Straub Dec 12 '16 at 14:33
  • Do this first. If you have created the variable in the Global section. Then, first inside any Jenkins job, echo the variable in a "Execute Shell" build step by entering: "echo $SWARM_PWD". Make sure you tick the checkbox which says, Mask password variables. Now next to that (under Build Environment), you'll find this checkbox: "Inject passwords to the build as environment variables", tick that box as well, inside that, tick "Global passwords" checkbox. Now see if you can see $SWARM_PWD available in Execute shell or not. If you do, you can pass it to your target script or inject it. – AKS Dec 13 '16 at 06:19
  • 1
    Thanks @ArunSangal for the great write up. Some additions I found through trial and error: * in url/manage-roles, Global Roles, I added "slaverole" with "Overall: Read" , "Agent:Connect" and "Agent:Create" * in url/assign-roles, add Anonymous to global role slaverole. – J.Z. Sep 19 '17 at 17:20
  • Cool. Thanks for sharing. – AKS Sep 19 '17 at 21:20
1

After we failed implementing the solution by Arun Sangal we found a way to allow everything to everyone when being logged in while still being able to use SWARM nodes.

We managed to do this by assinging Anonymous all "agent" rights, plus Read and Discover for jobs as well as Read for views and in general.

Then we created an additional role "admin" which has all rights (both in "Manage Roles").

In "Assign Roles" we assigned the admin role to the build-in group "authenticated" and "Anonymous" to "Anonymous".

Florian Straub
  • 826
  • 9
  • 18