Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preventing plugin setup wizard #310

Open
carlossg opened this issue Jul 18, 2016 · 33 comments
Open

Preventing plugin setup wizard #310

carlossg opened this issue Jul 18, 2016 · 33 comments

Comments

@carlossg
Copy link
Contributor

if I use

FROM jenkins:2.7.1
RUN echo 2.7.1 > /usr/share/jenkins/ref/jenkins.install.UpgradeWizard.state
RUN echo 2.7.1 > /usr/share/jenkins/ref/jenkins.install.InstallUtil.lastExecVersion

then I can avoid the wizard, but the admin password is not printed in the logs

Is there a way to just prevent the plugin setup?

@jglick
Copy link
Member

jglick commented Jul 26, 2016

Not sure. @kzantow do you know?

@kzantow
Copy link

kzantow commented Jul 26, 2016

If the initial admin user is actually created, it should print to the logs, see: https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/jenkins/install/SetupWizard.java#L91-L153

You may also want to pass -Djenkins.install.runSetupWizard=false to skip the initial setup altogether.

Optionally, you could cat $JENKINS_HOME/secrets/initialAdminPassword.

@kzantow
Copy link

kzantow commented Jul 26, 2016

If you actually just want to prevent the plugin setup, but you DO want the initial security setup, you can implement your own InstallStateFilter to alter the flow. You would need a plugin installed at boot time or to inject a class file into the war distribution, though. See: https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/jenkins/install/UpgradeWizard.java#L154 for a simple example.

@carlossg
Copy link
Contributor Author

The problem with -Djenkins.install.runSetupWizard=false is that it is a runtime flag, not build time, vs. burning a file in the image
I'd say the typical flow is to build the image with some preconfigured plugins, then not ask for plugin setup at startup. Creating the admin user may be ok.

@kzantow
Copy link

kzantow commented Jul 26, 2016

Hm, is there any way to provide a properties file or set system properties at boot time? Maybe hook into this somehow? https://github.com/jenkinsci/extras-executable-war/blob/master/src/main/java/Main.java#L171

@carlossg
Copy link
Contributor Author

at boot time yes, you can set JAVA_OPTS=-Djenkins.install.runSetupWizard=false
but I'm looking for something to do at build time, as it is then when the plugins are installed into the image

@kzantow
Copy link

kzantow commented Jul 26, 2016

I guess as things stand, either package it with a modification to the Main file I referenced to set the system property (or find a way to include a properties file in the distribution... or just add the command line flag to a run script if this is for a docker image). Or package a simple plugin that overrides the default behavior. It's trivial to do the latter, just involves actually making a plugin. I could send you an example, but it's basically the same as the UpgradeWizard I referenced: you just plug into the lifecycle, and set it to the RUNNING state, no matter what and It'll bypass the wizard (or wait until the security is configured and send it to the RUNNING state). There are a lot of solutions to this problem, let me know if I can help any other way.

@recena
Copy link

recena commented Aug 11, 2016

@carlossg Is there any update here?

@carlossg
Copy link
Contributor Author

No updates. IIUC there is the option to skip the wizard but not a way to skip only plugin installation.

@kzantow
Copy link

kzantow commented Aug 11, 2016

@carlossg Again, a fairly trivial InstallStateFilter will do the trick, you just need to add a plugin with it before the app starts.

@carlossg
Copy link
Contributor Author

@kzantow yes, I mean there is no way for someone extending the image to just do that easily with a file marker or something like that

@foxylion
Copy link

foxylion commented Sep 26, 2016

In our case we created a new Jenkins image which automatically installs some plugins and creates a admin user with a default password. So there is no Jenkins setup visible and after starting the container you can directly use Jenkins.
See here: https://github.com/foxylion/docker-jenkins

@carltonmason
Copy link

carltonmason commented Oct 1, 2016

@foxylion I tried using the approach you described after looking at your Dockerfile but, I can't login to Jenkins. The Docker image built fine but when I try to login via the Jenkins web UI, I specify the default id and password that were also specified in the Dockefile and I get: Invalid login information. Please try again.

Never mind, I looked closer at your Dockerfile and figured it out....

@foxylion
Copy link

foxylion commented Oct 4, 2016

@ckmason You're missing the Groovy file to add the user: https://github.com/foxylion/docker-jenkins/blob/master/docker-images/master/default-user.groovy

Edit: Ok. 😄

@hartzell
Copy link

hartzell commented Nov 3, 2016

@foxylion -- I am having trouble making my own image using your ideas, so I've fallen back on using your image but that doesn't work either. Details in foxylion/docker-jenkins#1

@krm1
Copy link

krm1 commented Feb 13, 2017

@kzantow
Can you please expain this behaviour? When I create a new Jenkins container with no mounts to store data in the host, then complete the Jenkins setup and then stop the container to save it as a new docker image (docker commit ...). Why isn't the setup completed when I start a new container with the saved image? I was expecting that my saved image contains now a Jenkins that is configured and ready to use.

e.g.:

sudo docker pull jenkins
sudo docker run -d -p 8080:8080 jenkins
...complete Jenkins setup ....
sudo docker stop a9
sudo docker commit a9 foo
sudo docker rm a9
sudo docker run -d -p 8080:8080 foo
.... do Jenkins setup again because it can find the old setup

Is there a way to save images with Jenkins data? I want to use my Docker registry as a backup system

@krm1
Copy link

krm1 commented Feb 13, 2017

Ok, found it out, its because of the Volume statement in the Dockerfile, removing it gets me to the expected behaviour.

VOLUME /var/jenkins_home

@dejayc
Copy link

dejayc commented Sep 14, 2017

@krm1 to clarify, volumes are not preserved into an image layer during commit.

@carlossg
Copy link
Contributor Author

So @kzantow there is still no way to choose not to run the plugin install wizard at build time?

@foxylion
Copy link

@kzantow It is possible, have a look at my customized image: https://github.com/foxylion/docker-jenkins
You can also use this image directly.

@coderanger
Copy link

coderanger commented Nov 14, 2017

If you want to do this from just groovy, I think correct incantation is:

import static jenkins.model.Jenkins.instance as jenkins
import jenkins.install.InstallState
if (!jenkins.installState.isSetupComplete()) {
  println '--> Neutering SetupWizard'
  InstallState.INITIAL_SETUP_COMPLETED.initializeState()
}

@ckhajavi
Copy link

@foxylion In your master docker image, I can see where you copy your groovy scripts, but where in the Dockerfile do you Run them? Sorry if I'm missing something totally obvious, I'm a docker noob!

@ckhajavi
Copy link

Ohh nm, it's because it's an init file.

@thorntonryan
Copy link

@coderanger 's incantation worked for me.

Worth noting, I could not get it to work when executing through a $JENKINS_HOME/init.groovy hook. Inside the call to InstallState.INITIAL_SETUP_COMPLETED.initializeState(), a null SetupWizard object was returned here which caused the init.groovy script to crash. But when running the script as the admin or any other user with appropriate permissions, it successfully disabled the Startup Wizard.

@cromat
Copy link

cromat commented May 18, 2018

This is what was working for me inside docker for Jenkins version 2.107.3.
I created this groovy script which disables setup wizard and creates admin user with custom admin password so you can just cut out the part with creating user if you don't need that.

basic-security.groovy

#!groovy
import jenkins.model.*
import hudson.security.*
import jenkins.install.InstallState

def instance = Jenkins.getInstance()

println "--> creating local user 'admin'"
// Create user with custom pass
def user = instance.getSecurityRealm().createAccount('admin', 'someAdminPass')
user.save()

def strategy = new FullControlOnceLoggedInAuthorizationStrategy()
strategy.setAllowAnonymousRead(false)
instance.setAuthorizationStrategy(strategy)

if (!instance.installState.isSetupComplete()) {
  println '--> Neutering SetupWizard'
  InstallState.INITIAL_SETUP_COMPLETED.initializeState()
}

instance.save()

Then in Dockerfile

COPY basic-security.groovy /var/lib/jenkins/init.groovy.d/

# In case you are running as root
RUN chown -R jenkins:jenkins /var/lib/jenkins/init.groovy.d/

Also if you want preinstalled plugins when building the image, you will need to copy plugin installation script from orginal Jenkins docker repository and optionally a text file with plugins to be installed.

install-plugins.sh https://github.com/jenkinsci/docker/blob/master/install-plugins.sh
jenkins-support https://github.com/jenkinsci/docker/blob/master/jenkins-support

Plugins file example:
plugins.txt https://github.com/fabric8io/jenkins-docker/blob/master/plugins.txt

Dockerfile

COPY install-plugins.sh /usr/local/bin/
COPY jenkins-support /usr/local/bin/
COPY plugins.txt /var/lib/jenkins/plugins.txt
RUN /usr/local/bin/install-plugins.sh < /var/lib/jenkins/plugins.txt

For me, the problem was default jenkins directory which is /var/lib/jenkins and preinstalled plugins go to /usr/share/jenkins/ref/plugins. Although the script should move installed plugins to /var/lib/jenkins/plugins, for some reason it didn't work. So I needed to change REF_DIR variable in install-plugins.sh script. After that, the script will install plugins directly to Jenkins home folder.

REF_DIR=${REF:-/usr/share/jenkins/ref/plugins}
to
REF_DIR=${REF:-/var/lib/jenkins/plugins}

Alternatively, if you don't want to change file directly you can do it with sed while building the image:
RUN sed -i "/REF_DIR=/c\REF_DIR=${REF:-/var/lib/jenkins/plugins}" /usr/local/bin/install-plugins.sh

@bkowenswork
Copy link

@cromat Unfortunately the code for disabling the wizard does not work as of 2.121.1

@gaoguoxin
Copy link

@foxylion after skip the setup wizard.the file jenkins.model.JenkinsLocationConfiguration.xml at jenkins_home was missed. and in that case when I access the BUILD_URL or JOB_URL then will ruturn null, so I have to click the save-button in system settings.and after that the file jenkins.model.JenkinsLocationConfiguration.xml was be created. and as you know the jenkinsUrl in that file which can't be predefined in Dockerfile. is there anything else I can do ?

@ringerc
Copy link

ringerc commented Jun 6, 2019

This seems to cause a great deal of confusion, see e.g.

etc. But many instructions seem wrong, outdated, etc. I can't yet find a method that actually works.

The answer "oh, just click OK" isn't really cool. This is meant to be a CI system, surely making it unnecessarily painful to deploy in fully automated, testable, configuration managed manner isn't ideal.

I was eventually able to make it behave with two JAVA_OPTS properties, e.g.

docker run -it -p 8080:8080 -p 50000:50000 --rm \
  --env JAVA_OPTS="-Djenkins.install.runSetupWizard=false" \
  jenkins/jenkins

(Obviously my real run uses volumes etc, this is a minimal example)

I've created #833 to request some changes

@chief-tyrol
Copy link

chief-tyrol commented Jun 24, 2019

After some trial and error, I was able to disable just the plugin installation phase of the installation wizard, without affecting the other sections.

The code I'm using is here: https://github.com/gryphon-zone/jenkins/blob/7788a6f9668561d5631c4c4b12fc69ba3bec1d84/configuration/disable-plugin-install-wizard.groovy
And I'm adding it into my Dockerfile here: https://github.com/gryphon-zone/jenkins/blob/7788a6f9668561d5631c4c4b12fc69ba3bec1d84/Dockerfile#L41-L42

(worth noting, I'm doing other customization in the Dockerfile to make Jenkins work for my specific use case, but the disable-plugin-install-wizard.groovy script is solely for disabling the plugin section of the wizard, and can be used in isolation of any of the rest of the repo)

As mentioned in the comments for the groovy script, right now there isn't a dedicated installation state for the plugin configuration section of the wizard (or at least if there is, I couldn't find it), meaning it's possible that the script will break in a future release of Jenkins/start skipping more than just the plugin installation (if dedicated states are added in the future I'll update the script).

Additionally, I'm using the deprecated ExtensionList.add() method: https://github.com/jenkinsci/jenkins/blob/57a3268afb749c84196ce5fa3cfd51b08cda1328/core/src/main/java/hudson/ExtensionList.java#L263-L279 (that may not be required, I haven't tried to get automatic registration working).

Definitely agree that given the presence of the install-plugins.sh, it would be much more convenient if there were a simpler way to disable just the plugin installation phase of the wizard, without affecting other aspects.

Also worth mentioning, adding -Djenkins.install.runSetupWizard=false isn't a good option anymore if your intention is just to skip plugin installation (if it ever was), because it bypasses the entire setup wizard, meaning things like adding an admin user and configuring the base URL are also skipped.

vasilejureschi added a commit to vasilejureschi/jenkins that referenced this issue Jul 12, 2019
Check for setup completed was wrong, added groovy script which
bypasses plugin install but leaves admin password visible in logs.

See
jenkinsci/docker#310
jenkinsci/docker#608
shadowwalkersb added a commit to cryoem/docker-images that referenced this issue Aug 3, 2019
@ChristianCiach
Copy link

I think the README should be corrected, as is it misleading in its current state. The README clearly states:

For 2.x-derived images, you may also want to

RUN echo 2.0 > /usr/share/jenkins/ref/jenkins.install.UpgradeWizard.state

to indicate that this Jenkins installation is fully configured. Otherwise a banner will appear prompting the user to install additional plugins, which may be inappropriate.

This is clearly wrong, so this should be removed from the README.

@andrew-aiken
Copy link

This will prevent the setup wizard from the Dockerfile

FROM jenkins/jenkins:lts
ENV JAVA_OPTS="-Djenkins.install.runSetupWizard=false"

@ddovbii
Copy link

ddovbii commented Sep 14, 2020

My goal was to disable setup wizard and at the same time create first admin user
Here is what allowed me to do it

Dockerfile:

FROM jenkins/jenkins:2.235.5-lts

ENV JENKINS_USER admin
ENV JENKINS_PASS admin

# Skip initial setup
ENV JAVA_OPTS -Djenkins.install.runSetupWizard=false

# use this for creating default admin user
COPY default-user.groovy /usr/share/jenkins/ref/init.groovy.d/

groovy script default-user.groovy:

import jenkins.model.*
import hudson.security.*

def env = System.getenv()

def jenkins = Jenkins.getInstance()
if(!(jenkins.getSecurityRealm() instanceof HudsonPrivateSecurityRealm))
    jenkins.setSecurityRealm(new HudsonPrivateSecurityRealm(false))

if(!(jenkins.getAuthorizationStrategy() instanceof FullControlOnceLoggedInAuthorizationStrategy))
   jenkins.setAuthorizationStrategy(new FullControlOnceLoggedInAuthorizationStrategy())

// create new Jenkins user account
// username & password from environment variables
def user = jenkins.getSecurityRealm().createAccount(env.JENKINS_USER, env.JENKINS_PASS)
user.save()
jenkins.getAuthorizationStrategy().add(Jenkins.ADMINISTER, env.JENKINS_USER)

jenkins.save()

@gabrielke
Copy link

With jenkins 2.2.89.3 this gives me following exception:

groovy.lang.MissingMethodException: No signature of method: hudson.security.FullControlOnceLoggedInAuthorizationStrategy.add() is applicable for argument types: (hudson.security.Permission, java.lang.String) values: [Permission[class hudson.model.Hudson,Administer], admin]

Although admin user created, setup wizard disabled, this is just not nice to see.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests