Setup and Configure Nexus 45/7145/4
authorTrevor Bramwell <tbramwell@linuxfoundation.org>
Sat, 28 Oct 2017 12:55:56 +0000 (05:55 -0700)
committerTrevor Bramwell <tbramwell@linuxfoundation.org>
Tue, 28 Nov 2017 19:24:52 +0000 (11:24 -0800)
Adds the Nexus (v2) container and does the following:

 - Creates the initial 'logs' repository
 - Configures Jenkins to be able to talk to Nexus by creating a
   settings.xml, and installing the needed packages on the
   jenkins-agent.
 - Installs required plugins for the jjb logs publishing job, including
   downloading PostBuildScript during the Jenkins container build.
 - Directs requests to 'jenkins.localhost', etc, on the jenkins-agent
   through the nginx container.
 - Sets the Jenkins Markup Formatter to 'Safe HTML' so the logs link can
   be displayed.

Change-Id: I63c783156bcffd1699e9ca7fe1a114ee2ed54bed
Signed-off-by: Trevor Bramwell <tbramwell@linuxfoundation.org>
.env
.gitignore
README.rst
config.env
docker-compose.yml
init/config-ci-environment.sh
jenkins/Dockerfile
jenkins/agent/Dockerfile
jenkins/plugins.txt
jenkins/scripts/create-nexus-settings.groovy [new file with mode: 0644]
jenkins/scripts/global-properties.groovy

diff --git a/.env b/.env
index 6aca8ce..a469f91 100644 (file)
--- a/.env
+++ b/.env
@@ -3,4 +3,5 @@
 ##
 JENKINS_CONTAINER_VERSION=lts
 GERRIT_CONTAINER_VERSION=latest
+NEXUS_CONTAINER_VERSION=oss
 OPENLDAP_CONTAINER_VERSION=latest
index 878f372..5e12c98 100644 (file)
@@ -27,3 +27,8 @@ __pycache__/
 docs/_build/
 dist/
 MANIFEST
+
+# Cloned repositories
+All-Projects
+All-Users
+ci-management
index bee18c1..c41914c 100644 (file)
@@ -9,7 +9,7 @@ The primary services are:
 
  * Gerrit
  * Jenkins
- * Nexus [TODO]
+ * Nexus
 
 And the secondary services that support these:
 
@@ -30,8 +30,10 @@ Add the following to /etc/hosts::
 
   127.0.1.1 jenkins.localhost
   127.0.1.2 gerrit.localhost
+  127.0.1.3 nexus.localhost
 
-Default user account: sandbox/sandbox
+Jenkins/Gerrit login: sandbox/sandbox
+Nexus login: admin/admin123
 
 Getting Started
 ---------------
@@ -40,6 +42,7 @@ Add the following to /etc/hosts::
 
   127.0.1.1 jenkins.localhost
   127.0.1.2 gerrit.localhost
+  127.0.1.3 nexus.localhost
 
 .. Note: This is the same as setting the 'Host' header when sending a GET
    request to localhost: `curl -H "Host: gerrit.localhost" localhost`
@@ -53,6 +56,31 @@ authentication backed by LDAP, a simple ci-management repo in
 Gerrit, and a basic job in Jenkins that verifies commits to the
 ci-management repo.
 
+Once the environment is up and running, copy your ssh public-key and add
+it to the sandbox user in Gerrit. This can be either be done through the
+web interface or from the commandline::
+
+  ./gerrit-auth.sh ~/.ssh/id_rsa.pub
+
+Then you can clone the ci-management repo and modify it to your hearts
+content::
+
+  git clone ssh://sandbox@gerrit.localhost:29418/ci-management.git
+
+Set the gitreview username::
+
+  git config --add gitreview.username "sandbox"
+
+And ensure the Change-Id hook exists::
+
+  git review -s
+
+Putting up a patchset for review that modifies "\*.yaml" files should
+trigger the ci-management-jjb-verify job and add a -1/+1 Verified vote.
+
+Notes
+-----
+
 To bring up a single service in the foreground you can use:
 
 .. code-block::
@@ -62,9 +90,8 @@ To bring up a single service in the foreground you can use:
 Note: dependent services will still be launched but in the background.
 Hitting '^C' will stop this service, but not the others.
 
-If a service is backed by a Dockerfile (most will be eventually), then
-changes to the Dockerfile or files under '$SERVICE/' will require
-rebuilding the container:
+If a service is backed by a Dockerfile, then changes to the Dockerfile
+or files under '$SERVICE/' will require rebuilding the container:
 
 .. code-block::
 
@@ -77,37 +104,21 @@ scratch, run:
 
   docker-compose down -v
 
-For other useful docker-compose commands such as logs, see::
-
-  docker-compose -h
-
-Next Steps
-----------
-
-Once the environment is up and running, copy your ssh public-key and add
-it to the sandbox user in Gerrit. This can be either be done through the
-web interface or from the commandline::
-
-  ./gerrit-auth.sh ~/.ssh/id_rsa.pub
-
-Then you can clone the ci-management repo and modify it to your hearts
-content::
-
-  git clone ssh://sandbox@gerrit.localhost:29418/ci-management.git
+To run a specific version of one of the services, edit the `.env` file,
+and rebuild the containers. For example, to run Jenkins 2.80 set the
+value in the `.env` file::
 
-Set the gitreview username::
+  JENKINS_CONTAINER_VERSION=2.80
 
-  git config --add gitreview.username "sandbox"
+and run::
 
-And ensure the Change-Id hook exists::
+  docker-compose up -d --build
 
-  git review -s
+to rebuild the Jenkins image before launching it.
 
-Putting up a patchset for review that modifies "\*.yaml" files should
-trigger the ci-management-jjb-verify job and add a -1/+1 Verified vote.
+For other useful docker-compose commands such as logs, see::
 
-Notes
------
+  docker-compose -h
 
 Init Container
 ~~~~~~~~~~~~~~
@@ -145,13 +156,15 @@ General:
 - [ ] Replace 'sandbox' names with 'workshop' since sandbox was just a
       placeholder
 - [ ] Setup OpenLDAP over SSL by default
-- [ ] Collapse environment config into single file and add lots of
-      comments, so users don't need to track down the correct file
 - [ ] Make things more configurable. There are a lot of hardcoded names
       in Groovy scripts which could be pulled from environment variables
+- [x] Collapse environment config into single file and add lots of
+      comments, so users don't need to track down the correct file
 
 Nexus:
-- [ ] Setup and configure Nexus
+- [ ] Configure Nexus to use LDAP (admin/admin123, or LDAP)
+- [x] Setup and configure Nexus
+  - [x] Create 'logs' Nexus site repo.
 
 Gerrit:
 - [ ] Remove postgres container configuration and replace with MariaDB
@@ -163,6 +176,15 @@ Jenkins:
       instance.hasExplicitPermission(attrs.sid,p) in /configureSecurity/.
       Reason: java.lang.NullPointerException
 - [ ] Make Groovy scripts Idempotent
+- [x] Set Markup Formatter to HTML Output
+- [x] Add LOGS_SERVER, SILO, NEXUS_URL, JENKINS_HOSTNAME
+- [x] Create XML config file 'jenkins-log-archives-settings' (depends on credentials)
+- [x] Install environment injector plugin
+      https://wiki.jenkins.io/display/JENKINS/EnvInject+Plugin
+- [x] Install plugin for build description
+      https://plugins.jenkins.io/description-setter
+- [x] Manually install postbuildscript.hpi
+      http://mirrors.jenkins-ci.org/plugins/postbuildscript/0.17/postbuildscript.hpi
 
 Init:
 - [ ] Make steps strongly idempotent (verify the state they modify)
index 4a55221..7f2bfdf 100644 (file)
@@ -1,5 +1,6 @@
 ##
 # Gerrit
+#   https://hub.docker.com/r/openfrontier/gerrit
 ##
 #GERRIT_INIT_ARGS=" \
 #  --install-plugin=download-commands \
@@ -23,6 +24,7 @@ LDAP_LOCALUSERNAMETOLOWERCASE=true
 
 ##
 # Jenkins
+#  https://hub.docker.com/r/jenkins/jenkins
 ##
 JENKINS_OPTS=""
 JENKINS_ADMIN_USER=admin
@@ -43,6 +45,7 @@ JJB_JENKINS_HOSTNAME=jenkins
 
 ##
 # Postgres
+#   https://hub.docker.com/r/_/postgres
 ##
 POSTGRES_USER=gerrit2
 POSTGRES_PASSWORD=gerrit
@@ -50,6 +53,7 @@ POSTGRES_DB=reviewdb
 
 ##
 # OpenLDAP
+#   https://hub.docker.com/r/osixia/openldap
 ##
 LDAP_ORGANISATION=Test Org
 LDAP_DOMAIN=example.org
@@ -62,3 +66,13 @@ LDAP_ADMIN_PASSWORD=admin
 LDAP_TLS=false
 LDAP_TLS_ENFORCE=false
 LDAP_REMOVE_CONFIG_AFTER_SETUP=false
+
+##
+# Nexus
+#   https://hub.docker.com/r/sonatype/nexus/
+##
+#CONTEXT_PATH="/nexus"
+#MAX_HEAP="768m"
+#MIN_HEAP="256m"
+#JAVA_OPTS="-server -XX:MaxPermSize192m -Djava.net.preferIPv4Stack=true"
+#LAUNCHER_CONF="./conf/jetty.xml ./conf/jetty-requestlog.xml"
index 82cc9c1..3285a44 100644 (file)
@@ -13,6 +13,7 @@ services:
         links:
             - jenkins
             - gerrit
+            - nexus
     ldap:
         image: "osixia/openldap:$OPENLDAP_CONTAINER_VERSION"
         container_name: releng-ldap
@@ -43,13 +44,16 @@ services:
         links:
             - ldap
             - nginx
-            - jenkins-agent
     jenkins-agent:
         build: ./jenkins/agent
         container_name: releng-agent
         env_file: config.env
         ports:
             - "22"
+        links:
+            - "nginx:jenkins.localhost"
+            - "nginx:nexus.localhost"
+            - "nginx:gerrit.localhost"
     gerrit:
         image: "openfrontier/gerrit:$GERRIT_CONTAINER_VERSION"
         container_name: releng-gerrit
@@ -69,6 +73,21 @@ services:
         links:
             - ldap
             - nginx
+    nexus:
+        image: "sonatype/nexus:$NEXUS_CONTAINER_VERSION"
+        container_name: releng-nexus
+        env_file: config.env
+        environment:
+            - VIRTUAL_HOST=nexus.localhost
+            - VIRTUAL_PORT=8081
+        volumes:
+            - nexus:/sonatype-work
+        expose:
+            - "8081"
+        depends_on:
+            - nginx
+        links:
+            - nginx
     postgres:
         image: postgres:latest
         env_file: config.env
@@ -85,4 +104,5 @@ services:
 volumes:
     jenkins:
     gerrit:
+    nexus:
     init:
index 6103c5e..c839529 100644 (file)
@@ -178,3 +178,34 @@ if [ ! -f /init/step-8.done ]; then
 
     touch /init/step-8.done
 fi
+
+##
+# Nexus Setup
+##
+/docker-entrypoint-init.d/wait-for-it.sh nexus:8081 -t 30
+
+
+# Create Nexus Repos
+if [ ! -f /init/step-9.done ]; then
+    cat > /init/repo.json <<-EOF
+{
+  "data": {
+    "name": "logs",
+    "repoType": "hosted",
+    "providerRole": "org.sonatype.nexus.proxy.repository.WebSiteRepository",
+    "exposed": true,
+    "id": "logs",
+    "provider": "site",
+    "writePolicy": "ALLOW_WRITE",
+    "browseable": true,
+    "indexable": true,
+    "notFoundCacheTTL": 1440,
+    "repoPolicy": "MIXED"
+  }
+}
+EOF
+    curl -H "Content-Type: application/json" -X POST -d @/init/repo.json \
+      -u admin:admin123 http://nexus:8081/nexus/service/local/repositories
+
+    touch /init/step-9.done
+fi
index 48808e1..a7ac5c2 100644 (file)
@@ -18,6 +18,11 @@ RUN echo 2.0 > /usr/share/jenkins/ref/jenkins.install.UpgradeWizard.state
 COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
 RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt
 
+# Download PostBuildScript Plugin
+RUN curl --fail -sSL \
+  http://ftp.osuosl.org/pub/jenkins/plugins/postbuildscript/0.17/postbuildscript.hpi \
+  -o /usr/share/jenkins/ref/plugins/postbuildscript.hpi
+
 ENV JENKINS_GROOVY_INIT /usr/share/jenkins/ref/init.groovy.d/
 
 # Configure Basic Security
@@ -38,3 +43,5 @@ COPY scripts/create-jenkins-agent.groovy $JENKINS_GROOVY_INIT
 # Create JJB INI in Config File Plugin
 COPY scripts/create-jjbini.groovy $JENKINS_GROOVY_INIT
 
+# Create Nexus settings.xml
+COPY scripts/create-nexus-settings.groovy $JENKINS_GROOVY_INIT
index bb61afc..70177e9 100644 (file)
@@ -3,7 +3,9 @@ FROM jenkinsci/ssh-slave
 RUN DEBIAN_FRONTEND=noninteractive \
     apt-get update \
     && apt-get install --no-install-recommends -y python python-pip \
-       python-tox \
+       python-tox python-dev \
+       build-essential zip facter xmlstarlet \
     && apt-get clean
 
+RUN /usr/bin/pip install --upgrade setuptools
 RUN /usr/bin/pip install virtualenv
index e741ab6..eb8f8ba 100644 (file)
@@ -1,6 +1,7 @@
 ace-editor:1.1
 ant:1.5
 antisamy-markup-formatter:1.5
+apache-httpcomponents-client-4-api:4.5.3-2.0
 authentication-tokens:1.3
 bouncycastle-api:2.16.2
 branch-api:2.0.11
@@ -9,11 +10,13 @@ cloudbees-folder:6.1.0
 config-file-provider:2.16.3
 credentials-binding:1.12
 credentials:2.1.14
+description-setter:1.9
 display-url-api:2.0
 docker-commons:1.8
 docker-workflow:1.12
 durable-task:1.14
 email-ext:2.58
+envinject:2.1.5
 external-monitor-job:1.7
 gerrit-trigger:2.25.0
 git-client:2.4.6
@@ -26,8 +29,10 @@ gradle:1.27.1
 handlebars:1.1.1
 icon-shim:2.0.3
 jackson2-api:2.7.3
+javadoc:1.4
 jclouds-jenkins:2.14
 jquery-detached:1.2.1
+jsch:0.1.54.1
 junit:1.20
 ldap:1.16
 mailer:1.20
@@ -35,6 +40,7 @@ mapdb-api:1.0.9.0
 mask-passwords:2.10.1
 matrix-auth:1.7
 matrix-project:1.11
+maven-plugin:3.0
 momentjs:1.1.1
 pam-auth:1.3
 pipeline-build-step:2.5.1
diff --git a/jenkins/scripts/create-nexus-settings.groovy b/jenkins/scripts/create-nexus-settings.groovy
new file mode 100644 (file)
index 0000000..4f1f0a4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * SPDX-License-Identifier: EPL-1.0
+ *
+ * Copyright (c) 2017 The Linux Foundation and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
+import com.cloudbees.plugins.credentials.Credentials;
+import com.cloudbees.plugins.credentials.CredentialsScope;
+import com.cloudbees.plugins.credentials.domains.Domain;
+import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl;
+import org.jenkinsci.plugins.configfiles.GlobalConfigFiles;
+import org.jenkinsci.plugins.configfiles.maven.MavenSettingsConfig;
+import org.jenkinsci.plugins.configfiles.maven.MavenSettingsConfig.MavenSettingsConfigProvider;
+import org.jenkinsci.plugins.configfiles.maven.security.ServerCredentialMapping;
+import jenkins.model.Jenkins;
+
+def store = SystemCredentialsProvider.getInstance().getStore();
+
+Credentials nexus_credentials =
+    (Credentials) new UsernamePasswordCredentialsImpl(
+        CredentialsScope.GLOBAL,
+        "nexus-credentials",
+        "Nexus Repository Credentials",
+        "admin",
+        "admin123");
+
+// Create Nexus credentials
+store.addCredentials(Domain.global(), nexus_credentials);
+
+
+// Need to wait until after plugins are loaded
+Thread.start {
+    sleep 10000
+    println "--> Creating the Nexus Settings file"
+
+    GlobalConfigFiles config_files_store = Jenkins.getInstance()
+        .getExtensionList(GlobalConfigFiles.class).get(GlobalConfigFiles.class);
+
+    ServerCredentialMapping server_credentials = new ServerCredentialMapping(
+        "logs",
+        "nexus-credentials");
+    List<ServerCredentialMapping> server_mapping =
+        new ArrayList<ServerCredentialMapping>();
+    server_mapping.add(server_credentials);
+
+    MavenSettingsConfigProvider settings_config =
+        new MavenSettingsConfigProvider();
+
+    MavenSettingsConfig config = new MavenSettingsConfig(
+        "jenkins-log-archives-settings",
+        "jenkins-logs",
+        "Nexus Repository",
+        settings_config.loadTemplateContent(),
+        MavenSettingsConfig.isReplaceAllDefault,
+        server_mapping);
+    config_files_store.save(config);
+}
index a4fed16..8dadc23 100644 (file)
  *
  */
 import jenkins.model.*
+import hudson.markup.RawHtmlMarkupFormatter
 
 instance = Jenkins.getInstance()
 globalNodeProperties = instance.getGlobalNodeProperties()
-envVarsNodePropertyList = globalNodeProperties.getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class)
+envVarsNodePropertyList =
+    globalNodeProperties.getAll(
+        hudson.slaves.EnvironmentVariablesNodeProperty.class)
 
 def env = System.getenv()
 
@@ -24,6 +27,9 @@ String LOGS_SERVER = env.get('JJB_LOGS_SERVER')
 String SILO = env.get('JJB_SILO')
 String JENKINS_HOSTNAME = env.get('JJB_JENKINS_HOSTNAME')
 
+// Set Markup Formatter to 'Safe HTML' so nexus build log links show up.
+instance.setMarkupFormatter(new RawHtmlMarkupFormatter(false))
+
 newEnvVarsNodeProperty = null
 envVars = null