Merge lp:~tcuthbert/mojo/mojo-specs-rt116682 into lp:mojo/mojo-specs

Proposed by Thomas Cuthbert
Status: Merged
Approved by: Barry Price
Approved revision: 130
Merged at revision: 130
Proposed branch: lp:~tcuthbert/mojo/mojo-specs-rt116682
Merge into: lp:mojo/mojo-specs
Diff against target: 275 lines (+236/-2)
4 files modified
mojo-how-to/manifest (+2/-2)
mojo-how-to/production/relations (+2/-0)
mojo-how-to/scripts/utils/configure-apache2-vhosts-autocert (+40/-0)
mojo-how-to/scripts/utils/juju-act (+192/-0)
To merge this branch: bzr merge lp:~tcuthbert/mojo/mojo-specs-rt116682
Reviewer Review Type Date Requested Status
Barry Price Approve
Review via email: mp+362658@code.launchpad.net

Commit message

Amendments based on the mojo.c.c deployment, cRT#116682

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Barry Price (barryprice) wrote :

+1

review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision 130

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'mojo-how-to/manifest'
2--- mojo-how-to/manifest 2019-02-04 04:28:17 +0000
3+++ mojo-how-to/manifest 2019-02-04 07:50:18 +0000
4@@ -8,12 +8,12 @@
5 script config=pre-deploy
6 # Deploy services only
7 deploy config=services local=services-secret delay=0
8-# Configure deploy autocert managed apache2
9-script config=scripts/utils/configure-apache2-vhosts-autocert APPLICATION=apache2 HTTP_TEMPLATE=${MOJO_STAGE}/../templates/vhost-http.tmpl HTTPS_TEMPLATE=${MOJO_STAGE}/../templates/vhost-https.tmpl
10 # Copy our built resources to the instances
11 script config=upload-built-content
12 # And now deploy relations as well
13 deploy config=relations
14+# Configure deploy autocert managed apache2
15+script config=scripts/utils/configure-apache2-vhosts-autocert APPLICATION=apache2 HTTP_TEMPLATE=${MOJO_STAGE}/../configs//mojo-how-to-production-vhost-http.tmpl HTTPS_TEMPLATE=${MOJO_STAGE}/../configs//mojo-how-to-production-vhost-https.tmpl
16 # Run verify steps
17 include config=manifest-verify
18 # Run post deploy steps
19
20=== modified file 'mojo-how-to/production/relations'
21--- mojo-how-to/production/relations 2019-02-04 04:28:17 +0000
22+++ mojo-how-to/production/relations 2019-02-04 07:50:18 +0000
23@@ -3,6 +3,8 @@
24 services:
25 apache2:
26 charm: apache2
27+ autocert-apache2:
28+ charm: autocert
29 content-fetcher:
30 charm: content-fetcher
31 nrpe:
32
33=== added directory 'mojo-how-to/scripts'
34=== added directory 'mojo-how-to/scripts/utils'
35=== added file 'mojo-how-to/scripts/utils/configure-apache2-vhosts-autocert'
36--- mojo-how-to/scripts/utils/configure-apache2-vhosts-autocert 1970-01-01 00:00:00 +0000
37+++ mojo-how-to/scripts/utils/configure-apache2-vhosts-autocert 2019-02-04 07:50:18 +0000
38@@ -0,0 +1,40 @@
39+#!/bin/sh
40+
41+set -eu
42+
43+if [ -z "${HTTP_TEMPLATE:-}" ]; then
44+ HTTP_TEMPLATE="${MOJO_STAGE}/templates/vhost-http.tmpl"
45+fi
46+
47+if [ -z "${HTTPS_TEMPLATE:-}" ]; then
48+ HTTPS_TEMPLATE="${MOJO_STAGE}/templates/vhost-https.tmpl"
49+fi
50+
51+echo "Checking Juju version..."
52+case $(juju version) in
53+ 1.*)
54+ juju_get="juju get"
55+ juju_set="juju set"
56+ juju_run='juju run --service'
57+ ;;
58+ 2.*)
59+ juju_get="juju config"
60+ juju_set="juju config"
61+ juju_run='juju run --application'
62+ ;;
63+ *)
64+ echo "Unknown Juju version $(juju version) detected! Exiting." >&2
65+ exit 1
66+ ;;
67+esac
68+
69+echo "Unsetting key, cert and chain for ${APPLICATION}..."
70+${juju_set} ${APPLICATION} ssl_cert= ssl_chain= ssl_key= || true # If the settings were already empty, this bombs out, so we don't want that to kill the script.
71+
72+echo "Asking autocert to update keys and certs for ${APPLICATION}..."
73+${juju_run} autocert-${APPLICATION} "/usr/bin/run-one /usr/sbin/autocert"
74+
75+echo "Updating ${APPLICATION} vhost templates..."
76+${juju_set} ${APPLICATION} \
77+ vhost_http_template="$(base64 -w0 < ${MOJO_SPEC_DIR}/${HTTP_TEMPLATE})" \
78+ vhost_https_template="$(base64 -w0 < ${MOJO_SPEC_DIR}/${HTTPS_TEMPLATE})"
79
80=== added file 'mojo-how-to/scripts/utils/juju-act'
81--- mojo-how-to/scripts/utils/juju-act 1970-01-01 00:00:00 +0000
82+++ mojo-how-to/scripts/utils/juju-act 2019-02-04 07:50:18 +0000
83@@ -0,0 +1,192 @@
84+#!/usr/bin/python3
85+# This file is part of juju-act, a juju plugin to invoke juju actions
86+# from the command line in a useful way, dealing with the async API
87+# for you.
88+#
89+# Copyright 2015-2017 Canonical Ltd.
90+#
91+# This program is free software: you can redistribute it and/or modify
92+# it under the terms of the GNU General Public License version 3, as
93+# published by the Free Software Foundation.
94+#
95+# This program is distributed in the hope that it will be useful, but
96+# WITHOUT ANY WARRANTY; without even the implied warranties of
97+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
98+# PURPOSE. See the GNU General Public License for more details.
99+#
100+# You should have received a copy of the GNU General Public License
101+# along with this program. If not, see <http://www.gnu.org/licenses/>.
102+
103+import argparse
104+from distutils.version import LooseVersion
105+from functools import lru_cache
106+import json
107+import os
108+import subprocess
109+import sys
110+from tempfile import NamedTemporaryFile
111+from textwrap import dedent
112+import yaml
113+
114+
115+__version__ = '1.0.0'
116+
117+
118+class DescriptionAction(argparse.Action):
119+ def __call__(self, parser, namespace, values, option_string=None):
120+ parser.exit(0, parser.description.splitlines()[0] + '\n')
121+
122+
123+class VersionAction(argparse.Action):
124+ def __call__(self, parser, namespace, values, option_string=None):
125+ parser.exit(0, __version__ + '\n')
126+
127+
128+def act_cmd(args=sys.argv[1:]):
129+ description = dedent("""\
130+ Run a juju action and display the result.
131+
132+ This command wraps the builtin run-action and show-action-output
133+ commands with an interface more usable for interactive use.
134+ """)
135+ v20 = has_juju_version('2.0')
136+ if v20:
137+ epilog_help = 'juju run-action --help'
138+ else:
139+ epilog_help = 'juju action do --help'
140+ epilog = dedent("""\
141+ See '{}' for further details about usage.
142+
143+ Exits with return code 0 if action completed, 1 if the action
144+ failed.
145+ """.format(epilog_help))
146+ parser = argparse.ArgumentParser(description=description, epilog=epilog)
147+ parser.add_argument('--description', action=DescriptionAction, nargs=0)
148+ parser.add_argument('--version', action=VersionAction, nargs=0)
149+ parser.add_argument('unit', metavar='UNIT', type=str,
150+ help='Unit to run action on')
151+ parser.add_argument('action', metavar='ACTION', type=str,
152+ help='Action to run')
153+ parser.add_argument('act_args', metavar='ARGS', type=str, nargs='*',
154+ help='Action parameters (overrides --params) '
155+ 'in key.key.key=value format. The values are '
156+ 'parsed as yaml, unless --string-args is used')
157+ if v20:
158+ parser.add_argument('-m', '--model',
159+ metavar="MODEL", type=str, action='store')
160+ else:
161+ parser.add_argument('-e', '--environment',
162+ metavar="MODEL", type=str, action='store')
163+ parser.add_argument('--format', metavar='FMT', type=str,
164+ action='store', default='yaml',
165+ help='Output format (yaml|json)')
166+ parser.add_argument('-o', '--output', metavar='FILE', type=str,
167+ action='store', default=None,
168+ help='Specify an output file')
169+ parser.add_argument('--params', metavar='YAML', type=str,
170+ action='store', default=None,
171+ help='Path to yaml-formatted params file')
172+ parser.add_argument('--string-args', default=False, action="store_true",
173+ help='Arguments are strings, and not parsed as yaml')
174+ parser.add_argument('--wait', dest='wait',
175+ help='How long to wait for results',
176+ action='store', default='0')
177+ if v20:
178+ parser.add_argument('-B', '--no-browser-login', default=False,
179+ action='store_true',
180+ help='Do not use web browser for authentication')
181+
182+ args = parser.parse_args(args)
183+
184+ # Run the action
185+ with NamedTemporaryFile() as outf:
186+ if v20:
187+ run_cmd = ['juju', 'run-action', args.unit, args.action,
188+ '--format=json', '--output={}'.format(outf.name)]
189+ if args.model:
190+ run_cmd.append('--model={}'.format(args.model))
191+ else:
192+ run_cmd = ['juju', 'action', 'do', args.unit, args.action,
193+ '--format=json', '--output={}'.format(outf.name)]
194+ if args.environment:
195+ run_cmd.append('--environment={}'.format(args.environment))
196+
197+ if args.params:
198+ run_cmd.append('--params={}'.format(args.params))
199+
200+ if args.string_args:
201+ run_cmd.append('--string-args')
202+
203+ if v20 and args.no_browser_login:
204+ run_cmd.append('--no-browser-login')
205+
206+ run_cmd.extend(args.act_args)
207+ rc = subprocess.call(run_cmd)
208+ if rc != 0:
209+ sys.exit(rc)
210+
211+ m = json.load(open(outf.name, 'r'))
212+ action_id = list(m.values())[0]
213+
214+ # Collect the result
215+ if v20:
216+ out_cmd = ['juju', 'show-action-output', action_id]
217+ if args.model:
218+ out_cmd.append('--model={}'.format(args.model))
219+ else:
220+ out_cmd = ['juju', 'action', 'fetch', action_id]
221+ if args.environment:
222+ out_cmd.append('--environment={}'.format(args.environment))
223+ if args.format:
224+ out_cmd.append('--format={}'.format(args.format))
225+ # if args.output:
226+ # out_cmd.append('--output={}'.format(args.output))
227+ out_cmd.append('--wait={}'.format(args.wait))
228+ result = subprocess.check_output(out_cmd, universal_newlines=True)
229+
230+ # Output
231+ if args.output:
232+ try:
233+ print(result, file=open(args.output, 'w'))
234+ except Exception:
235+ print('ERROR: failed to store result of action {} in {}'
236+ ''.format(action_id, args.output),
237+ file=sys.stderr)
238+ raise
239+ else:
240+ print(result)
241+ if args.format == 'json':
242+ m = json.loads(result)
243+ else:
244+ m = yaml.safe_load(result)
245+ if m['status'] == 'completed':
246+ sys.exit(0)
247+ elif m['status'] == 'failed':
248+ sys.exit(1)
249+ else:
250+ print('ERROR: Unknown return status {}'.format(m['status']),
251+ file=sys.stderr)
252+ sys.exit(99)
253+
254+
255+def has_juju_version(ver):
256+ """Return True if the Juju version is the same or later than `ver`"""
257+ return LooseVersion(juju_version()) >= LooseVersion(ver)
258+
259+
260+@lru_cache()
261+def juju_version():
262+ raw_ver = subprocess.check_output(['juju', '--version'],
263+ universal_newlines=True)
264+ return raw_ver.strip().split('-', 1)[0]
265+
266+
267+if __name__ == '__main__':
268+ # I use these to launch the entry points from the source tree.
269+ # Most installations will be using the setuptools generated
270+ # launchers.
271+ script = os.path.basename(sys.argv[0])
272+ if script == 'juju-act':
273+ sys.exit(act_cmd())
274+ else:
275+ raise RuntimeError('Unknown script {}'.format(script))

Subscribers

People subscribed via source and target branches

to all changes: