Merge lp:~cjwatson/launchpad-buildd/charm into lp:launchpad-buildd

Proposed by Colin Watson
Status: Rejected
Rejected by: Colin Watson
Proposed branch: lp:~cjwatson/launchpad-buildd/charm
Merge into: lp:launchpad-buildd
Diff against target: 324 lines (+273/-0)
8 files modified
.bzrignore (+2/-0)
charm/Makefile (+77/-0)
charm/README.md (+59/-0)
charm/config.yaml (+3/-0)
charm/layer.yaml (+13/-0)
charm/metadata.yaml (+21/-0)
charm/reactive/launchpad-buildd.py (+96/-0)
debian/changelog (+2/-0)
To merge this branch: bzr merge lp:~cjwatson/launchpad-buildd/charm
Reviewer Review Type Date Requested Status
Launchpad code reviewers Pending
Review via email: mp+312468@code.launchpad.net

Commit message

Add a Juju charm which can be used to deploy local launchpad-buildd instances.

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) wrote :

Unmerged revisions

213. By Colin Watson

Split out push and push-with-packages targets, since we don't need to push (dummy) resources every time.

212. By Colin Watson

Improve handling of attaching resources after initial deployment.

211. By Colin Watson

Add "push" target.

210. By Colin Watson

Unhold packages before installing them.

209. By Colin Watson

Set ntphost to the empty string rather than removing it entirely, to avoid confusing the postinst.

208. By Colin Watson

Treat zero-sized resources as missing, since the charm store doesn't support truly-optional resources.

207. By Colin Watson

Avoid formatting glitch.

206. By Colin Watson

Add a Juju charm which can be used to deploy local launchpad-buildd
instances.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2015-11-04 14:10:28 +0000
3+++ .bzrignore 2016-12-05 14:48:05 +0000
4@@ -1,5 +1,7 @@
5 *.egg-info
6 *.pyc
7+charm/dist
8+charm/tmp
9 dist
10 debian/files
11 debian/launchpad-buildd
12
13=== added directory 'charm'
14=== added file 'charm/Makefile'
15--- charm/Makefile 1970-01-01 00:00:00 +0000
16+++ charm/Makefile 2016-12-05 14:48:05 +0000
17@@ -0,0 +1,77 @@
18+NAME ?= launchpad-buildd
19+TOPDIR ?= $(CURDIR)/..
20+BUILDDIR ?= $(CURDIR)/dist
21+TMPDIR ?= $(CURDIR)/tmp
22+
23+CHARM_SERIES ?= xenial
24+CHARM_SRC ?= $(CURDIR)
25+JUJU_REPOSITORY = $(BUILDDIR)
26+CHARMDIR = $(BUILDDIR)/$(CHARM_SERIES)/$(NAME)
27+CHARMREPODIR = $(BUILDDIR)/build
28+RESOURCES = $(BUILDDIR)/resources/$(NAME)
29+CHARM = $(CHARMDIR)/.done
30+LAYER_PATH = $(TMPDIR)/layer
31+INTERFACE_PATH = $(TMPDIR)/interface
32+EXTRA_CHARM_BUILD_ARGS ?=
33+DEPLOY_ENV ?= devel
34+CHARM_STORE_URL ?= cs:~launchpad/launchpad-buildd
35+
36+export INTERFACE_PATH
37+export LAYER_PATH
38+export JUJU_REPOSITORY
39+
40+
41+build: $(CHARM)
42+
43+packages: $(RESOURCES)
44+
45+build-with-packages: build packages
46+
47+$(BUILDDIR):
48+ mkdir -p $@
49+
50+$(CHARM): $(CHARM_SRC) | $(BUILDDIR)
51+ rm -rf $(CHARMDIR)
52+ charm build -o $(BUILDDIR) -s $(CHARM_SERIES) -n $(NAME) $(EXTRA_CHARM_BUILD_ARGS)
53+ touch $(CHARMDIR)/dummy-launchpad-buildd.deb
54+ touch $(CHARMDIR)/dummy-python-lpbuildd.deb
55+ touch $@
56+
57+clean:
58+ rm -rf $(BUILDDIR) $(TMPDIR)
59+
60+$(RESOURCES):
61+ rm -rf $(TMPDIR)
62+ mkdir -p $(TMPDIR)
63+ rsync -a --exclude /charm $(TOPDIR)/ $(TMPDIR)/$(NAME)/
64+ cd $(TMPDIR)/$(NAME)/ && debuild -b -uc -us
65+ mkdir -p $(RESOURCES)
66+ cp -a $(TMPDIR)/launchpad-buildd_*.deb \
67+ $(RESOURCES)/launchpad-buildd.deb
68+ cp -a $(TMPDIR)/python-lpbuildd_*.deb $(RESOURCES)/python-lpbuildd.deb
69+
70+create-privileged-model:
71+ juju add-model privileged localhost
72+ lxc profile set juju-privileged security.privileged true
73+
74+deploy:
75+ juju deploy $(CHARMDIR)
76+
77+deploy-with-packages:
78+ juju deploy \
79+ --resource=launchpad-buildd=$(RESOURCES)/launchpad-buildd.deb \
80+ --resource=python-lpbuildd=$(RESOURCES)/python-lpbuildd.deb \
81+ $(CHARMDIR)
82+
83+push:
84+ charm push $(CHARMDIR) $(CHARM_STORE_URL)
85+
86+push-with-packages:
87+ charm push \
88+ --resource=launchpad-buildd=$(CHARMDIR)/dummy-launchpad-buildd.deb \
89+ --resource=python-lpbuildd=$(CHARMDIR)/dummy-python-lpbuildd.deb \
90+ $(CHARMDIR) $(CHARM_STORE_URL)
91+
92+.PHONY: build packages build-with-packages clean
93+.PHONY: create-privileged-model deploy deploy-with-packages
94+.PHONY: push push-with-packages
95
96=== added file 'charm/README.md'
97--- charm/README.md 1970-01-01 00:00:00 +0000
98+++ charm/README.md 2016-12-05 14:48:05 +0000
99@@ -0,0 +1,59 @@
100+# Overview
101+
102+This charm installs a Launchpad builder, which can build packages in
103+response to requests from a Launchpad instance. It is mainly intended for
104+use by Launchpad developers testing changes to builder handling.
105+
106+# Setup
107+
108+Builders need to be able to unpack chroots, which involves being able to
109+create device nodes. Unprivileged LXD containers cannot do this. If you
110+want to use this with the LXD provider, you should therefore do this first:
111+
112+```
113+make create-privileged-model
114+```
115+
116+... or, if you need more control, some variation on this:
117+
118+```
119+juju add-model privileged localhost
120+lxc profile set juju-privileged security.privileged true
121+```
122+
123+# Deployment
124+
125+You can either deploy the stock launchpad-buildd package from a PPA, or
126+build your own.
127+
128+Installing from a PPA is the default; just deploy this charm.
129+
130+If you're building your own package, then you already have the
131+launchpad-buildd code checked out. In the `charm/` subdirectory, build the
132+charm and packages together:
133+
134+```
135+make build-with-packages
136+```
137+
138+Then deploy the charm, attaching the packages as resources:
139+
140+```
141+make deploy-with-packages
142+```
143+
144+Either way, this should eventually give you a running builder. Find out its
145+host name (e.g. `juju-XXXXXX-0.lxd`) and [add it to your local Launchpad
146+instance](https://launchpad.dev/builders/+new) (e.g.
147+`http://juju-XXXXXX-0.lxd:8221/`).
148+
149+# Notes
150+
151+This charm gives you a non-virtualized builder, since there is no reset from
152+a base image between builds; you'll need to make sure that any archives or
153+snaps with builds you intend to dispatch to this builder have the "Require
154+virtualized builders" option disabled.
155+
156+The Launchpad development wiki has [instructions on setting up the rest of
157+Launchpad](https://dev.launchpad.net/Soyuz/HowToUseSoyuzLocally).
158+You can skip the parts about installing the builder.
159
160=== added file 'charm/config.yaml'
161--- charm/config.yaml 1970-01-01 00:00:00 +0000
162+++ charm/config.yaml 2016-12-05 14:48:05 +0000
163@@ -0,0 +1,3 @@
164+options:
165+ install_sources:
166+ default: ppa:launchpad/buildd-staging
167
168=== added file 'charm/layer.yaml'
169--- charm/layer.yaml 1970-01-01 00:00:00 +0000
170+++ charm/layer.yaml 2016-12-05 14:48:05 +0000
171@@ -0,0 +1,13 @@
172+repo: lp:launchpad-buildd
173+includes:
174+ - layer:basic
175+ - layer:apt
176+options:
177+ apt:
178+ packages:
179+ - bzr-builder
180+ - git-build-recipe
181+ - quilt
182+ignore:
183+ - dist
184+ - tmp
185
186=== added file 'charm/metadata.yaml'
187--- charm/metadata.yaml 1970-01-01 00:00:00 +0000
188+++ charm/metadata.yaml 2016-12-05 14:48:05 +0000
189@@ -0,0 +1,21 @@
190+name: launchpad-buildd
191+summary: Launchpad builder
192+description: |
193+ A system that can build packages in response to requests from a
194+ Launchpad instance.
195+tags:
196+ - application_development
197+maintainer: Colin Watson <cjwatson@canonical.com>
198+subordinate: false
199+series:
200+ - xenial
201+resources:
202+ launchpad-buildd:
203+ type: file
204+ filename: launchpad-buildd.deb
205+ description: The main Launchpad builder package.
206+ python-lpbuildd:
207+ type: file
208+ filename: python-lpbuildd.deb
209+ description: Python libraries supporting the Launchpad builder.
210+min-juju-version: 2.0.0
211
212=== added directory 'charm/reactive'
213=== added file 'charm/reactive/launchpad-buildd.py'
214--- charm/reactive/launchpad-buildd.py 1970-01-01 00:00:00 +0000
215+++ charm/reactive/launchpad-buildd.py 2016-12-05 14:48:05 +0000
216@@ -0,0 +1,96 @@
217+# Copyright 2016 Canonical Ltd. This software is licensed under the
218+# GNU Affero General Public License version 3 (see the file LICENSE).
219+
220+from __future__ import print_function
221+
222+import os.path
223+import re
224+import shutil
225+import subprocess
226+
227+from charmhelpers import fetch
228+from charmhelpers.core import (
229+ hookenv,
230+ host,
231+ )
232+from charms.apt import status_set
233+from charms.reactive import (
234+ hook,
235+ only_once,
236+ remove_state,
237+ set_state,
238+ when,
239+ when_not,
240+ )
241+
242+
243+@only_once
244+def install():
245+ with open("/etc/default/launchpad-buildd", "w") as default_file:
246+ print("RUN_NETWORK_REQUESTS_AS_ROOT=yes", file=default_file)
247+ set_state("launchpad-buildd.needs_install")
248+
249+
250+@hook("upgrade-charm", "config-changed")
251+def mark_needs_install():
252+ set_state("launchpad-buildd.needs_install")
253+
254+
255+@when_not("apt.needs_update")
256+@when("launchpad-buildd.needs_install")
257+def install_packages():
258+ cache_dir = os.path.join(hookenv.charm_dir(), "cache")
259+ host.mkdir(cache_dir, perms=0o755)
260+ to_install = []
261+ packages = ["launchpad-buildd", "python-lpbuildd"]
262+ options = ["--option=Dpkg::Options::=--force-confold"]
263+ resource_paths = [hookenv.resource_get(package) for package in packages]
264+ if all(path and os.path.getsize(path) for path in resource_paths):
265+ # Install from resources.
266+ changed = False
267+ for package, resource_path in zip(packages, resource_paths):
268+ local_path = os.path.join(cache_dir, "{}.deb".format(package))
269+ to_install.append((local_path, resource_path))
270+ if host.file_hash(local_path) != host.file_hash(resource_path):
271+ changed = True
272+ if not changed:
273+ return
274+ options.append("--reinstall")
275+ else:
276+ # We don't have resource-provided packages, so just install from the
277+ # PPA.
278+ to_install.extend([(None, package) for package in packages])
279+ new_paths = [new_path for _, new_path in to_install]
280+ try:
281+ status_set(None, "Installing {}".format(",".join(packages)))
282+ fetch.apt_unhold(packages)
283+ fetch.apt_install(new_paths, options=options)
284+ fetch.apt_hold(packages)
285+ except subprocess.CalledProcessError:
286+ status_set(
287+ "blocked",
288+ "Unable to install packages {}".format(",".join(packages)))
289+ else:
290+ for local_path, resource_path in to_install:
291+ if local_path is not None:
292+ shutil.copy2(resource_path, local_path)
293+ # ntp.buildd isn't likely to work outside of the Canonical
294+ # datacentre, and LXD containers can't set the system time. Let's
295+ # just not worry about NTP.
296+ config_path = "/etc/launchpad-buildd/default"
297+ with open(config_path) as config_file:
298+ config = config_file.read()
299+ config = re.sub(r"^ntphost = .*", "ntphost = ", config, flags=re.M)
300+ with open(config_path + ".new", "w") as new_config_file:
301+ new_config_file.write(config)
302+ os.rename(config_path + ".new", config_path)
303+ remove_state("launchpad-buildd.needs_install")
304+ set_state("launchpad-buildd.installed")
305+
306+
307+@when("apt.installed.bzr-builder")
308+@when("apt.installed.git-build-recipe")
309+@when("apt.installed.quilt")
310+@when("launchpad-buildd.installed")
311+def mark_active():
312+ status_set("active", "Builder running")
313
314=== modified file 'debian/changelog'
315--- debian/changelog 2016-11-30 10:20:32 +0000
316+++ debian/changelog 2016-12-05 14:48:05 +0000
317@@ -2,6 +2,8 @@
318
319 * buildsnap: Grant access to the proxy during the build phase as well as
320 during the pull phase (LP: #1642281).
321+ * Add a Juju charm which can be used to deploy local launchpad-buildd
322+ instances.
323
324 -- Colin Watson <cjwatson@ubuntu.com> Fri, 04 Nov 2016 10:47:41 +0000
325

Subscribers

People subscribed via source and target branches

to all changes: