Merge lp:~canonical-isd-hackers/canonical-identity-provider/auto-build-deploy into lp:canonical-identity-provider/release

Proposed by Ricardo Kirkner
Status: Merged
Approved by: Łukasz Czyżykowski
Approved revision: no longer in the source branch.
Merged at revision: 137
Proposed branch: lp:~canonical-isd-hackers/canonical-identity-provider/auto-build-deploy
Merge into: lp:canonical-identity-provider/release
Diff against target: 206 lines (+179/-1)
3 files modified
payload/__init__.py (+1/-0)
payload/upgrade_from_package.py (+177/-0)
payload/virtualenv.py (+1/-1)
To merge this branch: bzr merge lp:~canonical-isd-hackers/canonical-identity-provider/auto-build-deploy
Reviewer Review Type Date Requested Status
Canonical ISD hackers Pending
Review via email: mp+52846@code.launchpad.net

Commit message

add better hudson integration so that builds can automatically be deployed

Description of the change

This branch adds better hudson integration so that builds can automatically be deployed when requested.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'payload/__init__.py'
2--- payload/__init__.py 2011-03-08 19:11:08 +0000
3+++ payload/__init__.py 2011-03-10 13:39:41 +0000
4@@ -14,6 +14,7 @@
5
6 from .virtualenv import *
7 from .postgresql import *
8+from .upgrade_from_package import *
9
10 # make sure the virtualenv is automatically activated
11 setup_virtualenv()
12
13=== added file 'payload/upgrade_from_package.py'
14--- payload/upgrade_from_package.py 1970-01-01 00:00:00 +0000
15+++ payload/upgrade_from_package.py 2011-03-10 13:39:41 +0000
16@@ -0,0 +1,177 @@
17+# -*- coding: utf-8 -*-
18+
19+"""Fabric commands for building a package for a direct server upgrade.
20+
21+The local machine must have bzr-builder and pbuilder, and a lucid chroot
22+setup as the default pbuilder distribution:
23+
24+ $ sudo pbuilder create --distribution lucid
25+
26+"""
27+
28+from __future__ import absolute_import
29+from __future__ import with_statement
30+
31+__metaclass__ = type
32+__all__ = [
33+ 'build_and_install_deb',
34+ 'build_binary_packages',
35+ 'build_source_package',
36+ 'clean_local_branch',
37+ 'install_binary_packages',
38+ 'migrate_database',
39+ 'preflight_check',
40+ 'restart_services',
41+ 'update_configs',
42+ ]
43+
44+import os
45+import shutil
46+import tempfile
47+from datetime import datetime
48+from glob import glob
49+from textwrap import dedent
50+
51+from fabric.api import (
52+ env,
53+ local,
54+ put,
55+ run,
56+ sudo,
57+)
58+from fabric.contrib.files import exists
59+
60+
61+def clean_local_branch():
62+ local("find . -name '*.pyc' -delete")
63+
64+
65+def build_source_package(build_dir, recipe_filename='sso.recipe',
66+ distroseries='lucid'):
67+ clean_local_branch()
68+ # We use a recipe to ensure that we always generate later versions
69+ # with a timestamp. The recipe refers to the local branch '.' rather
70+ # than pulling from the network.
71+ recipe = dedent("""\
72+ # bzr-builder format 0.2 deb-version {debupstream}-0~{revno}+{time}
73+ .""")
74+ recipe_path = os.path.join(build_dir, recipe_filename)
75+ with open(recipe_path, 'w+') as recipe_file:
76+ recipe_file.write(recipe)
77+
78+ local('bzr dailydeb --distribution={0} {1} {2}'.format(
79+ distroseries, recipe_path, build_dir))
80+ dsc_file = glob(os.path.join(build_dir, '*.dsc'))[0]
81+
82+ print("Created source package at {0}.".format(dsc_file))
83+ return dsc_file
84+
85+
86+def build_binary_packages(build_dir, source_dsc):
87+ print("Building binary package for {0}".format(source_dsc))
88+ local('sudo pbuilder build --buildresult {0} {1}'.format(
89+ build_dir, source_dsc))
90+ deb_files = glob(os.path.join(build_dir, "*.deb"))
91+ print("Created binary at {0}.".format(deb_files))
92+ return deb_files
93+
94+
95+def migrate_database(config_dir=None):
96+ if config_dir is None:
97+ # By default, the sso config directory is assumed to be
98+ # /home/username/django_project.
99+ config_dir = 'django_project'
100+ run(config_dir + '/manage.py syncdb')
101+
102+
103+def preflight_check(config_dir='django_project'):
104+ run('COLUMNS=40 %s/manage.py preflight ' % config_dir)
105+
106+
107+def restart_services():
108+ sudo('service apache2 graceful', shell=False)
109+
110+
111+def install_binary_packages(*deb_files):
112+ files = []
113+ for deb_file in deb_files:
114+ put(deb_file, '.')
115+ deb_filename = os.path.basename(deb_file)
116+ files.append(deb_filename)
117+ sudo('dpkg -i {0}'.format(' '.join(files)), shell=False)
118+
119+
120+LOCAL_CONFIG = """
121+[__noschema__]
122+me = %s
123+
124+[__main__]
125+includes = config/staging.cfg
126+ config/uec_local.cfg
127+"""
128+
129+
130+def update_configs(config_branch, config_dir='django_project'):
131+ """Backup current config files and pull in the latest from a bzr branch.
132+
133+ If it exists, local.cfg is left unmodified.
134+ """
135+ timestamp = datetime.utcnow().isoformat()
136+ backup_dir = "%s.backup.%s" % (config_dir, timestamp)
137+ if exists(config_dir):
138+ run("mv %s %s" % (config_dir, backup_dir))
139+ put_bzr_branch(config_branch, config_dir)
140+ if exists(backup_dir + '/local.cfg'):
141+ run("cp %s/local.cfg %s" % (backup_dir, config_dir))
142+ else:
143+ # Create a local.cfg on the server from our template.
144+ local_file, local_path = tempfile.mkstemp()
145+ local_file.write(LOCAL_CONFIG % env.host_string)
146+ local_file.close()
147+ put(local_path, "%s/local.cfg" % config_dir)
148+ os.remove(local_path)
149+
150+
151+def put_bzr_branch(url, name):
152+ """
153+ Copy bazaar branch from launchpad to remote host
154+
155+ This have to be done with local machine as proxy, because remote machine
156+ cannot have access to private projects on launchpad. We don't want to put
157+ there our private ssh keys.
158+
159+ :param url: bazaar url to the branch, it can start with lp:
160+ :type url: str
161+
162+ :param name: name of the directory in which branch will be located remotely
163+ :type name: str
164+
165+ """
166+ local("rm -rf /tmp/%s" % name)
167+
168+ local("bzr branch %s /tmp/%s" % (url, name))
169+ local("cd /tmp && tar cjf %s.tar.bz2 %s" % (name, name))
170+ put("/tmp/%s.tar.bz2" % name, '~/')
171+
172+ local("rm -rf /tmp/%s.tar.bz2 /tmp/%s" % (name, name))
173+
174+ run("tar xjf %s.tar.bz2" % name)
175+
176+
177+def build_and_install_deb(config_branch, build_dir=None, distroseries='lucid'):
178+ delete_dir_after_build = False
179+ if build_dir is None:
180+ build_dir = tempfile.mkdtemp()
181+ delete_dir_after_build = True
182+
183+ dsc_file = build_source_package(build_dir, distroseries=distroseries)
184+ binary_files = build_binary_packages(build_dir, dsc_file)
185+ install_binary_packages(*binary_files)
186+ migrate_database()
187+ update_configs(config_branch)
188+ preflight_check()
189+ restart_services()
190+ print("Package installed and services restarted.")
191+
192+ if delete_dir_after_build:
193+ shutil.rmtree(build_dir, ignore_errors=True)
194
195=== modified file 'payload/virtualenv.py'
196--- payload/virtualenv.py 2011-03-07 17:16:54 +0000
197+++ payload/virtualenv.py 2011-03-10 13:39:41 +0000
198@@ -56,7 +56,7 @@
199
200 def _activate_virtualenv():
201 """Activate the virtualenv."""
202- activate_this = os.path.abspath("%s/bin/activate_this.py" % VIRTUALENV)
203+ activate_this = os.path.abspath("%s/bin/activate_this.py" % env.virtualenv)
204 execfile(activate_this, dict(__file__=activate_this))
205
206 def _create_virtualenv(clear=False):