Created
March 25, 2013 17:03
-
-
Save tbatchelli/5238708 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns proto.jenkins | |
(:use [pallet.phase :only (phase-fn)] | |
[pallet.action.package :only (package)] | |
[pallet.crate.automated-admin-user :only (automated-admin-user)] | |
[pallet.action.exec-script :only (exec-checked-script)] | |
[proto.common :only (user)] ) | |
(:require [pallet.core :as pc] | |
[pallet.crate.tomcat :as tomcat] | |
[pallet.crate.git :as git] | |
[pallet.crate.hudson :as hudson] | |
[pallet.crate.java :as java] | |
[pallet.crate.maven :as maven] | |
[pallet.action.user :as user] | |
[pallet.action.service :as service] | |
[pallet.action.package :as package] | |
[pallet.crate.etc-default :as etc-default] | |
[pallet.action.remote-file :as remote-file] | |
[pallet.crate.sudoers :as sudoers] | |
[pallet.action.user :as user] | |
[pallet.configure] | |
[pallet.parameter :as parameter])) | |
(def keystore-file "/etc/tomcat6/tc.ks") | |
(defn ssl-keystore | |
"Create a keystore with a self signed ssl certificate." | |
[session] | |
;; dname values taken from keytool manpage | |
(exec-checked-script | |
session | |
"Create keystore" | |
(when (not (file-exists? ~keystore-file)) | |
(keytool | |
-genkey -alias tomcat -keyalg RSA | |
-dname | |
(quoted "CN=Mark Smith, OU=Java, O=Sun, L=Cupertino, S=California, C=US") | |
-keystore ~keystore-file -storepass changeit -keypass changeit)))) | |
;; Base node for jenkins on VBox | |
(def jenkins-vbox-node | |
(pc/node-spec | |
:image {:image-id :ubuntu+12.04 | |
:os-family :ubuntu} | |
:hardware {:min-ram 1024})) | |
;; Base node for jenkins on AMZ EC2 | |
(def jenkins-ec2-east-node | |
(pc/node-spec | |
:image {:image-id "us-east-1/ami-3d4ff254"} | |
:hardware {:min-ram 1024 | |
:inbound-ports [22 80 443]})) | |
;; the configuration for the tomcat server | |
(def tomcat-config | |
(tomcat/server | |
:port "8005" | |
:shutdown "SHUTDOWN" | |
(tomcat/engine "Catalina" "localhost") | |
(tomcat/service | |
(tomcat/global-resources) | |
(tomcat/connector | |
:scheme "http" :port "80" | |
:protocol "HTTP/1.1" | |
:connectionTimeout "20000" | |
:redirectPort "443") | |
(tomcat/connector | |
:scheme "https" | |
:secure "true" | |
:SSLEnabled "true" | |
:keystoreFile keystore-file | |
:keystorePass "changeit" | |
:clientAuth "false" | |
:sslProtocol "TLS" | |
:port "443" :protocol "HTTP/1.1" | |
:connectionTimeout "20000")))) | |
;; jenkins jobs | |
(defn setup-hudson-jobs [s] | |
(-> | |
s | |
;; note: we're not creating jobs at this point | |
;; | |
;; (hudson/job :maven2 "test" | |
;; :maven-name "default maven" | |
;; :goals "-P clean deploy" | |
;; :group-id "test" | |
;; :artifact-id "test" | |
;; :github {:projectUrl "https://github.com/tbatchelli/vmfest"} | |
;; :maven-opts "" | |
;; :aggregator-style-build true | |
;; :scm ["git://github.com/tbatchelli/vmfest.git"]) | |
)) | |
(def tomcat-user "tomcat6") | |
(def tomcat-group "tomcat6") | |
(def tomcat-service "tomcat6") | |
(def jenkins-data-path "/var/lib/hudson") | |
(defn configure-hudson [s] | |
(-> | |
s | |
(hudson/config :use-secrurity true | |
;; Security based on unix auth/auth | |
:security-realm :pam | |
;; :disable-signup true not needed for PAM auth | |
:authorization-strategy :global-matrix | |
:permissions | |
;; Unix users of the group jenkins can do | |
;; everything. Everyone else cannot do and see | |
;; anything. | |
[{:user "jenkins" :permissions hudson/all-permissions} | |
{:user "Anonymous" :permissions []}]) | |
;; this is only for hudson-based authentication | |
;; | |
;; Passwords are SHA-256 using salt. Here is an easy way to create | |
;; the hash: http://www.hashgenerator.de | |
;; | |
;; Selecting SHA-256 and then entering "PASSWORD{SALT}" in the form | |
;; will result in a HASH. In the field :password-hash below, use | |
;; the resulting hash and the salt used, using the format | |
;; "SALT:HASH" | |
;; | |
;; (hudson/user "alexy" | |
;; { :full-name "user name" | |
;; :password-hash "abcdefg:6f4c61....1e60dd40126cb32a41a40" | |
;; :email "[email protected]"}) | |
)) | |
(defn hudson-setup [s] | |
(-> | |
s | |
;; install oracle JDK | |
(java/java-settings {:vendor :oracle ;; openjdk for installing OpenJDK | |
:components #{:jdk}}) | |
(java/install-java) | |
;; install git | |
(git/git) | |
;; | |
;; Prepare the tomcat install (version 6 at this point) | |
;; | |
;; using SSL, so we need a certificate. This creates a self-signed | |
;; cert and installs it in a keystore | |
(ssl-keystore) | |
;; configure tomcat | |
(tomcat/tomcat-settings | |
;; NOTE: we shouldn't need to override the tomcat user, but this | |
;; tomcat-crate needs to be fixed first. | |
{:group tomcat-group | |
:user tomcat-user | |
:owner tomcat-user | |
:server tomcat-config | |
:version "6"}) | |
;; install tomcat | |
(tomcat/install-tomcat) | |
;; The tomcat user must belong to the "shadow" group in order to be | |
;; able to authenticate based on unix user/group via PAM | |
(user/user tomcat-user :action :manage :groups [tomcat-group "shadow"]) | |
;; configure tomcat | |
(tomcat/server-configuration) | |
;; Jenkins requires the path to the directory where it will store | |
;; it's data to be passed as an environment variable. The default, | |
;; which is writing into the tomcat directory, will not work | |
;; because of the lack of permissions (and it is not a good practice) | |
(etc-default/write tomcat-service | |
"TOMCAT6_USER" tomcat-user | |
"TOMCAT6_GROUP" tomcat-group | |
"JAVA_OPTS" "-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC" | |
"HUDSON_HOME" jenkins-data-path | |
;; AUTHBIND is necessary for tomcat to be able | |
;; to use privileged ports | |
"AUTHBIND" "yes") | |
;; NOTE: Hudson versions 1.446 onwards cannot be reinstalled. the | |
;; system won't start: https://issues.jenkins-ci.org/browse/JENKINS-12338 | |
(hudson/tomcat-deploy :version "1.445") | |
(configure-hudson) | |
;; crete the jenkins obs | |
(setup-hudson-jobs))) | |
(defn create-users | |
([s] ;; by the fault, we look in the environment for this | |
(when-let [user-maps (pallet.environment/get-for s [:proto :users])] | |
(create-users s user-maps))) | |
([s user-maps] | |
(-> s | |
(pallet.thread-expr/for-> | |
[{:keys [username password groups public-keys]} user-maps] | |
(user username password groups public-keys))))) | |
(defn add-salted-passwords [user-maps salt] | |
(for [user user-maps] | |
(assoc user :password (str (:username user) salt)))) | |
(def users | |
[{:username "someone" | |
:groups ["jenkins"] | |
:public-keys ["ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6n/Xv0SAbH8feh7EN7jNPuDBbdGfY8QIoQT+iite8s/rz+lP9gnmjanT40B/sW+TCp/IvOrreBJRAM7Gkx7khN40PXT18fOTpEf5EfCyKmRqD8r9fvCDZ3YV3lQCwaZ3ebEJyBp7ULCso8QbEvcokL1F63rDLcUWiYFGZ5MWk2J0/Y/1es7BJfFzFgaqKtp9NABQvsAJdWnEYCtNZtTG+AzolIn1ru55gEOkZDpPLtqF/59YzCJx5YPx5w/MLrhgVOeggJbpvuTZWdpEK8srItXKJ2IIBK2kBLLWMMZ4iqHuQysbcyWp5PGI8F0R2s1DWQ7pHZtvFSQ5bWl71HDOZQ=="]} | |
{:username "anotherone" | |
:groups ["jenkins"]}]) | |
(def jenkins-server | |
(pc/server-spec | |
:phases | |
{:configure (phase-fn | |
hudson-setup) | |
:create-users (phase-fn | |
;; ensure the running user is not left out of the | |
;; sudoers list | |
(automated-admin-user) | |
;; create all the users | |
(create-users (add-salted-passwords users "-zzz"))) | |
:start-tomcat (phase-fn | |
(service/service "tomcat6" :action :start)) | |
:stop-tomcat (phase-fn | |
(service/service "tomcat76" :action :stop)) | |
:restart-tomcat (phase-fn | |
(service/service "tomcat6" :action :restart))})) | |
;;; group for running on virtual box | |
(def jenkins-vbox | |
(pc/group-spec | |
"jenkins" | |
:extends [jenkins-server] | |
:node-spec jenkins-vbox-node | |
:phases | |
{:bootstrap automated-admin-user})) | |
;;; group for running on EC2 | |
(def jenkins-ec2-east | |
(pc/group-spec | |
"jenkins" | |
:extends [jenkins-server] | |
:node-spec jenkins-ec2-east-node | |
:phases | |
{:bootstrap automated-admin-user})) | |
(defn jenkins-ip [session] | |
(let [all-jenkins-nodes (pallet.session/nodes-in-group session "jenkins") | |
jenkins-node (first (filter pallet.node/running? all-jenkins-nodes ))] | |
(pallet.node/primary-ip jenkins-node) )) | |
(defn ec2-provider [identity credential] | |
(pallet.configure/compute-service-from-map | |
{:provider "aws-ec2" | |
:identity identity | |
:credential credential})) | |
(defn vmfest-provider [] | |
(pallet.configure/compute-service-from-map | |
{:provider "vmfest"})) | |
(defn build-jenkins [provider spec] | |
(let [results (pc/converge {spec 1} | |
:compute provider | |
:phase [:create-users | |
:restart-tomcat]) | |
ip (jenkins-ip results)] | |
(format "https://%s/hudson" ip))) | |
(defn destroy-jenkins [provider spec] | |
(pc/converge {spec 0} | |
:compute provider) | |
true) | |
(defn update-users [provider spec] | |
(pc/lift [spec] | |
:compute provider | |
:phase [:create-users]) | |
true) | |
(defn restart-jenkins [provider spec] | |
(pc/lift [spec] | |
:compute provider | |
:phase [:restart-tomcat]) | |
true) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment