James Moger
2011-12-02 b774dedd7f0ab1567e790610b70eb7f2241423fb
Preliminary changes for running on RedHat OpenShift. Still in-progress.
1 files added
7 files modified
342 ■■■■ changed files
.gitignore 2 ●●●●● patch | view | raw | blame | history
build.xml 149 ●●●● patch | view | raw | blame | history
distrib/openshift.mkd 35 ●●●●● patch | view | raw | blame | history
docs/00_index.mkd 31 ●●●●● patch | view | raw | blame | history
docs/04_releases.mkd 5 ●●●●● patch | view | raw | blame | history
src/com/gitblit/GitBlit.java 89 ●●●● patch | view | raw | blame | history
src/com/gitblit/GitServlet.java 2 ●●● patch | view | raw | blame | history
src/com/gitblit/WebXmlSettings.java 29 ●●●●● patch | view | raw | blame | history
.gitignore
@@ -21,3 +21,5 @@
/bin/
/.settings/
/javadoc
/express
/build-demo.xml
build.xml
@@ -16,6 +16,7 @@
    <property name="project.war.dir" value="${basedir}/war" />
    <property name="project.site.dir" value="${basedir}/site" />
    <property name="project.resources.dir" value="${basedir}/resources" />    
    <property name="project.express.dir" value="${basedir}/express" />
    <available property="hasBuildProps" file="${basedir}/build.properties"/>
    <!--
@@ -87,6 +88,7 @@
        <property name="fedclient.zipfile" value="fedclient-${gb.version}.zip" />
        <property name="manager.zipfile" value="manager-${gb.version}.zip" />
        <property name="gbapi.zipfile" value="gbapi-${gb.version}.zip" />
        <property name="express.zipfile" value="express-${gb.version}.zip" />
    </target>
    
    
@@ -157,6 +159,7 @@
            <fileset dir="${basedir}/distrib">
                <include name="**/*" />
                <exclude name="federation.properties" />
                <exclude name="openshift.mkd" />
            </fileset>
            <fileset dir="${basedir}">
                <include name="LICENSE" />
@@ -280,6 +283,9 @@
                <arg value="%API%=${gbapi.zipfile}" />
                <arg value="--substitute" />
                <arg value="%EXPRESS%=${express.zipfile}" />
                <arg value="--substitute" />
                <arg value="%BUILDDATE%=${gb.versionDate}" />
                <arg value="--substitute" />
@@ -313,7 +319,7 @@
        
        <echo>Building Gitblit WAR ${gb.version}</echo>
        
        <delete dir="${project.war.dir}" />
        <delete dir="${project.war.dir}" />
        <!-- Copy web.xml and users.properties to WEB-INF -->
        <copy todir="${project.war.dir}/WEB-INF">
@@ -376,7 +382,7 @@
        <mkdir dir="${project.war.dir}/WEB-INF/classes"/>
        <copy todir="${project.war.dir}/WEB-INF/classes">
            <fileset dir="${project.build.dir}">
                <exclude name="WEB-INF/web.xml" />
                <exclude name="WEB-INF/" />
                <exclude name="com/gitblit/tests/" />
                <exclude name="com/gitblit/build/**" />
                <exclude name="com/gitblit/client/**" />
@@ -434,12 +440,100 @@
    <!-- 
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Build a Gitblit filesystem for deployment to RedHat OpenShif Expresst
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -->
    <target name="buildOpenShift" depends="compile" description="Build exploded WAR file suitable for deployment to OpenShift Express">
        <echo>Building Gitblit Express for RedHat OpenShift ${gb.version}</echo>
        <delete dir="${project.express.dir}" />
        <!-- Create the OpenShift filesystem -->
        <property name="deployments.root" value="${project.express.dir}/deployments/ROOT.war"/>
        <mkdir dir="${deployments.root}" />
        <touch file="${project.express.dir}/deployments/ROOT.war.dodeploy" />
        <!-- Copy the Gitblit OpenShift readme file -->
        <copy tofile="${project.express.dir}/README.gitblit"
            file="${basedir}/distrib/openshift.mkd"/>
        <!-- Copy LICENSE and NOTICE to WEB-INF -->
        <copy todir="${deployments.root}/WEB-INF">
            <fileset dir="${basedir}">
                <include name="LICENSE" />
                <include name="NOTICE" />
            </fileset>
        </copy>
        <!-- Copy gitblit.properties as reference.properties -->
        <copy tofile="${deployments.root}/WEB-INF/reference.properties"
            file="${basedir}/distrib/gitblit.properties"/>
        <!-- Build the WAR web.xml from the prototype web.xml and gitblit.properties -->
        <!-- THIS FILE IS NOT OVERRIDDEN ONCE IT IS BUILT!!! -->
        <java classpath="${project.build.dir}" classname="com.gitblit.build.BuildWebXml">
            <classpath refid="master-classpath" />
            <arg value="--sourceFile" />
            <arg value="${basedir}/src/WEB-INF/web.xml" />
            <arg value="--destinationFile" />
            <arg value="${deployments.root}/WEB-INF/web.xml" />
            <arg value="--propertiesFile" />
            <arg value="${basedir}/distrib/gitblit.properties" />
        </java>
        <!-- Gitblit resources -->
        <copy todir="${deployments.root}">
            <fileset dir="${project.resources.dir}">
                <exclude name="thumbs.db" />
            </fileset>
        </copy>
        <!-- Gitblit library dependencies -->
        <mkdir dir="${deployments.root}/WEB-INF/lib"/>
        <copy todir="${deployments.root}/WEB-INF/lib">
            <fileset dir="${basedir}/ext">
                <exclude name="*-sources.jar" />
                <exclude name="*-javadoc.jar" />
                <exclude name="jcommander*.jar" />
                <exclude name="jetty*.jar" />
                <exclude name="junit*.jar" />
                <exclude name="servlet*.jar" />
            </fileset>
        </copy>
        <!-- Gitblit classes -->
        <mkdir dir="${deployments.root}/WEB-INF/classes"/>
        <copy todir="${deployments.root}/WEB-INF/classes">
            <fileset dir="${project.build.dir}">
                <exclude name="WEB-INF/" />
                <exclude name="com/gitblit/tests/" />
                <exclude name="com/gitblit/build/**" />
                <exclude name="com/gitblit/client/**" />
                <exclude name="com/gitblit/GitBlitServer*.class" />
                <exclude name="com/gitblit/Launcher*.class" />
                <exclude name="com/gitblit/MakeCertificate*.class" />
            </fileset>
        </copy>
        <!-- Build Express Zip file -->
        <zip destfile="${express.zipfile}">
            <fileset dir="${project.express.dir}" />
        </zip>
    </target>
    <!--
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Build the stand-alone, Gitblit Manager
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -->
    <target name="buildManager" depends="compile" description="Builds the stand-alone Gitblit Manager">
        <echo>Building Gitblit Manager ${gb.version}</echo>
        <genjar jarfile="manager-${gb.version}.jar">
            <resource file="${basedir}/src/com/gitblit/client/splash.png" />
            <resource file="${basedir}/resources/gitblt-favicon.png" />
@@ -461,7 +555,7 @@
            <resource file="${basedir}/resources/commit_merge_16x16.png" />
            <resource file="${basedir}/resources/blank.png" />
            <resource file="${basedir}/src/com/gitblit/wicket/GitBlitWebApp.properties" />
            <class name="com.gitblit.client.GitblitManagerLauncher" />
            <classfilter>
                <exclude name="org.apache." />
@@ -479,7 +573,7 @@
                <attribute name="Release-Date" value="${gb.versionDate}" />
            </manifest>
        </genjar>
        <!-- Build Manager Zip file -->
        <zip destfile="${manager.zipfile}">
            <fileset dir="${basedir}">
@@ -683,6 +777,9 @@
            <arg value="%API%=${gbapi.zipfile}" />
            <arg value="--substitute" />
            <arg value="%EXPRESS%=${express.zipfile}" />
            <arg value="--substitute" />
            <arg value="%BUILDDATE%=${gb.versionDate}" />
            <arg value="--substitute" />
@@ -705,30 +802,31 @@
        </java>    
    </target>
    <!--
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
        Compile from source, publish binaries, and build & deploy site
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -->
    <target name="buildAll" depends="buildGO,buildWAR,buildFederationClient,buildManager,buildApiLibrary,buildSite">
    <target name="buildAll" depends="buildGO,buildWAR,buildOpenShift,buildFederationClient,buildManager,buildApiLibrary,buildSite">
        <!-- Cleanup -->
        <delete dir="${project.build.dir}" />
        <delete dir="${project.war.dir}" />
        <delete dir="${project.deploy.dir}" />
        <delete dir="${project.express.dir}" />
    </target>
    <!-- 
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Publish binaries to Google Code
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -->
    <target name="publishBinaries" depends="buildGO,buildWAR,buildFederationClient,buildManager" description="Publish the Gitblit binaries to Google Code">
    <target name="publishBinaries" depends="buildGO,buildWAR,buildOpenShift,buildFederationClient,buildManager" description="Publish the Gitblit binaries to Google Code">
        <echo>Uploading Gitblit ${gb.version} binaries</echo>
        <!-- Upload Gitblit GO ZIP file -->
        <gcupload 
             username="${googlecode.user}" 
@@ -738,7 +836,7 @@
             targetfilename="gitblit-${gb.version}.zip"
             summary="Gitblit GO v${gb.version} (standalone, integrated Gitblit server)"
             labels="Featured, Type-Package, OpSys-All" />
        <!-- Upload Gitblit WAR file -->
        <gcupload 
             username="${googlecode.user}" 
@@ -748,7 +846,7 @@
             targetfilename="gitblit-${gb.version}.war"
             summary="Gitblit WAR v${gb.version} (standard WAR webapp for servlet containers)"
             labels="Featured, Type-Package, OpSys-All" />
        <!-- Upload Gitblit FedClient -->
        <gcupload 
            username="${googlecode.user}" 
@@ -768,7 +866,7 @@
            targetfilename="manager-${gb.version}.zip"
            summary="Gitblit Manager v${gb.version} (Swing tool to remotely administer a Gitblit server)"
            labels="Featured, Type-Package, OpSys-All" />
        <!-- Upload Gitblit API Library -->
        <gcupload 
            username="${googlecode.user}" 
@@ -778,19 +876,30 @@
            targetfilename="gbapi-${gb.version}.zip"
            summary="Gitblit API Library v${gb.version} (JSON RPC library to integrate with your software)"
            labels="Featured, Type-Package, OpSys-All" />
        <!-- Upload Gitblit Express for RedHat OpenShift -->
        <gcupload
            username="${googlecode.user}"
            password="${googlecode.password}"
            projectname="gitblit"
            filename="${express.zipfile}"
            targetfilename="express-${gb.version}.zip"
            summary="Gitblit Express v${gb.version} (run Gitblit on RedHat's OpenShift cloud)"
            labels="Featured, Type-Package, OpSys-All" />
    </target>
    <!--
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
        Publish site to hosting service
        Publish site to site hosting service
        You must add ext/commons-net-1.4.0.jar to your ANT classpath.
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -->
    <target name="publishSite" depends="buildSite" description="Publish the Gitblit site to a webserver (requires ext/commons-net-1.4.0.jar)" >
        <echo>Uploading Gitblit ${gb.version} website</echo>
        <ftp server="${ftp.server}"
            userid="${ftp.user}"
            password="${ftp.password}"
@@ -801,7 +910,7 @@
        </ftp>
    </target>
    <!--
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
        Compile from source, publish binaries, and build & deploy site
distrib/openshift.mkd
New file
@@ -0,0 +1,35 @@
## Gitblit on RedHat's OpenShift Cloud Service
The Gitblit Express distribution can be copied to the root of your RedHat OpenShift
application repository.  Gitblit Express is an exploded WAR file with all appropriate
dependencies bundled.
You should delete the `pom.xml` file and the `src` folder from your application repository
as this Gitblit Express is not a source distribution to be built with Maven on OpenShift.
Gitblit automatically adjusts itself to running on OpenShift.  Repositories, users,
federation proposals, and setting overrides are stored in *OPENSHIFT_DATA_DIR*.
It is recommended to enable all RPC settings in the `web.xml` file to allow remote
administration and, more importantly, configuration of your Gitblit Express
installation using the Gitblit Manager.
Please do not change the following settings unless you know exactly what you are
doing:
- *git.repositoriesFolder*
- *federation.proposalsFolder*
- *realm.userService* (for standard users.properties)
Additionally, it is recommended to force your Gitblit installation to cleanup up
older versions on your OpenShift filesystem to maximize available space for your
repositories.
Append the following command to your ./openshift/action_hooks/build file:
    rm -fr $OPENSHIFT_APP_DIR/jbossas-7.0/standalone/tmp/vfs/*
For more detailed instructions on how to setup and deploy an OpenShift application
please see this excellent turorial:
https://github.com/opensas/play-demo/wiki/Step-12.5---deploy-to-openshift
docs/00_index.mkd
@@ -1,15 +1,16 @@
## What is Gitblit?
<div class="well" style="margin-left:5px;float:right;width:275px;padding: 10px 10px;">
<b>Current Release %VERSION% (%BUILDDATE%)</b> <a href="releases.html">changelog</a>
<div style="padding:5px;"><a style="text-decoration:none;" class="btn success" href="http://code.google.com/p/gitblit/downloads/detail?name=%GO%">Download Gitblit GO</a></div>
<div style="padding:5px;"><a style="text-decoration:none;" class="btn danger" href="http://code.google.com/p/gitblit/downloads/detail?name=%WAR%">Download Gitblit WAR</a></div>
<div style="padding:5px;"><a style="text-decoration:none;" class="btn primary" href="http://code.google.com/p/gitblit/downloads/detail?name=%MANAGER%">Download Gitblit Manager</a></div>
    <div style="text-align:center;">
<div style="padding:5px;"><a style="width:150px;text-decoration:none;" class="btn success" href="http://code.google.com/p/gitblit/downloads/detail?name=%GO%">Download Gitblit GO</a></div>
<div style="padding:5px;"><a style="width:150px;text-decoration:none;" class="btn danger" href="http://code.google.com/p/gitblit/downloads/detail?name=%WAR%">Download Gitblit WAR</a></div>
<div style="padding:5px;"><a style="width:150px;text-decoration:none;" class="btn info" href="http://code.google.com/p/gitblit/downloads/detail?name=%EXPRESS%">Download Gitblit Express</a></div>
<div style="padding:5px;"><a style="width:150px;text-decoration:none;" class="btn primary" href="http://code.google.com/p/gitblit/downloads/detail?name=%MANAGER%">Download Gitblit Manager</a></div>
    <div style="text-align:center">
        <a href="http://code.google.com/p/gitblit/downloads/detail?name=%API%">Gitblit API</a> | <a href="http://code.google.com/p/gitblit/downloads/detail?name=%FEDCLIENT%">Gitblit Federation Client</a>
        <br/>
        <a href="screenshots.html" title="Screenshots"><img style="margin-top:5px;border:1px solid #ccc;" src="thumbs/00.png" alt="Screenshots" /></a>
    </div>
    <div style="padding-top:5px;">
    <table class="condensed-table">
        <tbody>
@@ -19,9 +20,9 @@
        <tr><th>Discussion</th><td><a href="http://groups.google.com/group/gitblit">Gitblit Group</a></td></tr>
        <tr><th>Google+</th><td><a href="https://plus.google.com/114464678392593421684">Gitblit+</a></td></tr>
        </tbody>
        </table>
        </table>
    </div>
    <a target="_top" href="http://www.ohloh.net/p/gitblit">
        <img style="padding-top:5px;" border="0" width="100" height="16" src="http://www.ohloh.net/p/gitblit/widgets/project_thin_badge.gif" alt="Ohloh project report for Gitblit" />
    </a>
@@ -30,19 +31,26 @@
Gitblit is an open-source, pure Java stack for managing, viewing, and serving [Git][git] repositories.  
It's designed primarily as a tool for small workgroups who want to host centralized repositories.
You can browse a live demo [here](http://demo-gitblit.rhcloud.com) hosted on [RedHat's OpenShift][rhcloud] cloud service.
### GO: Single-Stack Solution
*Gitblit GO* is an integrated, single-stack solution based on Jetty.
You do not need Apache httpd, Perl, Git, or Gitweb.  Should you want to use some or all of those, you still can; Gitblit plays nice with the other kids on the block.
This is what you should download if you want to go from zero to Git in less than 5 mins.
All dependencies are downloaded on first execution.
### WAR: For Your Servlet Container
*Gitblit WAR* is what you should download if you already have a servlet container available that you wish to use.  Jetty 6/7/8 and Tomcat 6/7 are known to work.  Generally, any Servlet 2.5 or Servlet 3.0 container should work.
All dependencies are bundled.
### Express: For the Cloud
*Gitblit Express* is a prepared distribution for [RedHat's OpenShift][rhcloud] cloud service.
All dependencies are bundled.
### You decide how to use Gitblit
@@ -72,4 +80,5 @@
Gitblit requires a Java 6 Runtime Environment (JRE) or a Java 6 Development Kit (JDK).
[jgit]: http://eclipse.org/jgit "Eclipse JGit Site"
[git]: http://git-scm.com "Official Git Site"
[git]: http://git-scm.com "Official Git Site"
[rhcloud]: https://openshift.redhat.com/app "RedHat OpenShift"
docs/04_releases.mkd
@@ -1,11 +1,12 @@
## Release History
### Current Release
**%VERSION%** ([go](http://code.google.com/p/gitblit/downloads/detail?name=%GO%) | [war](http://code.google.com/p/gitblit/downloads/detail?name=%WAR%) | [fedclient](http://code.google.com/p/gitblit/downloads/detail?name=%FEDCLIENT%) | [manager](http://code.google.com/p/gitblit/downloads/detail?name=%MANAGER%) | [api](http://code.google.com/p/gitblit/downloads/detail?name=%API%)) based on [%JGIT%][jgit] &nbsp; *released %BUILDDATE%*
**%VERSION%** ([go](http://code.google.com/p/gitblit/downloads/detail?name=%GO%) | [war](http://code.google.com/p/gitblit/downloads/detail?name=%WAR%) | [express](http://code.google.com/p/gitblit/downloads/detail?name=%EXPRESS%) | [fedclient](http://code.google.com/p/gitblit/downloads/detail?name=%FEDCLIENT%) | [manager](http://code.google.com/p/gitblit/downloads/detail?name=%MANAGER%) | [api](http://code.google.com/p/gitblit/downloads/detail?name=%API%)) based on [%JGIT%][jgit] &nbsp; *released %BUILDDATE%*
- added: Gitblit Express bundle for running Gitblit on RedHat's OpenShift cloud
- added: optional Gravatar integration  
    **New:** *web.allowGravatar = true*   
- added: multi-repository activity page.  this is a timeline of commit activity over the last N days for one or more repositories.
- added: multi-repository activity page.  this is a timeline of commit activity over the last N days for one or more repositories.
   **New:** *web.activityDuration = 14*  
   **New:** *web.timeFormat = HH:mm*  
   **New:** *web.datestampLongFormat = EEEE, MMMM d, yyyy*  
src/com/gitblit/GitBlit.java
@@ -247,6 +247,54 @@
    }
    /**
     * Returns the file object for the specified configuration key.
     *
     * @return the file
     */
    public static File getFileOrFolder(String key, String defaultFileOrFolder) {
        String fileOrFolder = GitBlit.getString(key, defaultFileOrFolder);
        return getFileOrFolder(fileOrFolder);
    }
    /**
     * Returns the file object which may have it's base-path determined by
     * environment variables for running on a cloud hosting service. All Gitblit
     * file or folder retrievals are (at least initially) funneled through this
     * method so it is the correct point to globally override/alter filesystem
     * access based on environment or some other indicator.
     *
     * @return the file
     */
    public static File getFileOrFolder(String fileOrFolder) {
        String openShift = System.getenv("OPENSHIFT_DATA_DIR");
        if (!StringUtils.isEmpty(openShift)) {
            // running on RedHat OpenShift
            return new File(openShift, fileOrFolder);
        }
        return new File(fileOrFolder);
    }
    /**
     * Returns the path of the repositories folder. This method checks to see if
     * Gitblit is running on a cloud service and may return an adjusted path.
     *
     * @return the repositories folder path
     */
    public static File getRepositoriesFolder() {
        return getFileOrFolder(Keys.git.repositoriesFolder, "git");
    }
    /**
     * Returns the path of the proposals folder. This method checks to see if
     * Gitblit is running on a cloud service and may return an adjusted path.
     *
     * @return the proposals folder path
     */
    public static File getProposalsFolder() {
        return getFileOrFolder(Keys.federation.proposalsFolder, "proposals");
    }
    /**
     * Updates the list of server settings.
     * 
     * @param settings
@@ -1120,8 +1168,7 @@
        try {
            // make the proposals folder
            File proposalsFolder = new File(getString(Keys.federation.proposalsFolder, "proposals")
                    .trim());
            File proposalsFolder = getProposalsFolder();
            proposalsFolder.mkdirs();
            // cache json to a file
@@ -1153,7 +1200,7 @@
     */
    public List<FederationProposal> getPendingFederationProposals() {
        List<FederationProposal> list = new ArrayList<FederationProposal>();
        File folder = new File(getString(Keys.federation.proposalsFolder, "proposals").trim());
        File folder = getProposalsFolder();
        if (folder.exists()) {
            File[] files = folder.listFiles(new FileFilter() {
                @Override
@@ -1276,7 +1323,7 @@
     * @return true if the proposal was deleted
     */
    public boolean deletePendingFederationProposal(FederationProposal proposal) {
        File folder = new File(getString(Keys.federation.proposalsFolder, "proposals").trim());
        File folder = getProposalsFolder();
        File file = new File(folder, proposal.token + Constants.PROPOSAL_EXT);
        return file.delete();
    }
@@ -1391,7 +1438,7 @@
    public void configureContext(IStoredSettings settings, boolean startFederation) {
        logger.info("Reading configuration from " + settings.toString());
        this.settings = settings;
        repositoriesFolder = new File(settings.getString(Keys.git.repositoriesFolder, "git"));
        repositoriesFolder = getRepositoriesFolder();
        logger.info("Git repositories folder " + repositoriesFolder.getAbsolutePath());
        repositoryResolver = new FileResolver<Void>(repositoriesFolder, exportAll);
        serverStatus = new ServerStatus(isGO());
@@ -1406,16 +1453,26 @@
        } catch (Throwable t) {
            // not a login service class or class could not be instantiated.
            // try to use default file login service
            File realmFile = new File(realm);
            if (!realmFile.exists()) {
            File realmFile = getFileOrFolder(Keys.realm.userService, "users.properties");
            if (realmFile.exists()) {
                // load the existing realm file
                loginService = new FileUserService(realmFile);
            } else {
                // create a new realm file and add the default admin account.
                // this is necessary for bootstrapping a dynamic environment
                // like running on a cloud service.
                try {
                    realmFile.createNewFile();
                    loginService = new FileUserService(realmFile);
                    UserModel admin = new UserModel("admin");
                    admin.password = "admin";
                    admin.canAdmin = true;
                    loginService.updateUserModel(admin);
                } catch (IOException x) {
                    logger.error(
                            MessageFormat.format("COULD NOT CREATE REALM FILE {0}!", realmFile), x);
                }
            }
            loginService = new FileUserService(realmFile);
        }
        setUserService(loginService);
        mailExecutor = new MailExecutor(settings);
@@ -1441,7 +1498,21 @@
        settingsModel = loadSettingModels();
        if (settings == null) {
            // Gitblit WAR is running in a servlet container
            WebXmlSettings webxmlSettings = new WebXmlSettings(contextEvent.getServletContext());
            ServletContext context = contextEvent.getServletContext();
            WebXmlSettings webxmlSettings = new WebXmlSettings(context);
            // 0.7.0 web.properties in the deployed war folder
            File overrideFile = new File(context.getRealPath("/WEB-INF/web.properties"));
            if (overrideFile.exists()) {
                webxmlSettings.applyOverrides(overrideFile);
            }
            // 0.8.0 gitblit.properties file located outside the deployed war
            // folder lie, for example, on RedHat OpenShift.
            overrideFile = getFileOrFolder("gitblit.properties");
            if (!overrideFile.getPath().equals("gitblit.properties")) {
                webxmlSettings.applyOverrides(overrideFile);
            }
            configureContext(webxmlSettings, true);
        }
src/com/gitblit/GitServlet.java
@@ -35,7 +35,7 @@
    @Override
    public String getInitParameter(String name) {
        if (name.equals("base-path")) {
            return GitBlit.getString(Keys.git.repositoriesFolder, "git");
            return GitBlit.getRepositoriesFolder().getAbsolutePath();
        } else if (name.equals("export-all")) {
            return "1";
        }
src/com/gitblit/WebXmlSettings.java
@@ -20,6 +20,7 @@
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
@@ -38,11 +39,10 @@
    private final Properties properties = new Properties();
    private final ServletContext context;
    private File overrideFile;
    public WebXmlSettings(ServletContext context) {
        super(WebXmlSettings.class);
        this.context = context;
        Enumeration<?> keys = context.getInitParameterNames();
        while (keys.hasMoreElements()) {
            String key = keys.nextElement().toString();
@@ -50,15 +50,21 @@
            properties.put(key, decodeValue(value));
            logger.debug(key + "=" + properties.getProperty(key));
        }
    }
    public void applyOverrides(File overrideFile) {
        this.overrideFile = overrideFile;
        // apply any web-configured overrides
        File file = new File(context.getRealPath("/WEB-INF/web.properties"));
        if (file.exists()) {
        if (overrideFile.exists()) {
            try {
                InputStream is = new FileInputStream(file);
                InputStream is = new FileInputStream(overrideFile);
                properties.load(is);
                is.close();
            } catch (Throwable t) {
                logger.error("Failed to load web.properties setting overrides", t);
                logger.error(
                        MessageFormat.format("Failed to apply {0} setting overrides",
                                overrideFile.getAbsolutePath()), t);
            }
        }
    }
@@ -78,19 +84,18 @@
        try {
            Properties props = new Properties();
            // load pre-existing web-configuration
            File file = new File(context.getRealPath("/WEB-INF/web.properties"));
            if (file.exists()) {
                InputStream is = new FileInputStream(file);
            if (overrideFile.exists()) {
                InputStream is = new FileInputStream(overrideFile);
                props.load(is);
                is.close();
            }
            // put all new settings and persist
            props.putAll(settings);
            OutputStream os = new FileOutputStream(file);
            OutputStream os = new FileOutputStream(overrideFile);
            props.store(os, null);
            os.close();
            // override current runtime settings
            properties.putAll(settings);
            return true;