aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Sokolovsky <paul.sokolovsky@linaro.org>2013-10-11 15:53:53 +0300
committerPaul Sokolovsky <paul.sokolovsky@linaro.org>2013-10-11 15:53:53 +0300
commit2c4009a15f114d4a3dcfeb225144b55e2d9ab424 (patch)
tree12976285f2b2ce993a30a4981de880a8919ad1fa
parentf1f6069b4e586fbc7aeede36563be6493f9fa63d (diff)
Initial proof-of-concept Ansible scripts to deploy android-build infra.
-rw-r--r--ansible-deploy/Vagrantfile104
-rw-r--r--ansible-deploy/files/apache.conf81
-rw-r--r--ansible-deploy/filter_plugins/custom_plugins.py17
-rw-r--r--ansible-deploy/frontend.yml9
-rw-r--r--ansible-deploy/group_vars/all5
-rw-r--r--ansible-deploy/hosts-devel-vagrant8
-rw-r--r--ansible-deploy/hosts-production2
-rw-r--r--ansible-deploy/jenkins.yml16
-rw-r--r--ansible-deploy/new_publish.yml46
-rw-r--r--ansible-deploy/reposeed.yml5
-rw-r--r--ansible-deploy/roles/apache/files/ssleay.conf9
-rw-r--r--ansible-deploy/roles/apache/tasks/main.yml39
-rw-r--r--ansible-deploy/roles/common/handlers/main.yml3
-rw-r--r--ansible-deploy/roles/common/tasks/main.yml10
-rw-r--r--ansible-deploy/roles/frontend/tasks/main.yml98
-rw-r--r--ansible-deploy/roles/frontend/templates/settings_prod.py12
-rw-r--r--ansible-deploy/roles/jenkins/files/jenkins-config/config.xml77
-rw-r--r--ansible-deploy/roles/jenkins/files/jenkins-config/jobs/blank/config.xml40
-rw-r--r--ansible-deploy/roles/jenkins/files/jenkins-config/users/admin/config.xml24
-rw-r--r--ansible-deploy/roles/jenkins/handlers/main.yml3
-rw-r--r--ansible-deploy/roles/jenkins/tasks/main.yml57
-rw-r--r--ansible-deploy/roles/jenkins/templates/jenkins-config/hudson.tasks.Mailer.xml7
-rw-r--r--ansible-deploy/roles/jenkins/templates/jenkins-config/users/frontend/config.xml23
-rw-r--r--ansible-deploy/roles/reposeed/tasks/main.yml3
-rw-r--r--ansible-deploy/site.yml5
25 files changed, 703 insertions, 0 deletions
diff --git a/ansible-deploy/Vagrantfile b/ansible-deploy/Vagrantfile
new file mode 100644
index 0000000..9c3caa4
--- /dev/null
+++ b/ansible-deploy/Vagrantfile
@@ -0,0 +1,104 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+#
+# This is vagrant config file for local VM setup of android-build
+#
+
+Vagrant::Config.run do |config|
+ # All Vagrant configuration is done here. The most common configuration
+ # options are documented and commented below. For a complete reference,
+ # please see the online documentation at vagrantup.com.
+
+ # Every Vagrant virtual environment requires a box to build off of.
+ config.vm.box = "precise32"
+
+ # The url from where the 'config.vm.box' box will be fetched if it
+ # doesn't already exist on the user's system.
+ # config.vm.box_url = "http://domain.com/path/to/above.box"
+
+ # Boot with a GUI so you can see the screen. (Default is headless)
+ config.vm.boot_mode = :gui
+
+ # Assign this VM to a host-only network IP, allowing you to access it
+ # via the IP. Host-only networks can talk to the host machine as well as
+ # any other machines on the same network, but cannot be accessed (through this
+ # network interface) by any external networks.
+ # config.vm.network :hostonly, "192.168.33.10"
+
+ # Assign this VM to a bridged network, allowing you to connect directly to a
+ # network using the host's network device. This makes the VM appear as another
+ # physical device on your network.
+ # config.vm.network :bridged
+
+ # Forward a port from the guest to the host, which allows for outside
+ # computers to access the VM, whereas host only networking does not.
+ config.vm.forward_port 80, 6080
+ config.vm.forward_port 443, 6443
+
+ # Share an additional folder to the guest VM. The first argument is
+ # an identifier, the second is the path on the guest to mount the
+ # folder, and the third is the path on the host to the actual folder.
+ # config.vm.share_folder "v-data", "/vagrant_data", "../data"
+
+ # Enable provisioning with Puppet stand alone. Puppet manifests
+ # are contained in a directory path relative to this Vagrantfile.
+ # You will need to create the manifests directory and a manifest in
+ # the file base.pp in the manifests_path directory.
+ #
+ # An example Puppet manifest to provision the message of the day:
+ #
+ # # group { "puppet":
+ # # ensure => "present",
+ # # }
+ # #
+ # # File { owner => 0, group => 0, mode => 0644 }
+ # #
+ # # file { '/etc/motd':
+ # # content => "Welcome to your Vagrant-built virtual machine!
+ # # Managed by Puppet.\n"
+ # # }
+ #
+ # config.vm.provision :puppet do |puppet|
+ # puppet.manifests_path = "manifests"
+ # puppet.manifest_file = "base.pp"
+ # end
+
+ # Enable provisioning with chef solo, specifying a cookbooks path, roles
+ # path, and data_bags path (all relative to this Vagrantfile), and adding
+ # some recipes and/or roles.
+ #
+ # config.vm.provision :chef_solo do |chef|
+ # chef.cookbooks_path = "../my-recipes/cookbooks"
+ # chef.roles_path = "../my-recipes/roles"
+ # chef.data_bags_path = "../my-recipes/data_bags"
+ # chef.add_recipe "mysql"
+ # chef.add_role "web"
+ #
+ # # You may also specify custom JSON attributes:
+ # chef.json = { :mysql_password => "foo" }
+ # end
+
+ # Enable provisioning with chef server, specifying the chef server URL,
+ # and the path to the validation key (relative to this Vagrantfile).
+ #
+ # The Opscode Platform uses HTTPS. Substitute your organization for
+ # ORGNAME in the URL and validation key.
+ #
+ # If you have your own Chef Server, use the appropriate URL, which may be
+ # HTTP instead of HTTPS depending on your configuration. Also change the
+ # validation key to validation.pem.
+ #
+ # config.vm.provision :chef_client do |chef|
+ # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
+ # chef.validation_key_path = "ORGNAME-validator.pem"
+ # end
+ #
+ # If you're using the Opscode platform, your validator client is
+ # ORGNAME-validator, replacing ORGNAME with your organization name.
+ #
+ # IF you have your own Chef Server, the default validation client name is
+ # chef-validator, unless you changed the configuration.
+ #
+ # chef.validation_client_name = "ORGNAME-validator"
+end
diff --git a/ansible-deploy/files/apache.conf b/ansible-deploy/files/apache.conf
new file mode 100644
index 0000000..6f64af8
--- /dev/null
+++ b/ansible-deploy/files/apache.conf
@@ -0,0 +1,81 @@
+<VirtualHost _default_:443>
+ ServerAdmin webmaster@localhost
+ ServerName android-build.linaro.org
+ <Proxy *>
+ Order deny,allow
+ Allow from all
+ </Proxy>
+
+ RewriteEngine on
+ RewriteRule ^/builds/~([a-z][-a-z0-9]+)/([-A-Za-z0-9_.]+)/([0-9]+)/output(.*) http://127.0.0.1:600/$1_$2/builds/$3/archive$4 [L,P]
+ RewriteRule ^/builds/~([a-z][-a-z0-9]+)/([-A-Za-z0-9_.]+)/lastSuccessful/output(.*) http://127.0.0.1:600/$1_$2/lastSuccessful/archive$3 [L,P]
+ RewriteRule ^/mockup(.*) $1 [R=301]
+
+ ProxyPass /jenkins http://localhost:9090/jenkins
+ ProxyPassReverse /jenkins http://localhost:9090/jenkins
+
+ Alias /static /home/build-system-frontend/frontend/static
+ Alias /3.3.0/build /home/build-system-frontend/yui/build
+
+ WSGIScriptAlias /combo /home/build-system-frontend/lazr-js/combo.wsgi
+ WSGIScriptAlias / /home/build-system-frontend/frontend/linaro-abs-frontend.wsgi
+
+ <LocationMatch "/(3.3.0/build|combo)">
+ SetOutputFilter DEFLATE
+ FileETag none
+ ExpiresActive on
+ ExpiresDefault "access plus 10 years"
+ Header append Cache-Control "public"
+ </LocationMatch>
+
+ SSLEngine on
+ SSLCertificateFile /etc/ssl/private/android-build.linaro.org.crt
+
+ BrowserMatch "MSIE [2-6]" \
+ nokeepalive ssl-unclean-shutdown \
+ downgrade-1.0 force-response-1.0
+ BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
+</VirtualHost>
+
+<VirtualHost 127.0.0.1:600>
+ ServerAdmin webmaster@localhost
+ ServerName android-build.linaro.org
+ DocumentRoot /var/lib/jenkins/jobs
+</VirtualHost>
+
+<VirtualHost _default_:80>
+ ServerAdmin webmaster@localhost
+ ServerName android-build.linaro.org
+ Alias /download/ /var/lib/jenkins/jobs/
+ # Provide shortcut URLs to access artifacts
+ AliasMatch ^/builds/~([^/]+)/([^/]+)/(lastStable|lastSuccessful)(.*) /var/lib/jenkins/jobs/$1_$2/$3/archive/build/out$4
+ AliasMatch ^/builds/~([^/]+)/([^/]+)/([^/]+)(.*) /var/lib/jenkins/jobs/$1_$2/builds/$3/archive/build/out$4
+ <Directory "/var/lib/jenkins/jobs/">
+ Options Indexes MultiViews FollowSymLinks
+ AllowOverride None
+ </Directory>
+ Alias /seed/ /mnt2/seed/
+ <Directory "/mnt2/seed/">
+ Options Indexes MultiViews FollowSymLinks
+ AllowOverride None
+# Order deny,allow
+# Deny from all
+# Allow from 127.0.0.0/8 ::1/128 10.0.0.0/8
+ </Directory>
+
+# RewriteLog /var/log/apache2/mod_rewrite_log
+# RewriteLogLevel 3
+
+ RewriteEngine on
+ RewriteCond %{REQUEST_URI} !^/(download|seed|builds)
+ RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [redirect=301,last]
+ # Allow to access everything in /builds/*
+ RewriteCond %{REQUEST_URI} ^/builds/
+ RewriteRule .* - [last]
+ # Allow to access XMLs in build artifact archives
+ RewriteCond %{REQUEST_URI} .+/archive/.+\.xml$
+ RewriteRule .* - [last]
+ # But disallow access any other XMLs (e.g. configs)
+ RewriteCond %{REQUEST_URI} .+\.xml$
+ RewriteRule .* - [forbidden]
+</VirtualHost>
diff --git a/ansible-deploy/filter_plugins/custom_plugins.py b/ansible-deploy/filter_plugins/custom_plugins.py
new file mode 100644
index 0000000..45a2031
--- /dev/null
+++ b/ansible-deploy/filter_plugins/custom_plugins.py
@@ -0,0 +1,17 @@
+import hashlib
+
+
+class FilterModule(object):
+ ''' Custom filters are loaded by FilterModule objects '''
+
+ def filters(self):
+ return {
+ 'jenkins_hash': self.jenkins_hash,
+ }
+
+ def jenkins_hash(self, value):
+ # TODO: generate salt randomly
+ salt = "salt"
+ h = hashlib.sha256()
+ h.update("%s{%s}" % (value, salt))
+ return salt + ":" + h.hexdigest()
diff --git a/ansible-deploy/frontend.yml b/ansible-deploy/frontend.yml
new file mode 100644
index 0000000..c88d9b7
--- /dev/null
+++ b/ansible-deploy/frontend.yml
@@ -0,0 +1,9 @@
+---
+- hosts: frontend
+ gather_facts: no
+ vars:
+ - linaro_android_frontend_repo: lp:linaro-android-frontend
+ - linaro_android_frontend_rev: 337
+ roles:
+ - common
+ - frontend
diff --git a/ansible-deploy/group_vars/all b/ansible-deploy/group_vars/all
new file mode 100644
index 0000000..290d329
--- /dev/null
+++ b/ansible-deploy/group_vars/all
@@ -0,0 +1,5 @@
+# These are global variables, applying to every play
+---
+# The path is relative to roles' main.yml file. Do not use in non-role tasks!
+# TODO: Ansible really should provide var for top-level playbook dir
+cred_store: ../../../../ansible-credentials/{{inventory_hostname}}_{{ansible_ssh_port}}
diff --git a/ansible-deploy/hosts-devel-vagrant b/ansible-deploy/hosts-devel-vagrant
new file mode 100644
index 0000000..8dc0cb5
--- /dev/null
+++ b/ansible-deploy/hosts-devel-vagrant
@@ -0,0 +1,8 @@
+[jenkins-master]
+localhost:2222 ansible_ssh_user=vagrant ansible_ssh_pass=vagrant
+
+[frontend]
+localhost:2222 ansible_ssh_user=vagrant ansible_ssh_pass=vagrant
+
+[reposeed]
+localhost:2222 ansible_ssh_user=vagrant ansible_ssh_pass=vagrant
diff --git a/ansible-deploy/hosts-production b/ansible-deploy/hosts-production
new file mode 100644
index 0000000..f5f902e
--- /dev/null
+++ b/ansible-deploy/hosts-production
@@ -0,0 +1,2 @@
+[jenkins-master]
+android-build.linaro.org ansible_ssh_user=vagrant
diff --git a/ansible-deploy/jenkins.yml b/ansible-deploy/jenkins.yml
new file mode 100644
index 0000000..93a28e1
--- /dev/null
+++ b/ansible-deploy/jenkins.yml
@@ -0,0 +1,16 @@
+---
+- hosts: jenkins-master
+ gather_facts: no
+ vars:
+ - linaro_android_build_tools_repo: lp:linaro-android-build-tools
+ - linaro_android_build_tools_rev: 676
+ - jenkins_version: 1.509.2
+ - site_name: android-build.linaro.org
+ - ssl_cert: /etc/ssl/private/android-build.linaro.org.crt
+ roles:
+ - common
+ - apache
+ - jenkins
+ tasks:
+ - name: Check out linaro-android-build-tools
+ bzr: name=$linaro_android_build_tools_repo version=$linaro_android_build_tools_rev dest=~/linaro-android-build-tools
diff --git a/ansible-deploy/new_publish.yml b/ansible-deploy/new_publish.yml
new file mode 100644
index 0000000..3edd6f1
--- /dev/null
+++ b/ansible-deploy/new_publish.yml
@@ -0,0 +1,46 @@
+# Note: older development, not ported to fit with new plays!
+---
+- hosts: publishing
+ gather_facts: no
+ connection: local
+ user: root
+ vars:
+ - root: ''
+ - publish_home: $root/mnt/publish
+ # not ideal
+ - keys_dir: $publish_home
+ tasks:
+ - name: Create top-level publishing dir
+ # Home dir must be owned by root for ssh ChrootDirectory to work
+ file: dest=$publish_home state=directory mode=0755 owner=root group=root
+ - name: Create publish group
+ group: name=publish state=present
+ - name: Create publish-copy user
+ user: name=publish-copy comment='Publishing - transfer user'
+ group=publish home=$publish_home
+ generate_ssh_key=yes
+ ssh_key_file=$keys_dir/publish-copy
+ - name: Create publish-trigger user
+ user: name=publish-trigger comment='Publishing - trigger user'
+ group=publish home=$publish_home
+ generate_ssh_key=yes
+ ssh_key_file=$keys_dir/publish-trigger
+ - name: Create upload dir
+ # Actual uploads will happen to this dir
+ # publish-copy should have write access there, publish-trigger
+ # generally only read (cleanup can be handled by cronjob)
+ file: dest=$publish_home/uploads state=directory mode=0755 owner=publish-copy group=publish
+
+
+ - name: Create /etc/ssh/user-authorized-keys/
+ file: dest=$root/etc/ssh/user-authorized-keys/ state=directory mode=0755 owner=root group=root
+
+ - name: Setup publish-copy user SSH restrictions
+ template: src=templates/publish-copy.j2
+ dest=$root/etc/ssh/user-authorized-keys/publish-copy
+ owner=root group=root mode=0644
+
+ - name: Setup publish-trigger user SSH restrictions
+ template: src=templates/publish-trigger.j2
+ dest=$root/etc/ssh/user-authorized-keys/publish-trigger
+ owner=root group=root mode=0644
diff --git a/ansible-deploy/reposeed.yml b/ansible-deploy/reposeed.yml
new file mode 100644
index 0000000..3239f38
--- /dev/null
+++ b/ansible-deploy/reposeed.yml
@@ -0,0 +1,5 @@
+- hosts: reposeed
+ gather_facts: no
+ roles:
+ - common
+ - reposeed
diff --git a/ansible-deploy/roles/apache/files/ssleay.conf b/ansible-deploy/roles/apache/files/ssleay.conf
new file mode 100644
index 0000000..ff79601
--- /dev/null
+++ b/ansible-deploy/roles/apache/files/ssleay.conf
@@ -0,0 +1,9 @@
+RANDFILE = /dev/urandom
+[ req ]
+default_bits = 1024
+default_keyfile = privkey.pem
+distinguished_name = req_distinguished_name
+prompt = no
+policy = policy_anything
+[ req_distinguished_name ]
+commonName = android-build.linaro.org
diff --git a/ansible-deploy/roles/apache/tasks/main.yml b/ansible-deploy/roles/apache/tasks/main.yml
new file mode 100644
index 0000000..bfadc03
--- /dev/null
+++ b/ansible-deploy/roles/apache/tasks/main.yml
@@ -0,0 +1,39 @@
+- name: Install Apache2
+ apt: pkg={{item}}
+ sudo: yes
+ with_items:
+ - apache2
+ - libapache2-mod-wsgi
+- name: Enable Apache modules
+ command: a2enmod {{item}} creates=/etc/apache2/mods-enabled/{{item}}.load
+ sudo: yes
+ with_items:
+ - proxy
+ - proxy_http
+ - headers
+ - rewrite
+ - expires
+ - ssl
+- name: Prepare OpenSSL config
+ copy: src=ssleay.conf dest=/tmp/
+- name: Create self-signed SSL certificate
+ command: openssl req -config /tmp/ssleay.conf -new -x509 -days 3650 -nodes -out {{ssl_cert}} -keyout {{ssl_cert}}
+ creates={{ssl_cert}}
+ sudo: yes
+ notify:
+ - Restart Apache
+- name: Set permissions on certificate
+ file: path={{ssl_cert}} mode=600
+ sudo: yes
+- name: Install Apache site config
+ copy: src=files/apache.conf dest=/etc/apache2/sites-available/{{site_name}}
+ sudo: yes
+ notify:
+ - Restart Apache
+- name: Enable site config
+ command: a2ensite {{item}} creates=/etc/apache2/sites-enabled/{{site_name}}
+ sudo: yes
+ with_items:
+ - "{{site_name}}"
+ notify:
+ - Restart Apache
diff --git a/ansible-deploy/roles/common/handlers/main.yml b/ansible-deploy/roles/common/handlers/main.yml
new file mode 100644
index 0000000..604dd7f
--- /dev/null
+++ b/ansible-deploy/roles/common/handlers/main.yml
@@ -0,0 +1,3 @@
+- name: Restart Apache
+ service: name=apache2 state=restarted
+ sudo: yes
diff --git a/ansible-deploy/roles/common/tasks/main.yml b/ansible-deploy/roles/common/tasks/main.yml
new file mode 100644
index 0000000..62655ca
--- /dev/null
+++ b/ansible-deploy/roles/common/tasks/main.yml
@@ -0,0 +1,10 @@
+- name: Install base packages
+ apt: pkg={{item}}
+ sudo: yes
+ with_items:
+ - bzr
+ - git-core
+ - gnupg
+ - make
+ # ??
+ - python-pycurl
diff --git a/ansible-deploy/roles/frontend/tasks/main.yml b/ansible-deploy/roles/frontend/tasks/main.yml
new file mode 100644
index 0000000..40f02a5
--- /dev/null
+++ b/ansible-deploy/roles/frontend/tasks/main.yml
@@ -0,0 +1,98 @@
+- name: Install Frontend package dependencies
+ apt: pkg={{item}}
+ sudo: yes
+ with_items:
+ - python-virtualenv
+ - python-lxml
+ - python-openid
+ - tidy
+ - unzip
+ - python-cssutils
+
+- name: Create frontend user
+ user: name=build-system-frontend comment="Android Build Frontend"
+ sudo: yes
+
+- name: Create Frontend var dir
+ file: state=directory path=/var/lib/linaro-abs-frontend/ owner=www-data
+ sudo: yes
+
+- name: Install Frontend/Jenkins auth password
+ copy: content={{ lookup('password', cred_store + '/jenkins/frontend') }}
+ dest=/var/lib/linaro-abs-frontend/jenkins-password mode=0640
+ sudo_user: www-data
+ sudo: yes
+
+- name: Check out Frontend
+ bzr: name=$linaro_android_frontend_repo version=$linaro_android_frontend_rev dest=~/frontend-$linaro_android_frontend_rev
+ sudo_user: build-system-frontend
+ sudo: yes
+- name: Create Frontend current version symlink
+ file: state=link src=~/frontend-$linaro_android_frontend_rev/ dest=~/frontend
+ sudo_user: build-system-frontend
+ sudo: yes
+
+- name: Install Frontend
+ shell: cd ~/frontend; make
+ sudo_user: build-system-frontend
+ sudo: yes
+
+- name: Create production config
+ # TODO: actually replace SECRET_KEY
+ template: src=settings_prod.py dest=~build-system-frontend/ mode=0640 owner=build-system-frontend group=www-data
+ sudo: yes
+- name: Create config symlink
+ # wart: relative symlinks not supported
+ file: state=link src=~/settings_prod.py dest=~/frontend/settings_prod.py
+ sudo_user: build-system-frontend
+ sudo: yes
+- name: Create DB
+ shell: cd ~build-system-frontend/frontend; ./bin/manage syncdb --noinput --settings settings_prod
+ sudo_user: www-data
+ sudo: yes
+ # Fixture is automatically installed by syncdb
+ #sudo -u www-data ./bin/manage loaddata --settings settings_prod group-fixture.json
+
+- name: Download YUI3
+ get_url: url=http://yui.zenfs.com/releases/yui3/yui_3.3.0.zip dest=~/yui_3.3.0.zip
+ sudo_user: build-system-frontend
+ sudo: yes
+ register: download_yui3
+- name: Extract YUI3
+ shell: cd ~; unzip -o -q yui_3.3.0.zip
+ sudo_user: build-system-frontend
+ sudo: yes
+ when: download_yui3.changed
+- name: Checkout patched lazr-js
+ bzr: name=lp:~mwhudson/lazr-js/combo-mod_wsgi-config dest=~/lazr-js
+ # version=?
+ sudo_user: build-system-frontend
+ sudo: yes
+- name: Setup lazr-js
+ file: state=directory path=~/lazr-js/{{item}}
+ with_items:
+ - build/3.3.0
+ - build/gallery
+ sudo_user: build-system-frontend
+ sudo: yes
+- name: Setup lazr-js 2
+ file: state=link src=~/yui/build/ dest=~/lazr-js/build/3.3.0/build
+ sudo_user: build-system-frontend
+ sudo: yes
+- name: Setup lazr-js 3
+ file: state=directory path=~/lazr-js/build/gallery/{{item}}
+ with_items:
+ - gallery-overlay-extras
+ - gallery-outside-events
+ - gallery-base64
+ sudo_user: build-system-frontend
+ sudo: yes
+- name: Fetch YUI gallery components
+ get_url: url=http://yui.yahooapis.com/combo?gallery-2010.12.16-18-24/build/{{item}}/{{item}}-min.js
+ dest=~/lazr-js/build/gallery/{{item}}/{{item}}-min.js
+ with_items:
+ - gallery-overlay-extras
+ - gallery-outside-events
+ - gallery-base64
+ sudo_user: build-system-frontend
+ sudo: yes
diff --git a/ansible-deploy/roles/frontend/templates/settings_prod.py b/ansible-deploy/roles/frontend/templates/settings_prod.py
new file mode 100644
index 0000000..ca84ca8
--- /dev/null
+++ b/ansible-deploy/roles/frontend/templates/settings_prod.py
@@ -0,0 +1,12 @@
+from settings import *
+
+MEDIA_URL = '/static/'
+LOGIN_URL = '/openid/login/'
+LOGOUT_URL = '/logout'
+
+DATABASES['default']['NAME'] = '/var/lib/linaro-abs-frontend/session.db'
+
+FRONTEND_JENKINS_USER = 'frontend'
+FRONTEND_JENKINS_PASSWORD = open('/var/lib/linaro-abs-frontend/jenkins-password').read().strip()
+
+SECRET_KEY = '$KEY'
diff --git a/ansible-deploy/roles/jenkins/files/jenkins-config/config.xml b/ansible-deploy/roles/jenkins/files/jenkins-config/config.xml
new file mode 100644
index 0000000..4efa391
--- /dev/null
+++ b/ansible-deploy/roles/jenkins/files/jenkins-config/config.xml
@@ -0,0 +1,77 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<hudson>
+ <version>1.415</version>
+ <numExecutors>0</numExecutors>
+ <mode>NORMAL</mode>
+ <useSecurity>true</useSecurity>
+ <authorizationStrategy class="hudson.security.GlobalMatrixAuthorizationStrategy">
+ <permission>hudson.model.Hudson.Administer:admin</permission>
+ <permission>hudson.model.Hudson.Read:anonymous</permission>
+ <permission>hudson.model.Hudson.Read:frontend</permission>
+ <permission>hudson.model.Item.Build:frontend</permission>
+ <permission>hudson.model.Item.Configure:frontend</permission>
+ <permission>hudson.model.Item.Create:frontend</permission>
+ <permission>hudson.model.Item.Delete:frontend</permission>
+ <permission>hudson.model.Item.Read:anonymous</permission>
+ <permission>hudson.model.Item.Read:frontend</permission>
+ </authorizationStrategy>
+ <securityRealm class="hudson.security.HudsonPrivateSecurityRealm">
+ <disableSignup>false</disableSignup>
+ </securityRealm>
+ <markupFormatter class="hudson.markup.RawHtmlMarkupFormatter"/>
+ <jdks/>
+ <viewsTabBar class="hudson.views.DefaultViewsTabBar"/>
+ <myViewsTabBar class="hudson.views.DefaultMyViewsTabBar"/>
+ <clouds>
+ <hudson.plugins.ec2.EC2Cloud>
+ <name>ec2-US_EAST_1</name>
+ <accessId></accessId>
+ <secretKey>NSdfT2gW7whnbhkIpFcg4Q==</secretKey>
+ <privateKey>
+ <privateKey>NSdfT2gW7whnbhkIpFcg4Q==</privateKey>
+ </privateKey>
+ <instanceCap>10</instanceCap>
+ <templates>
+ <hudson.plugins.ec2.SlaveTemplate>
+ <ami>ami-68ad5201</ami>
+ <description>Natty Release 64bit Instance Store</description>
+ <remoteFS>/mnt/jenkins</remoteFS>
+ <sshPort></sshPort>
+ <type>XLARGE</type>
+ <labels>ec2 natty 64bit</labels>
+ <initScript>{
+apt-get update
+apt-get install -y bzr
+bzr clone lp:linaro-android-build-tools /tmp/build-tools
+time /tmp/build-tools/node/root-setup-android-build-node
+} 2&gt;&amp;1 | tee /tmp/instance-log.txt
+</initScript>
+ <userData></userData>
+ <numExecutors>1</numExecutors>
+ <remoteAdmin>ubuntu</remoteAdmin>
+ <rootCommandPrefix>sudo</rootCommandPrefix>
+ <jvmopts></jvmopts>
+ </hudson.plugins.ec2.SlaveTemplate>
+ </templates>
+ <region>US_EAST_1</region>
+ </hudson.plugins.ec2.EC2Cloud>
+ </clouds>
+ <slaves/>
+ <quietPeriod>5</quietPeriod>
+ <scmCheckoutRetryCount>0</scmCheckoutRetryCount>
+ <views>
+ <hudson.model.AllView>
+ <owner class="hudson" reference="../../.."/>
+ <name>All</name>
+ <filterExecutors>false</filterExecutors>
+ <filterQueue>false</filterQueue>
+ <properties class="hudson.model.View$PropertyList"/>
+ </hudson.model.AllView>
+ </views>
+ <primaryView>All</primaryView>
+ <slaveAgentPort>-1</slaveAgentPort>
+ <label></label>
+ <nodeProperties/>
+ <globalNodeProperties/>
+ <disabledAdministrativeMonitors/>
+</hudson>
diff --git a/ansible-deploy/roles/jenkins/files/jenkins-config/jobs/blank/config.xml b/ansible-deploy/roles/jenkins/files/jenkins-config/jobs/blank/config.xml
new file mode 100644
index 0000000..72bc44e
--- /dev/null
+++ b/ansible-deploy/roles/jenkins/files/jenkins-config/jobs/blank/config.xml
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <actions/>
+ <description></description>
+ <keepDependencies>false</keepDependencies>
+ <properties>
+ <hudson.model.ParametersDefinitionProperty>
+ <parameterDefinitions>
+ <hudson.model.StringParameterDefinition>
+ <name>CONFIG</name>
+ <description></description>
+ <defaultValue></defaultValue>
+ </hudson.model.StringParameterDefinition>
+ </parameterDefinitions>
+ </hudson.model.ParametersDefinitionProperty>
+ </properties>
+ <scm class="hudson.scm.NullSCM"/>
+ <assignedNode>ec2</assignedNode>
+ <canRoam>false</canRoam>
+ <disabled>false</disabled>
+ <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
+ <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
+ <triggers class="vector"/>
+ <concurrentBuild>true</concurrentBuild>
+ <builders>
+ <hudson.tasks.Shell>
+ <command>rm -rf build-tools
+bzr clone lp:linaro-android-build-tools build-tools
+build-tools/node/build &quot;$JENKINS_URL&quot; &quot;$CONFIG&quot;
+</command>
+ </hudson.tasks.Shell>
+ </builders>
+ <publishers>
+ <hudson.tasks.ArtifactArchiver>
+ <artifacts>build/out/target/*/*/*.img,build/out/target/*/*/*.tar.bz2,build/out/*.tar.bz2,build/out/*.xml</artifacts>
+ <latestOnly>false</latestOnly>
+ </hudson.tasks.ArtifactArchiver>
+ </publishers>
+ <buildWrappers/>
+</project> \ No newline at end of file
diff --git a/ansible-deploy/roles/jenkins/files/jenkins-config/users/admin/config.xml b/ansible-deploy/roles/jenkins/files/jenkins-config/users/admin/config.xml
new file mode 100644
index 0000000..4747f35
--- /dev/null
+++ b/ansible-deploy/roles/jenkins/files/jenkins-config/users/admin/config.xml
@@ -0,0 +1,24 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<user>
+ <fullName>Jenkins Admin</fullName>
+ <properties>
+ <hudson.model.MyViewsProperty>
+ <primaryViewName>All</primaryViewName>
+ <views>
+ <hudson.model.AllView>
+ <owner class="hudson.model.MyViewsProperty" reference="../../.."/>
+ <name>All</name>
+ <filterExecutors>false</filterExecutors>
+ <filterQueue>false</filterQueue>
+ <properties class="hudson.model.View$PropertyList"/>
+ </hudson.model.AllView>
+ </views>
+ </hudson.model.MyViewsProperty>
+ <hudson.security.HudsonPrivateSecurityRealm_-Details>
+ <passwordHash>pmqdNw:4a3d61f112ade59bf1e53b2743de44ea68d165490a2b6936bd7ec8f314e43a86</passwordHash>
+ </hudson.security.HudsonPrivateSecurityRealm_-Details>
+ <hudson.tasks.Mailer_-UserProperty>
+ <emailAddress>admin@address.org</emailAddress>
+ </hudson.tasks.Mailer_-UserProperty>
+ </properties>
+</user>
diff --git a/ansible-deploy/roles/jenkins/handlers/main.yml b/ansible-deploy/roles/jenkins/handlers/main.yml
new file mode 100644
index 0000000..de84965
--- /dev/null
+++ b/ansible-deploy/roles/jenkins/handlers/main.yml
@@ -0,0 +1,3 @@
+- name: Restart Jenkins
+ service: name=jenkins state=restarted
+ sudo: yes
diff --git a/ansible-deploy/roles/jenkins/tasks/main.yml b/ansible-deploy/roles/jenkins/tasks/main.yml
new file mode 100644
index 0000000..b50aa3a
--- /dev/null
+++ b/ansible-deploy/roles/jenkins/tasks/main.yml
@@ -0,0 +1,57 @@
+- name: Install Jenkins dependency packages
+ apt: pkg={{item}}
+ sudo: yes
+ with_items:
+ - python-lxml
+ - default-jre
+ - daemon
+- name: Download Jenkins {{jenkins_version}} LTS package
+ get_url: url=http://pkg.jenkins-ci.org/debian-stable/binary/jenkins_{{jenkins_version}}_all.deb
+ dest=/tmp/jenkins_{{jenkins_version}}_all.deb
+- name: Install Jenkins
+ command: dpkg -i --skip-same-version /tmp/jenkins_{{jenkins_version}}_all.deb
+ sudo: yes
+- name: Configure Jenkins port
+ lineinfile: regexp="^HTTP_PORT=" line="HTTP_PORT=9090" dest=/etc/default/jenkins backup=yes
+ sudo: yes
+- name: Configure Jenkins URL prefix
+ # Add --prefix= arg to existing args if not there yet
+ lineinfile: regexp='^JENKINS_ARGS=(?!.*--prefix=/jenkins)"?(.+?)"?$'
+ line='JENKINS_ARGS="\1 --prefix=/jenkins"'
+ dest=/etc/default/jenkins backrefs=yes
+ sudo: yes
+- name: Set up minimal Jenkins configuration
+ # This requires recursive copy patch
+ copy: backup=yes src=jenkins-config/ dest=/var/lib/jenkins/ owner=jenkins
+ sudo: yes
+- name: Create Jenkins plugin dir
+ file: state=directory path=~jenkins/plugins/ owner=jenkins
+ sudo: yes
+- name: Download Jenkins plugins
+ get_url: url={{item}} dest=~jenkins/plugins/ owner=jenkins
+ sudo: yes
+ with_items:
+ - http://updates.jenkins-ci.org/download/plugins/ec2/1.18/ec2.hpi
+ - http://people.linaro.org/~paul.sokolovsky/jenkins/shell-status-20120125.hpi
+ notify:
+ - Restart Jenkins
+
+- name: Generate Frontend/Jenkins auth password
+ copy: content={{ lookup('password', cred_store + '/jenkins/frontend') }}
+ dest=/var/lib/linaro-abs-frontend/jenkins-password mode=0640
+ sudo_user: www-data
+ sudo: yes
+ # with_password leaks password in log
+ #copy: content={{item}} dest=/var/lib/linaro-abs-frontend/jenkins-password
+ #with_password:
+ # - $cred_store/jenkins/frontend
+
+- name: Create Jenkins "frontend" user config
+ template: src=jenkins-config/users/frontend/config.xml
+ dest=/var/lib/jenkins/users/frontend/config.xml owner=jenkins
+ sudo: yes
+
+- name: Create Jenkins external address config
+ template: src=jenkins-config/hudson.tasks.Mailer.xml
+ dest=/var/lib/jenkins/hudson.tasks.Mailer.xml owner=jenkins
+ sudo: yes
diff --git a/ansible-deploy/roles/jenkins/templates/jenkins-config/hudson.tasks.Mailer.xml b/ansible-deploy/roles/jenkins/templates/jenkins-config/hudson.tasks.Mailer.xml
new file mode 100644
index 0000000..5b0b7c3
--- /dev/null
+++ b/ansible-deploy/roles/jenkins/templates/jenkins-config/hudson.tasks.Mailer.xml
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<hudson.tasks.Mailer_-DescriptorImpl>
+ <hudsonUrl>https://{{site_name}}/jenkins/</hudsonUrl>
+ <adminAddress>address not configured yet &lt;nobody@nowhere&gt;</adminAddress>
+ <useSsl>false</useSsl>
+ <charset>UTF-8</charset>
+</hudson.tasks.Mailer_-DescriptorImpl>
diff --git a/ansible-deploy/roles/jenkins/templates/jenkins-config/users/frontend/config.xml b/ansible-deploy/roles/jenkins/templates/jenkins-config/users/frontend/config.xml
new file mode 100644
index 0000000..4ca3b9f
--- /dev/null
+++ b/ansible-deploy/roles/jenkins/templates/jenkins-config/users/frontend/config.xml
@@ -0,0 +1,23 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<user>
+ <fullName>Linaro Cloud Buildd Frontend</fullName>
+ <properties>
+ <hudson.model.MyViewsProperty>
+ <primaryViewName>All</primaryViewName>
+ <views>
+ <hudson.model.AllView>
+ <owner class="hudson.model.MyViewsProperty" reference="../../.."/>
+ <name>All</name>
+ <filterExecutors>false</filterExecutors>
+ <filterQueue>false</filterQueue>
+ </hudson.model.AllView>
+ </views>
+ </hudson.model.MyViewsProperty>
+ <hudson.security.HudsonPrivateSecurityRealm_-Details>
+ <passwordHash>{{ lookup('password', cred_store + '/jenkins/frontend') | jenkins_hash }}</passwordHash>
+ </hudson.security.HudsonPrivateSecurityRealm_-Details>
+ <hudson.tasks.Mailer_-UserProperty>
+ <emailAddress>frontend@address.org</emailAddress>
+ </hudson.tasks.Mailer_-UserProperty>
+ </properties>
+</user> \ No newline at end of file
diff --git a/ansible-deploy/roles/reposeed/tasks/main.yml b/ansible-deploy/roles/reposeed/tasks/main.yml
new file mode 100644
index 0000000..774caff
--- /dev/null
+++ b/ansible-deploy/roles/reposeed/tasks/main.yml
@@ -0,0 +1,3 @@
+- name: Create seed directory
+ file: state=directory path=/mnt2/seed
+ sudo: yes
diff --git a/ansible-deploy/site.yml b/ansible-deploy/site.yml
new file mode 100644
index 0000000..bd2a790
--- /dev/null
+++ b/ansible-deploy/site.yml
@@ -0,0 +1,5 @@
+# Main site file - deploys everything
+---
+- include: jenkins.yml
+- include: frontend.yml
+- include: reposeed.yml