Merge lp:~ev/ubuntu-ci-services-itself/phase0-ppa into lp:ubuntu-ci-services-itself

Proposed by Evan
Status: Merged
Approved by: Chris Johnston
Approved revision: 277
Merged at revision: 290
Proposed branch: lp:~ev/ubuntu-ci-services-itself/phase0-ppa
Merge into: lp:ubuntu-ci-services-itself
Diff against target: 345 lines (+249/-7)
9 files modified
charms/precise/rabbitmq-worker/Makefile (+24/-0)
charms/precise/rabbitmq-worker/charm-helpers.yaml (+4/-0)
charms/precise/rabbitmq-worker/cm.py (+172/-0)
charms/precise/rabbitmq-worker/config-manager.txt (+5/-0)
charms/precise/rabbitmq-worker/config.yaml (+25/-0)
charms/precise/rabbitmq-worker/hooks/hooks.py (+4/-1)
juju-deployer/branch-source-builder.yaml.tmpl (+5/-2)
juju-deployer/image-builder.yaml.tmpl (+5/-2)
juju-deployer/test-runner.yaml.tmpl (+5/-2)
To merge this branch: bzr merge lp:~ev/ubuntu-ci-services-itself/phase0-ppa
Reviewer Review Type Date Requested Status
Andy Doan (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+208811@code.launchpad.net

Commit message

- Bring charmhelpers into the rabbitmq-worker charm.
- Use PPA versions of the dependencies for the bsb, image builder, and test runner components.

Description of the change

This kills the remaining installs of pip packages to the production deployment. This ensures that if pypi goes down or the egg has a flaky install routine, we're still able to get through a deployment.

By using a "release" PPA, we ensure a predictable and reproducible environment by sticking to the same dependency versions unless we explicitly upload a new one.

- Bring charmhelpers into the rabbitmq-worker charm.
- Use PPA versions of the dependencies for the bsb, image builder, and test runner components.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:277
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~ev/ubuntu-ci-services-itself/phase0-ppa/+merge/208811/+edit-commit-message

http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/250/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/250/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:277
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/251/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/251/rebuild

review: Approve (continuous-integration)
Revision history for this message
Andy Doan (doanac) wrote :

makes me so happy.

NOTE: we have one pip dependency still lurking here:

 http://bazaar.launchpad.net/~ev/ubuntu-ci-services-itself/phase0-ppa/view/head:/charms/precise/restish/hooks/hooks.py#L93

but we can probably treat that in a separate MP

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'charms/precise/rabbitmq-worker/Makefile'
2--- charms/precise/rabbitmq-worker/Makefile 1970-01-01 00:00:00 +0000
3+++ charms/precise/rabbitmq-worker/Makefile 2014-02-28 14:19:37 +0000
4@@ -0,0 +1,24 @@
5+PWD := $(shell pwd)
6+SOURCEDEPS_DIR ?= $(shell dirname $(PWD))/.sourcecode
7+PYTHON := /usr/bin/env python
8+CONFIGMANAGER := $(PWD)/bin/cm.py
9+
10+
11+sourcedeps: $(PWD)/config-manager.txt clean
12+ @echo Updating source dependencies...
13+ @$(PYTHON) cm.py -c $(PWD)/config-manager.txt \
14+ -p $(SOURCEDEPS_DIR) \
15+ -t $(PWD)
16+ @$(PYTHON) build/charm-helpers/tools/charm_helpers_sync/charm_helpers_sync.py \
17+ -c charm-helpers.yaml \
18+ -b build/charm-helpers \
19+ -d hooks/charmhelpers
20+ @echo Do not forget to commit the updated files if any.
21+ #@cd $(PWD)/build/charm-helpers; \
22+ #@$(PYTHON) setup.py install --install-purelib=$(PWD)/lib \
23+ #--install-scripts=$(PWD)/lib/bin
24+
25+clean:
26+ rm -fr hooks/charmhelpers build/charm-helpers ../.sourcecode
27+
28+.PHONY: sourcedeps
29
30=== added directory 'charms/precise/rabbitmq-worker/build'
31=== added file 'charms/precise/rabbitmq-worker/charm-helpers.yaml'
32--- charms/precise/rabbitmq-worker/charm-helpers.yaml 1970-01-01 00:00:00 +0000
33+++ charms/precise/rabbitmq-worker/charm-helpers.yaml 2014-02-28 14:19:37 +0000
34@@ -0,0 +1,4 @@
35+include:
36+ - core
37+ - fetch
38+ - contrib.charmsupport
39
40=== added file 'charms/precise/rabbitmq-worker/cm.py'
41--- charms/precise/rabbitmq-worker/cm.py 1970-01-01 00:00:00 +0000
42+++ charms/precise/rabbitmq-worker/cm.py 2014-02-28 14:19:37 +0000
43@@ -0,0 +1,172 @@
44+# Copyright 2014 Canonical Ltd. All rights reserved.
45+
46+import os
47+import re
48+import sys
49+import errno
50+import hashlib
51+import subprocess
52+import optparse
53+import urllib
54+
55+from os import curdir
56+from bzrlib.branch import Branch
57+from bzrlib.plugin import load_plugins
58+load_plugins()
59+from bzrlib.plugins.launchpad import account as lp_account
60+
61+if 'GlobalConfig' in dir(lp_account):
62+ from bzrlib.config import LocationConfig as LocationConfiguration
63+ _ = LocationConfiguration
64+else:
65+ from bzrlib.config import LocationStack as LocationConfiguration
66+ _ = LocationConfiguration
67+
68+
69+def get_ubunet_branch_config(config_file):
70+ """
71+ Retrieves the sourcedeps configuration for an ubunet source dir.
72+ Returns a dict of (branch, revspec) tuples, keyed by branch name.
73+ """
74+ branches = {}
75+ with open(config_file, 'r') as stream:
76+ for line in stream:
77+ line = line.split('#')[0].strip()
78+ match = re.match(r'(\S+)\s+'
79+ 'bzr\+ssh://([^/]+)/([^;]+)'
80+ '(?:;revno=(\d+))?', line)
81+ if match:
82+ name, host, branch, revno = match.group(1, 2, 3, 4)
83+ if revno is None:
84+ revspec = "-1"
85+ else:
86+ revspec = revno
87+ branches[name] = (host, branch, revspec)
88+ return branches
89+
90+
91+def main(config_file, parent_dir, target_dir, verbose):
92+ """Do the deed."""
93+
94+ try:
95+ os.makedirs(parent_dir)
96+ except OSError, e:
97+ if e.errno != errno.EEXIST:
98+ raise
99+
100+ bzr_config = LocationConfiguration(parent_dir)
101+ get_lp_login = lp_account.get_lp_login
102+ username = get_lp_login(bzr_config) or get_lp_login()
103+ if username is None:
104+ raise RuntimeError("Unable to determine launchpad login")
105+ quoted_username = urllib.quote(username)
106+
107+ branches = sorted(get_ubunet_branch_config(config_file).iteritems())
108+ for branch_name, (host, quoted_branch_spec, revspec) in branches:
109+ revno = int(revspec)
110+
111+ # qualify mirror branch name with hash of remote repo path to deal
112+ # with changes to the remote branch URL over time
113+ branch_spec_digest = hashlib.sha1(quoted_branch_spec).hexdigest()
114+ branch_directory = branch_spec_digest
115+
116+ source_path = os.path.join(parent_dir, branch_directory)
117+ destination_path = os.path.join(target_dir, branch_name)
118+
119+ # Remove leftover symlinks/stray files.
120+ try:
121+ os.remove(destination_path)
122+ except OSError, e:
123+ if e.errno != errno.EISDIR and e.errno != errno.ENOENT:
124+ raise
125+
126+ branch_url = ("bzr+ssh://%s@%s/%s" %
127+ (quoted_username, host, quoted_branch_spec))
128+ lp_url = "lp:" + quoted_branch_spec.replace("+branch/", "")
129+
130+ # Create the local mirror branch if it doesn't already exist
131+ if verbose:
132+ sys.stderr.write('%30s: ' % (branch_name,))
133+ sys.stderr.flush()
134+
135+ fresh = False
136+ if not os.path.exists(source_path):
137+ subprocess.check_call(['bzr', 'branch', '-q',
138+ '--', branch_url, source_path])
139+ fresh = True
140+
141+ source_branch = Branch.open(source_path)
142+
143+ # Freshen the source branch if required (-1 means we want tip).
144+ if not fresh and (revno == -1 or revno > source_branch.revno()):
145+ subprocess.check_call(['bzr', 'pull', '-q', '--overwrite', '-r',
146+ str(revno), '-d', source_path,
147+ '--', branch_url])
148+
149+ if os.path.exists(destination_path):
150+ # Overwrite the destination with the appropriate revision.
151+ subprocess.check_call(['bzr', 'clean-tree', '--force', '-q',
152+ '--ignored', '-d', destination_path])
153+ subprocess.check_call(['bzr', 'pull', '-q', '--overwrite',
154+ '-r', str(revno),
155+ '-d', destination_path, '--', source_path])
156+ else:
157+ # Create a new branch.
158+ subprocess.check_call(['bzr', 'branch', '-q', '--hardlink',
159+ '-r', str(revno),
160+ '--', source_path, destination_path])
161+
162+ # Check the state of the destination branch.
163+ destination_branch = Branch.open(destination_path)
164+ destination_revno = destination_branch.revno()
165+
166+ if verbose:
167+ sys.stderr.write('checked out %4s of %s\n' %
168+ ("r" + str(destination_revno), lp_url))
169+ sys.stderr.flush()
170+
171+ if revno != -1 and destination_revno != revno:
172+ raise RuntimeError("Expected revno %d but got revno %d" %
173+ (revno, destination_revno))
174+
175+if __name__ == '__main__':
176+ parser = optparse.OptionParser(
177+ usage="%prog [options]",
178+ description=(
179+ "Add a lightweight checkout in <target> for each "
180+ "corresponding file in <parent>."),
181+ add_help_option=False)
182+ parser.add_option(
183+ '-p', '--parent', dest='parent', default=None,
184+ help=("The directory of the parent tree."),
185+ metavar="DIR")
186+ parser.add_option(
187+ '-t', '--target', dest='target', default=curdir,
188+ help=("The directory of the target tree."),
189+ metavar="DIR")
190+ parser.add_option(
191+ '-c', '--config', dest='config', default=None,
192+ help=("The config file to be used for config-manager."),
193+ metavar="DIR")
194+ parser.add_option(
195+ '-q', '--quiet', dest='verbose', action='store_false',
196+ help="Be less verbose.")
197+ parser.add_option(
198+ '-h', '--help', action='help',
199+ help="Show this help message and exit.")
200+ parser.set_defaults(verbose=True)
201+
202+ options, args = parser.parse_args()
203+
204+ if options.parent is None:
205+ parser.error(
206+ "Parent directory not specified.")
207+
208+ if options.target is None:
209+ parser.error(
210+ "Target directory not specified.")
211+
212+ sys.exit(main(config_file=options.config,
213+ parent_dir=options.parent,
214+ target_dir=options.target,
215+ verbose=options.verbose))
216
217=== added file 'charms/precise/rabbitmq-worker/config-manager.txt'
218--- charms/precise/rabbitmq-worker/config-manager.txt 1970-01-01 00:00:00 +0000
219+++ charms/precise/rabbitmq-worker/config-manager.txt 2014-02-28 14:19:37 +0000
220@@ -0,0 +1,5 @@
221+# After making changes to this file, to ensure that the charm payload
222+# is up-to-date do:
223+#
224+# make
225+build/charm-helpers bzr+ssh://bazaar.launchpad.net/~charm-helpers/charm-helpers/devel;revno=99
226
227=== modified file 'charms/precise/rabbitmq-worker/config.yaml'
228--- charms/precise/rabbitmq-worker/config.yaml 2014-02-17 10:13:29 +0000
229+++ charms/precise/rabbitmq-worker/config.yaml 2014-02-28 14:19:37 +0000
230@@ -51,3 +51,28 @@
231 type: string
232 default: '/'
233 description: The vhost in the rabbitMQ server.
234+
235+ # Apt
236+ install_sources:
237+ type: string
238+ default: ""
239+ description: |
240+ YAML list of additional installation sources, as a string. The number
241+ of install_sources must match the number of install_keys. For
242+ example:
243+ install_sources: |
244+ - ppa:project1/ppa
245+ - ppa:project2/ppa
246+ install_keys:
247+ type: string
248+ default: ""
249+ description: |
250+ YAML list of GPG keys for installation sources, as a string. For apt
251+ repository URLs, use the public key ID used to verify package
252+ signatures. For other sources such as PPA, use empty string. This
253+ list must have the same number of elements as install_sources, even
254+ if the key items are all empty string. An example to go with the
255+ above for install_sources:
256+ install_keys: |
257+ - ""
258+ - ""
259
260=== modified file 'charms/precise/rabbitmq-worker/hooks/hooks.py'
261--- charms/precise/rabbitmq-worker/hooks/hooks.py 2014-02-17 10:13:29 +0000
262+++ charms/precise/rabbitmq-worker/hooks/hooks.py 2014-02-28 14:19:37 +0000
263@@ -7,6 +7,7 @@
264 import subprocess
265 import sys
266 import textwrap
267+import charmhelpers.fetch
268
269
270 def juju_info(msg):
271@@ -80,13 +81,15 @@
272
273
274 def install(config):
275+ charmhelpers.fetch.configure_sources(update=True)
276+
277 pkgs = [x for x in config.get('packages', '').split(' ') if x]
278 pkgs.append('python-amqplib')
279 pkgs.append('python-pip')
280 pkgs.append('bzr')
281
282 juju_info('installing apt packages...')
283- subprocess.check_call(['apt-get', 'install', '-y', '-q'] + pkgs)
284+ charmhelpers.fetch.apt_install(pkgs)
285
286 pip_pkgs = [x for x in config.get('pip-packages', '').split(' ') if x]
287 if pip_pkgs:
288
289=== modified file 'juju-deployer/branch-source-builder.yaml.tmpl'
290--- juju-deployer/branch-source-builder.yaml.tmpl 2014-02-18 23:43:39 +0000
291+++ juju-deployer/branch-source-builder.yaml.tmpl 2014-02-28 14:19:37 +0000
292@@ -23,8 +23,11 @@
293 branch: ${CI_BRANCH}
294 tarball: ${CI_PAYLOAD_URL}
295 unit-config: include-base64://configs/unit_config.yaml
296- packages: dput
297- pip-packages: dput
298+ packages: "dput python-dput"
299+ install_sources: |
300+ - ${CI_PPA}
301+ install_keys: |
302+ - ""
303 rabbit:
304 branch: lp:~canonical-ci-engineering/charms/precise/ubuntu-ci-services-itself/rabbitmq-server@46
305 charm: rabbitmq
306
307=== modified file 'juju-deployer/image-builder.yaml.tmpl'
308--- juju-deployer/image-builder.yaml.tmpl 2014-02-26 05:13:02 +0000
309+++ juju-deployer/image-builder.yaml.tmpl 2014-02-28 14:19:37 +0000
310@@ -23,10 +23,13 @@
311 vcs: ${CI_CODE_SOURCE}
312 branch: ${CI_BRANCH}
313 tarball: ${CI_PAYLOAD_URL}
314- packages: "qemu-utils"
315- pip-packages: "python-glanceclient python-swiftclient==1.8.0"
316+ packages: "qemu-utils python-glanceclient python-swiftclient"
317 uid: root
318 unit-config: include-base64://configs/unit_config.yaml
319+ install_sources: |
320+ - ${CI_PPA}
321+ install_keys: |
322+ - ""
323 rabbit:
324 branch: lp:~canonical-ci-engineering/charms/precise/ubuntu-ci-services-itself/rabbitmq-server@46
325 charm: rabbitmq
326
327=== modified file 'juju-deployer/test-runner.yaml.tmpl'
328--- juju-deployer/test-runner.yaml.tmpl 2014-02-19 23:49:36 +0000
329+++ juju-deployer/test-runner.yaml.tmpl 2014-02-28 14:19:37 +0000
330@@ -30,10 +30,13 @@
331 vcs: ${CI_CODE_SOURCE}
332 branch: ${CI_BRANCH}
333 tarball: ${CI_PAYLOAD_URL}
334- packages: "python-requests"
335- pip-packages: "python-novaclient python-swiftclient==1.8.0"
336+ packages: "python-requests python-novaclient python-swiftclient"
337 unit-config: include-base64://configs/unit_config.yaml
338 uid: root
339+ install_sources: |
340+ - ${CI_PPA}
341+ install_keys: |
342+ - ""
343 rabbit:
344 branch: lp:~canonical-ci-engineering/charms/precise/ubuntu-ci-services-itself/rabbitmq-server@46
345 charm: rabbitmq

Subscribers

People subscribed via source and target branches

to all changes: