Merge ~lgp171188/launchpad:charming-extract-launchpad-build into launchpad:master

Proposed by Guruprasad
Status: Merged
Approved by: Guruprasad
Approved revision: bcb8af31aa51eb821765f5bd782572d36fc41023
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~lgp171188/launchpad:charming-extract-launchpad-build
Merge into: launchpad:master
Diff against target: 286 lines (+219/-0)
11 files modified
charm/.gitignore (+4/-0)
charm/Makefile (+96/-0)
charm/bundle.yaml.in (+10/-0)
charm/dependencies.txt (+2/-0)
charm/launchpad/charmcraft.yaml (+20/-0)
charm/launchpad/config.yaml (+8/-0)
charm/launchpad/icon.svg (+1/-0)
charm/launchpad/layer.yaml (+15/-0)
charm/launchpad/metadata.yaml (+13/-0)
charm/launchpad/reactive/launchpad.py (+47/-0)
charm/packages.txt (+3/-0)
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+426198@code.launchpad.net

Commit message

Create a basic reactive charm skeleton for Launchpad

This WIP charm uses the ols layer to
* Download and extract the latest Launchpad build artifact from
  the SWIFT storage. It also does the symlink switching for
  deploying a different build.
* Install the requirements.

To post a comment you must log in.
Revision history for this message
Jürgen Gmach (jugmac00) wrote :

> This WIP charm now uses to the ols layer to

=>

> This WIP charm now uses the ols layer to

Revision history for this message
Guruprasad (lgp171188) wrote :

Jürgen, thanks for catching this typo. Fixed now.

Revision history for this message
Guruprasad (lgp171188) :
Revision history for this message
Colin Watson (cjwatson) wrote :

Just deploying "Launchpad" isn't really a coherent thing on its own - we'll want to have `launchpad-appserver`, `launchpad-librarian`, `launchpad-buildd-manager`, etc., and each of those would consist of some common code to put the actual Launchpad code in place plus some service-specific code to do whatever extra bits are needed for each particular deployment type.

To achieve that, I expect we may want to turn this skeleton into a local layer on top of layer:ols (or possibly inline the necessary bits into each service charm if it turns out that the common code is too trivial to be worth bothering with a common layer, but it's probably worth avoiding copying even a dozen lines of code into each service charm if we can). As such I expect we won't retain `charm/launchpad/` in the long run. However, this is fine to land as a starting point for future work.

review: Approve
Revision history for this message
Guruprasad (lgp171188) wrote :

> each of those would consist of some common code to put the actual Launchpad code in place plus some service-specific code to do whatever extra bits are needed for each particular deployment type.
>
> To achieve that, I expect we may want to turn this skeleton into a local layer on top of layer:ols
> (or possibly inline the necessary bits into each service charm if it turns out that the common
> code is too trivial to be worth bothering with a common layer, but it's probably worth avoiding
> copying even a dozen lines of code into each service charm if we can).

The current charm directory does not have any code to do the common service setup and `charm/launchpad/reactive/launchpad.py` just adds a hook for `ols.configured` to loop it in and then just logs 'Hello world!'. The actual work is all done by the configuration passed to the 'ols' layer. So I do not know if we have to add a layer on top of the ols layer to do the same things, unless we want to hard-code some configuration in it to abstract it away from the consumers of the layer.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/charm/.gitignore b/charm/.gitignore
2new file mode 100644
3index 0000000..da831d3
4--- /dev/null
5+++ b/charm/.gitignore
6@@ -0,0 +1,4 @@
7+*.charm
8+bundle.yaml
9+dist
10+tmp
11diff --git a/charm/Makefile b/charm/Makefile
12new file mode 100644
13index 0000000..de55a73
14--- /dev/null
15+++ b/charm/Makefile
16@@ -0,0 +1,96 @@
17+# The charmcraft tool is shipped as a snap, so make sure it's on $PATH.
18+export PATH := $(PATH):/snap/bin
19+
20+APP_NAME := launchpad
21+
22+BUILDDIR := $(CURDIR)/dist
23+TMPDIR := $(CURDIR)/tmp
24+CHARM_LAYERS_DIR := $(TMPDIR)/deps/ols-layers/layer
25+CHARM_INTERFACES_DIR := $(TMPDIR)/deps/ols-layers/interface
26+
27+CHARM_SERIES ?= 18.04
28+ARCH := $(shell dpkg --print-architecture)
29+charm_file = $(1)_ubuntu-$(CHARM_SERIES)-$(ARCH).charm
30+
31+BUILD_LABEL = $(shell git rev-parse HEAD)
32+TARBALL = $(APP_NAME).tar.gz
33+ASSET = ../build/$(BUILD_LABEL)/$(TARBALL)
34+
35+CHARMS := launchpad
36+
37+all: ## alias to build
38+all: build
39+
40+help: ## display this help message
41+ @echo "Please use \`make <target>' where <target> is one of"
42+ @grep '^[a-zA-Z]' $(MAKEFILE_LIST) | sort | awk -F ':.*?## ' 'NF==2 {printf "\033[36m %-25s\033[0m %s\n", $$1, $$2}'
43+
44+$(BUILDDIR) $(TMPDIR):
45+ @mkdir -p $@
46+
47+# We have to clone our dependencies by hand rather than letting charmcraft
48+# do it, since some of them are in private repositories and charmcraft
49+# doesn't have suitable credentials.
50+CHARM_DEPS := $(CHARM_LAYERS_DIR)/.done $(CHARM_INTERFACES_DIR)/.done
51+$(CHARM_DEPS): $(CURDIR)/dependencies.txt | $(TMPDIR)
52+ @echo "Fetching dependencies..."
53+ @mkdir -p $(TMPDIR)/deps
54+ @cd $(TMPDIR)/deps && codetree $<
55+ @touch $(CHARM_DEPS)
56+
57+build: ## build all the charms
58+build: $(foreach charm,$(CHARMS),build-$(charm))
59+
60+build-launchpad: ## build the launchpad charm
61+build-launchpad: dist/$(call charm_file,launchpad)
62+
63+dist/%_ubuntu-$(CHARM_SERIES)-$(ARCH).charm: $(CHARM_DEPS) | $(BUILDDIR)
64+ @echo "Building $*..."
65+ @rm -rf $*/tmp
66+ @cp -a tmp $*/tmp
67+ @cd $* && charmcraft pack
68+ @cp -a $*/$(call charm_file,$*) dist/
69+ @rm -rf $*/tmp
70+
71+clean: ## clean the build environment
72+clean: $(foreach charm,$(CHARMS),clean-$(charm))
73+ @find . -name \*.pyc -delete
74+ @find . -depth -name '__pycache__' -exec rm -rf '{}' \;
75+ @rm -f bundle.yaml
76+ @rm -f layer/*/codetree-collect-info.yaml
77+ @rm -rf $(BUILDDIR) $(TMPDIR)
78+
79+clean-%:
80+ @echo "Cleaning $*..."
81+ @cd $* && charmcraft clean
82+ @rm -f dist/$(call charm_file,$*)
83+
84+bundle.yaml: ## create the bundle.yaml file from the bundle.yaml.in template
85+bundle.yaml: bundle.yaml.in
86+ sed \
87+ -e 's/%BUILD_LABEL%/$(BUILD_LABEL)/g' \
88+ bundle.yaml.in >bundle.yaml
89+
90+deploy: ## deploy the built charm
91+deploy: build bundle.yaml
92+ @echo "Deploying $(APP_NAME)..."
93+ @juju deploy ./bundle.yaml
94+
95+payload: ## build a launchpad tarball
96+payload: $(ASSET)
97+$(ASSET):
98+ @echo "Building asset for $(BUILD_LABEL)..."
99+ @$(MAKE) -C .. build-tarball
100+
101+
102+setup-jenkaas: ## prepare a Jenkins-as-a-service container for charm building
103+setup-jenkaas:
104+ sudo systemctl stop snapd.socket
105+ sudo systemctl stop snapd
106+ echo SNAPPY_STORE_NO_CDN=1 | sudo tee -a /etc/environment >/dev/null
107+ echo SNAPPY_TESTING=1 | sudo tee -a /etc/environment >/dev/null
108+ sudo systemctl start snapd.socket
109+ sudo snap install --classic charm
110+
111+.PHONY: $(foreach charm,$(CHARMS),build-$(charm))
112+.PHONY: all build clean deploy payload setup-jenkaas
113diff --git a/charm/bundle.yaml.in b/charm/bundle.yaml.in
114new file mode 100644
115index 0000000..82244f1
116--- /dev/null
117+++ b/charm/bundle.yaml.in
118@@ -0,0 +1,10 @@
119+series: bionic
120+description: "Launchpad development bundle"
121+applications:
122+ launchpad:
123+ charm: ./dist/launchpad_ubuntu-18.04-amd64.charm
124+ num_units: 1
125+ options:
126+ build_label: "%BUILD_LABEL%"
127+ swift_storage_url: "https://radosgw.ps5.canonical.com/swift/v1/AUTH_318a449e4c8e40e2865c120a597a9644"
128+ swift_container_name: "launchpad-builds"
129diff --git a/charm/dependencies.txt b/charm/dependencies.txt
130new file mode 100644
131index 0000000..a4a6420
132--- /dev/null
133+++ b/charm/dependencies.txt
134@@ -0,0 +1,2 @@
135+ols-layers git+ssh://git.launchpad.net/~ubuntuone-pqm-team/ols-charm-deps/+git/ols-layers;revno=df20c87d
136+charm-wheels git+ssh://git.launchpad.net/~ubuntuone-hackers/ols-charm-deps/+git/wheels;revno=fe523e25
137diff --git a/charm/launchpad/charmcraft.yaml b/charm/launchpad/charmcraft.yaml
138new file mode 100644
139index 0000000..5b50137
140--- /dev/null
141+++ b/charm/launchpad/charmcraft.yaml
142@@ -0,0 +1,20 @@
143+type: charm
144+bases:
145+ - build-on:
146+ - name: ubuntu
147+ channel: "18.04"
148+ run-on:
149+ - name: ubuntu
150+ channel: "18.04"
151+parts:
152+ launchpad:
153+ source: .
154+ plugin: reactive
155+ build-snaps: [charm]
156+ build-environment:
157+ - CHARM_LAYERS_DIR: tmp/deps/ols-layers/layer
158+ - CHARM_INTERFACES_DIR: tmp/deps/ols-layers/interface
159+ - PIP_NO_INDEX: "true"
160+ - PIP_FIND_LINKS: tmp/deps/charm-wheels
161+ stage:
162+ - -tmp
163diff --git a/charm/launchpad/config.yaml b/charm/launchpad/config.yaml
164new file mode 100644
165index 0000000..adc4e2c
166--- /dev/null
167+++ b/charm/launchpad/config.yaml
168@@ -0,0 +1,8 @@
169+options:
170+ # layer-apt
171+ install_sources:
172+ default: |
173+ - ppa:launchpad/ppa
174+ install_keys:
175+ default: |
176+ - null # PPA keys securely added via Launchpad.
177diff --git a/charm/launchpad/icon.svg b/charm/launchpad/icon.svg
178new file mode 100644
179index 0000000..b2889cc
180--- /dev/null
181+++ b/charm/launchpad/icon.svg
182@@ -0,0 +1 @@
183+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 165.39062 165.39062"><defs><style>.cls-1{fill:#e9500e;}.cls-2{fill:#fff;}</style></defs><rect class="cls-1" width="165.39062" height="165.39062"/><path class="cls-2" d="M29.63876,57.97189C43.189,67.692,61.13456,69.25577,77.65457,62.15038c16.25576-6.87157,27.74036-21.43444,29.97828-38.0075.04663-.34331.11016-.81367-1.59861-1.24044l-10.10934-2.197c-.3254-.04494-.79136-.04967-1.15258,1.22455C91.37844,36.07384,84.34062,45.04243,72.6347,50.1123c-11.77316,5.10029-23.18748,4.05279-35.91893-3.29386-.58119-.27843-.91909-.26086-1.45568.52577l-5.77947,8.65163A1.34512,1.34512,0,0,0,29.63876,57.97189Z" transform="translate(0.39062 0.39062)"/><path class="cls-2" d="M79.86106,139.66026l10.3631.565c1.74155.03446,1.79122-.42981,1.83717-.77312,2.23826-16.5734-4.97222-33.66107-18.81739-44.59422C59.196,83.62132,41.47815,80.36935,25.83365,86.14747a1.33956,1.33956,0,0,0-.67918,1.85373l3.28,9.88226c.30952.90153.62816,1.011,1.26443.89409,14.22464-3.70543,25.50717-1.68748,35.50635,6.3512,9.94174,7.9934,14.34865,18.50754,13.86883,33.08867C79.08524,139.50144,79.53735,139.615,79.86106,139.66026Z" transform="translate(0.39062 0.39062)"/><path class="cls-2" d="M86.50488,70.59048a10.50817,10.50817,0,0,0-1.39587-.09461A9.35237,9.35237,0,0,0,79.39915,72.382a9.61981,9.61981,0,1,0,7.10573-1.79156Z" transform="translate(0.39062 0.39062)"/><path class="cls-2" d="M138.26869,53.18923,133.457,43.97736c-.68628-1.51583-1.22793-1.36985-1.79594-1.17657-15.382,6.63165-25.99848,21.22156-28.40434,39.03776-2.40755,17.82971,3.97169,34.72681,17.0647,45.19906a1.177,1.177,0,0,0,.90794.32844,1.48362,1.48362,0,0,0,.99546-.54l6.76175-8.11166c.62342-.78393.35783-1.18333.0321-1.52461-10.60639-10.44454-14.5764-20.81677-12.84905-33.60769,1.73682-12.86121,8.51918-22.08254,21.34457-29.019C138.52854,53.95289,138.36533,53.421,138.26869,53.18923Z" transform="translate(0.39062 0.39062)"/></svg>
184\ No newline at end of file
185diff --git a/charm/launchpad/layer.yaml b/charm/launchpad/layer.yaml
186new file mode 100644
187index 0000000..ae16aa0
188--- /dev/null
189+++ b/charm/launchpad/layer.yaml
190@@ -0,0 +1,15 @@
191+includes:
192+ - layer:basic
193+ - layer:ols
194+options:
195+ apt:
196+ packages:
197+ - launchpad-dependencies
198+ ols:
199+ service_name: launchpad
200+ config_filename: service.conf
201+ user: launchpad
202+ tarball_payload: true
203+ symlink_switch_payload: true
204+ python_bin: /usr/bin/python3
205+repo: https://git.launchpad.net/launchpad
206diff --git a/charm/launchpad/metadata.yaml b/charm/launchpad/metadata.yaml
207new file mode 100644
208index 0000000..79f06eb
209--- /dev/null
210+++ b/charm/launchpad/metadata.yaml
211@@ -0,0 +1,13 @@
212+name: launchpad
213+display-name: launchpad
214+summary: Launchpad web application
215+maintainer: Guruprasad <guruprasad.ln@canonical.com>
216+description: |
217+ Launchpad is an open source suite of tools that help people and teams
218+ to work together on software projects.
219+tags:
220+ # https://juju.is/docs/charm-metadata#heading--charm-store-fields
221+ - network
222+series:
223+ - bionic
224+subordinate: false
225diff --git a/charm/launchpad/reactive/launchpad.py b/charm/launchpad/reactive/launchpad.py
226new file mode 100644
227index 0000000..7cdf698
228--- /dev/null
229+++ b/charm/launchpad/reactive/launchpad.py
230@@ -0,0 +1,47 @@
231+# Copyright 2022 Canonical Ltd. This software is licensed under the
232+# GNU Affero General Public License version 3 (see the file LICENSE).
233+
234+import subprocess
235+
236+from charmhelpers.core import hookenv
237+from charms.reactive import (
238+ remove_state,
239+ set_state,
240+ when,
241+ when_not,
242+ )
243+from ols import base
244+
245+
246+# Monkey-patch layer:ols.
247+def create_virtualenv(wheels_dir, codedir, python_exe):
248+ subprocess.run(
249+ ['make', 'compile', 'PYTHON={}'.format(python_exe)],
250+ cwd=codedir, check=True)
251+
252+
253+base.create_virtualenv = create_virtualenv
254+
255+
256+@when('ols.configured')
257+@when_not('service.configured')
258+def configure():
259+ hookenv.log('Hello world!')
260+ set_state('service.configured')
261+
262+
263+@when('service.configured')
264+def check_is_running():
265+ hookenv.status_set('active', 'Ready')
266+
267+
268+@when('config.changed.build_label')
269+def build_label_changed():
270+ remove_state('ols.service.installed')
271+ remove_state('ols.configured')
272+ remove_state('service.configured')
273+
274+
275+@when('config.changed')
276+def config_changed():
277+ remove_state('service.configured')
278diff --git a/charm/packages.txt b/charm/packages.txt
279new file mode 100644
280index 0000000..c33fce5
281--- /dev/null
282+++ b/charm/packages.txt
283@@ -0,0 +1,3 @@
284+flake8
285+python-codetree
286+squashfuse

Subscribers

People subscribed via source and target branches

to status/vote changes: