When running Jenkins, you may try to set the JENKINS_HOME path that Jenkins uses at start-up, only to find the following output message:
Jenkins home directory: /var/jenkins_home/.jenkins found at: $user.home/.jenkins
You're trying to get Jenkins to read its files from /var/jenkins_home
, but it keeps tacking on a /.jenkins
hidden folder, and you can't get it to stop.
You've googled around and read all the documentation, but none of it describes how to fix this.
The actual problem can be found in the Jenkins source code found here on GitHub:
public FileAndDescription getHomeDir(ServletContextEvent event) {
// check JNDI for the home directory first
for (String name : HOME_NAMES) {
try {
InitialContext iniCtxt = new InitialContext();
Context env = (Context) iniCtxt.lookup("java:comp/env");
String value = (String) env.lookup(name);
if(value!=null && value.trim().length()>0)
return new FileAndDescription(new File(value.trim()),"JNDI/java:comp/env/"+name);
// look at one more place. See issue #1314
value = (String) iniCtxt.lookup(name);
if(value!=null && value.trim().length()>0)
return new FileAndDescription(new File(value.trim()),"JNDI/"+name);
} catch (NamingException e) {
// ignore
}
}
// next the system property
for (String name : HOME_NAMES) {
String sysProp = SystemProperties.getString(name);
if(sysProp!=null)
return new FileAndDescription(new File(sysProp.trim()),"SystemProperties.getProperty(\""+name+"\")");
}
// look at the env var next
for (String name : HOME_NAMES) {
String env = EnvVars.masterEnvVars.get(name);
if(env!=null)
return new FileAndDescription(new File(env.trim()).getAbsoluteFile(),"EnvVars.masterEnvVars.get(\""+name+"\")");
}
// otherwise pick a place by ourselves
String root = event.getServletContext().getRealPath("/WEB-INF/workspace");
if(root!=null) {
File ws = new File(root.trim());
if(ws.exists())
// Hudson <1.42 used to prefer this before ~/.hudson, so
// check the existence and if it's there, use it.
// otherwise if this is a new installation, prefer ~/.hudson
return new FileAndDescription(ws,"getServletContext().getRealPath(\"/WEB-INF/workspace\")");
}
File legacyHome = new File(new File(System.getProperty("user.home")),".hudson");
if (legacyHome.exists()) {
return new FileAndDescription(legacyHome,"$user.home/.hudson"); // before rename, this is where it was stored
}
File newHome = new File(new File(System.getProperty("user.home")),".jenkins");
return new FileAndDescription(newHome,"$user.home/.jenkins");
}
This code is doing a couple things:
- Check for a name matching the 'HOME_NAMES' list in the lookup for JNDI environment variables
- Check 'SystemProperties' for the same names
- Check 'EnvVars' for the same thing
- Check for a '/WEB-INF/workspace' directory in the Servlet's current context
- Check for a 'user.home'/.hudson directory
- Finally, just default to 'user.home'/.jenkins
I'm not a Java developer, so I couldn't understand most of how it was looking up JNDI, SystemProperties, or EnvVars. However, I did happen upon this Oracle page about using JNDI: https://docs.oracle.com/javase/jndi/tutorial/beyond/env/source.html
Apparenty you can set SystemProperties by adding the -D
option on the command-line to Java. So, let's try adding -DJENKINS_HOME=/var/jenkins_home
:
java -DJENKINS_HOME=/var/jenkins_home -Djenkins.install.runSetupWizard=false -Djenkins.model.Jenkins.slaveAgentPort=50000 -Djenkins.model.Jenkins.slaveAgentPortEnforce=true -Dio.jenkins.dev.security.createAdmin= -Dio.jenkins.dev.security.allowRunsOnMaster= -Dhudson.model.LoadStatistics.clock=1000 -Djava.awt.headless=true -jar /var/jenkins_home/jenkins.war --webroot=/var/jenkins_home/war
Some time later:
Jenkins home directory: /var/jenkins_home found at: SystemProperties.getProperty("JENKINS_HOME")
Voila! No more '.jenkins' directory!