Merge lp:~teknico/charms/precise/juju-gui/encrypt-api-env-connection into lp:~juju-gui/charms/precise/juju-gui/trunk
- Precise Pangolin (12.04)
- encrypt-api-env-connection
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 21 |
Proposed branch: | lp:~teknico/charms/precise/juju-gui/encrypt-api-env-connection |
Merge into: | lp:~juju-gui/charms/precise/juju-gui/trunk |
Diff against target: |
365 lines (+51/-40) 12 files modified
HACKING.md (+2/-2) config.yaml (+2/-2) config/config.js.template (+1/-1) config/juju-api-agent.conf.template (+2/-1) config/juju-api-improv.conf.template (+2/-1) config/nginx.conf.template (+2/-2) hooks/config-changed (+11/-10) hooks/start (+3/-2) hooks/utils.py (+13/-10) revision (+1/-1) tests/deploy.test (+2/-2) tests/test_utils.py (+10/-6) |
To merge this branch: | bzr merge lp:~teknico/charms/precise/juju-gui/encrypt-api-env-connection |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju GUI Hackers | Pending | ||
Review via email: mp+141107@code.launchpad.net |
Commit message
Description of the change
Setup encrypted conn. to the API environment
Pass the same certificate and private key used by nginx to the
API environment, so that the websocket connection can use WSS.
Nicola Larosa (teknico) wrote : | # |
Nicola Larosa (teknico) wrote : | # |
*** Submitted:
Setup encrypted conn. to the API environment
Pass the same certificate and private key used by nginx to the
API environment, so that the websocket connection can use WSS.
Nicola Larosa (teknico) wrote : | # |
Please take a look.
Francesco Banconi (frankban) wrote : | # |
Land with changes.
This branch looks good Nicola: it's nice to see everything's working
with TLS enabled. Tests pass.
Please take a look at my comments below: especially the config-changed
issue needs to be addressed IMHO.
https:/
File HACKING.md (right):
https:/
HACKING.md:128: /var/lib/
charm.log file to investigate,
Good catch, thank you.
https:/
File hooks/config-
https:/
hooks/config-
The improv and the api agent services now depend on the certificates
path, and need to be restarted if the ssl-cert-path is changed. AFAICT,
currently this is not handled here. E.g., if the user run ``juju set
juju-gui ssl-cert-
and the GUI ends up in a broken state.
https:/
hooks/config-
See above.
https:/
File hooks/utils.py (right):
https:/
hooks/utils.py:59: SSL_CERT_PATH = '/etc/ssl/juju-gui'
Here the config default is redefined, and this value is used as default
for the functions below needing the tls keys path.
Is this really required? I believe that the default value is never used,
i.e. each time we call start_improv, start_agent etc., we always pass
the value taken from config. Moreover, it seems to me that if, in the
future, we want to change the default path, we will need to change the
same value in two different places.
https:/
hooks/utils.py:339: crt_path = os.path.
I like how you renamed the keys.
Nicola Larosa (teknico) wrote : | # |
Thanks for the review, very useful.
https:/
File hooks/config-
https:/
hooks/config-
frankban wrote:
> The improv and the api agent services now depend on the certificates
> path, and need to be restarted if the ssl-cert-path is changed.
> AFAICT, currently this is not handled here.
You are right, I will add ssl-cert-path to the checked properties.
https:/
hooks/config-
frankban wrote:
> See above.
Ditto.
https:/
File hooks/utils.py (right):
https:/
hooks/utils.py:59: SSL_CERT_PATH = '/etc/ssl/juju-gui'
frankban wrote:
> I believe that the default value is never used, i.e. each time we call
> start_improv, start_agent etc., we always pass the value taken from
config.
Indeed. I foolishly unified the defaults into the constant, forgetting
that the value comes from the config anyway, and the defaults do not
really make sense. I'll remove them.
https:/
hooks/utils.py:339: crt_path = os.path.
frankban wrote:
> I like how you renamed the keys.
Well, I had to. :-) The --keys Juju option only passes the certificates
directory, not the filenames: they are hardwired.
Nicola Larosa (teknico) wrote : | # |
Please take a look.
Nicola Larosa (teknico) wrote : | # |
Please take a look.
Gary Poster (gary) wrote : | # |
Nicola Larosa (teknico) wrote : | # |
*** Submitted:
Setup encrypted conn. to the API environment
Pass the same certificate and private key used by nginx to the
API environment, so that the websocket connection can use WSS.
R=frankban, gary.poster
CC=
https:/
Preview Diff
1 | === modified file 'HACKING.md' |
2 | --- HACKING.md 2012-12-19 15:27:53 +0000 |
3 | +++ HACKING.md 2013-01-04 14:51:21 +0000 |
4 | @@ -114,7 +114,7 @@ |
5 | this (again, assuming you have set up your repo the way the functional tests |
6 | need them, as described above). |
7 | |
8 | - juju deploy --repository=/path/to/charm/repo local:precise/juju-gui |
9 | + juju deploy --repository=/path/to/charm/repo --upgrade local:precise/juju-gui |
10 | juju expose juju-gui |
11 | |
12 | Now you are working with a test run, as described in |
13 | @@ -125,7 +125,7 @@ |
14 | When something goes wrong, on your local machine run |
15 | `juju debug-hooks juju-gui/0` or similar. This will initially put you on the |
16 | unit that has the problem. You can look at what is going on in |
17 | -/var/log/juju/units/[NAME OF UNIT]. There is a charm.log file to investigate, |
18 | +/var/lib/juju/units/[NAME OF UNIT]. There is a charm.log file to investigate, |
19 | and a charm directory which contains the charm. The charm directory contains |
20 | the juju-gui and juju directories, so everything you need is there. |
21 | |
22 | |
23 | === modified file 'config.yaml' |
24 | --- config.yaml 2012-12-21 15:05:06 +0000 |
25 | +++ config.yaml 2013-01-04 14:51:21 +0000 |
26 | @@ -27,7 +27,7 @@ |
27 | Connect the Juju GUI to the staging backend |
28 | (i.e. a simulated Juju environment). |
29 | type: boolean |
30 | - default: False |
31 | + default: false |
32 | staging-environment: |
33 | description: | |
34 | The environment JSON export used by the staging server. This option can |
35 | @@ -50,7 +50,7 @@ |
36 | description: | |
37 | The path to the directory where the SSL certificates are stored. |
38 | type: string |
39 | - default: /etc/ssl/private/juju-gui |
40 | + default: /etc/ssl/juju-gui |
41 | ssl-cert-contents: |
42 | description: | |
43 | The contents of the certificate file to be used in SSL connections to |
44 | |
45 | === modified file 'config/config.js.template' |
46 | --- config/config.js.template 2013-01-02 13:31:03 +0000 |
47 | +++ config/config.js.template 2013-01-04 14:51:21 +0000 |
48 | @@ -6,5 +6,5 @@ |
49 | viewContainer: '#main', |
50 | transitions: false, |
51 | charm_store_url: 'https://jujucharms.com/', |
52 | - socket_url: 'ws://%(address)s:%(port)s/ws' |
53 | + socket_url: 'wss://%(address)s:%(port)s/ws' |
54 | }; |
55 | |
56 | === modified file 'config/juju-api-agent.conf.template' |
57 | --- config/juju-api-agent.conf.template 2012-11-29 13:23:28 +0000 |
58 | +++ config/juju-api-agent.conf.template 2013-01-04 14:51:21 +0000 |
59 | @@ -10,4 +10,5 @@ |
60 | # Use --nodaemon so that upstart can correctly retrieve the process ID. |
61 | exec /usr/bin/python -m juju.agents.api --nodaemon --port %(port)s \ |
62 | --logfile /var/log/juju/api-agent.log \ |
63 | - --session-file /var/run/juju/api-agent.zksession |
64 | + --session-file /var/run/juju/api-agent.zksession \ |
65 | + --secure --keys %(keys)s |
66 | |
67 | === modified file 'config/juju-api-improv.conf.template' |
68 | --- config/juju-api-improv.conf.template 2012-12-03 10:02:45 +0000 |
69 | +++ config/juju-api-improv.conf.template 2013-01-04 14:51:21 +0000 |
70 | @@ -8,4 +8,5 @@ |
71 | env PYTHONPATH=%(juju_dir)s:$PYTHONPATH |
72 | |
73 | exec /usr/bin/python %(juju_dir)s/improv.py --port %(port)s \ |
74 | - -f %(juju_dir)s/%(staging_env)s.json |
75 | + -f %(juju_dir)s/%(staging_env)s.json \ |
76 | + --secure --keys %(keys)s |
77 | |
78 | === modified file 'config/nginx.conf.template' |
79 | --- config/nginx.conf.template 2013-01-02 13:31:03 +0000 |
80 | +++ config/nginx.conf.template 2013-01-04 14:51:21 +0000 |
81 | @@ -9,8 +9,8 @@ |
82 | server_name _; |
83 | root %(server_root)s; |
84 | index index.html; |
85 | - ssl_certificate %(ssl_cert_path)s/server.pem; |
86 | - ssl_certificate_key %(ssl_cert_path)s/server.key; |
87 | + ssl_certificate %(ssl_cert_path)s/juju.crt; |
88 | + ssl_certificate_key %(ssl_cert_path)s/juju.key; |
89 | |
90 | # Serve static assets. |
91 | location ^~ /juju-ui/ { |
92 | |
93 | === modified file 'hooks/config-changed' |
94 | --- hooks/config-changed 2012-12-21 16:32:53 +0000 |
95 | +++ hooks/config-changed 2013-01-04 14:51:21 +0000 |
96 | @@ -41,7 +41,7 @@ |
97 | |
98 | added_or_changed = diff.added_or_changed |
99 | juju_api_port = config.get('juju-api-port') |
100 | - staging = config.get('staging') |
101 | + in_staging = config.get('staging') |
102 | |
103 | # The juju_gui_source_changed and juju_api_branch_changed variables |
104 | # control whether we restart the GUI and the API, respectively, at the |
105 | @@ -62,17 +62,18 @@ |
106 | # Handle changes to SSL certificates. |
107 | ssl_properties = set( |
108 | ['ssl-cert-path', 'ssl-cert-contents', 'ssl-key-contents']) |
109 | - if added_or_changed & ssl_properties: |
110 | + ssl_changed = added_or_changed & ssl_properties |
111 | + if ssl_changed: |
112 | save_or_create_certificates( |
113 | config['ssl-cert-path'], config.get('ssl-cert-contents'), |
114 | config.get('ssl-key-contents')) |
115 | |
116 | # Handle changes to the improv server configuration. |
117 | - if staging: |
118 | + if in_staging: |
119 | staging_properties = set( |
120 | ['staging', 'staging-environment', 'juju-api-port']) |
121 | staging_changed = added_or_changed & staging_properties |
122 | - if staging_changed or juju_api_branch_changed: |
123 | + if staging_changed or ssl_changed or juju_api_branch_changed: |
124 | if 'staging' in added_or_changed: |
125 | # 'staging' went from False to True, so the agent server is |
126 | # running and must be stopped. |
127 | @@ -85,11 +86,12 @@ |
128 | service_control(current_api, STOP) |
129 | # Now the improv server can be cleanly started. |
130 | log('Starting or restarting staging.') |
131 | - start_improv(juju_api_port, config.get('staging-environment')) |
132 | + start_improv(juju_api_port, config.get('staging-environment'), |
133 | + config['ssl-cert-path']) |
134 | else: |
135 | agent_properties = set(['juju-api-port', 'staging']) |
136 | agent_changed = added_or_changed & agent_properties |
137 | - if agent_changed or juju_api_branch_changed: |
138 | + if agent_changed or ssl_changed or juju_api_branch_changed: |
139 | if 'staging' in added_or_changed: |
140 | # If 'staging' transitions to False we need to stop the backend |
141 | # and start the agent. |
142 | @@ -100,19 +102,18 @@ |
143 | current_api = AGENT |
144 | service_control(current_api, STOP) |
145 | log('Starting or restarting Juju API agent.') |
146 | - start_agent(juju_api_port) |
147 | + start_agent(juju_api_port, config['ssl-cert-path']) |
148 | |
149 | # Handle changes to the juju-gui configuration. |
150 | gui_properties = set( |
151 | ['juju-gui-console-enabled', 'juju-api-port', 'staging']) |
152 | gui_changed = added_or_changed & gui_properties |
153 | - ssl_cert_path_changed = 'ssl-cert-path' in added_or_changed |
154 | - if gui_changed or juju_gui_source_changed or ssl_cert_path_changed: |
155 | + if gui_changed or ssl_changed or juju_gui_source_changed: |
156 | with su('root'): |
157 | service_control(GUI, STOP) |
158 | console_enabled = config.get('juju-gui-console-enabled') |
159 | ssl_cert_path = config['ssl-cert-path'] |
160 | - start_gui(juju_api_port, console_enabled, staging, ssl_cert_path) |
161 | + start_gui(juju_api_port, console_enabled, in_staging, ssl_cert_path) |
162 | |
163 | |
164 | def main(): |
165 | |
166 | === modified file 'hooks/start' |
167 | --- hooks/start 2013-01-02 13:31:03 +0000 |
168 | +++ hooks/start 2013-01-04 14:51:21 +0000 |
169 | @@ -34,9 +34,10 @@ |
170 | juju_api_port, config['juju-gui-console-enabled'], staging, |
171 | config['ssl-cert-path']) |
172 | if staging: |
173 | - start_improv(juju_api_port, config['staging-environment']) |
174 | + start_improv(juju_api_port, config['staging-environment'], |
175 | + config['ssl-cert-path']) |
176 | else: |
177 | - start_agent(juju_api_port) |
178 | + start_agent(juju_api_port, config['ssl-cert-path']) |
179 | open_ports(juju_api_port) |
180 | |
181 | |
182 | |
183 | === modified file 'hooks/utils.py' |
184 | --- hooks/utils.py 2012-12-21 15:22:50 +0000 |
185 | +++ hooks/utils.py 2013-01-04 14:51:21 +0000 |
186 | @@ -178,7 +178,7 @@ |
187 | results_log.info('\n' + results) |
188 | |
189 | |
190 | -def start_improv(juju_api_port, staging_env, |
191 | +def start_improv(juju_api_port, staging_env, ssl_cert_path, |
192 | config_path='/etc/init/juju-api-improv.conf'): |
193 | """Start a simulated juju environment using ``improv.py``.""" |
194 | log('Setting up staging start up script.') |
195 | @@ -186,6 +186,7 @@ |
196 | 'juju_dir': JUJU_DIR, |
197 | 'port': juju_api_port, |
198 | 'staging_env': staging_env, |
199 | + 'keys': ssl_cert_path, |
200 | } |
201 | render_to_file('juju-api-improv.conf.template', context, config_path) |
202 | log('Starting the staging backend.') |
203 | @@ -193,7 +194,8 @@ |
204 | service_control(IMPROV, START) |
205 | |
206 | |
207 | -def start_agent(juju_api_port, config_path='/etc/init/juju-api-agent.conf'): |
208 | +def start_agent(juju_api_port, ssl_cert_path, |
209 | + config_path='/etc/init/juju-api-agent.conf'): |
210 | """Start the Juju agent and connect to the current environment.""" |
211 | # Retrieve the Zookeeper address from the start up script. |
212 | unit_dir = os.path.realpath(os.path.join(CURRENT_DIR, '..')) |
213 | @@ -204,6 +206,7 @@ |
214 | 'juju_dir': JUJU_DIR, |
215 | 'port': juju_api_port, |
216 | 'zookeeper': zookeeper, |
217 | + 'keys': ssl_cert_path, |
218 | } |
219 | render_to_file('juju-api-agent.conf.template', context, config_path) |
220 | log('Starting API agent.') |
221 | @@ -211,7 +214,7 @@ |
222 | service_control(AGENT, START) |
223 | |
224 | |
225 | -def start_gui(juju_api_port, console_enabled, staging, ssl_cert_path, |
226 | +def start_gui(juju_api_port, console_enabled, in_staging, ssl_cert_path, |
227 | config_path='/etc/init/juju-gui.conf', |
228 | nginx_path=JUJU_GUI_SITE, |
229 | config_js_path=None): |
230 | @@ -219,7 +222,7 @@ |
231 | with su('root'): |
232 | run('chown', '-R', 'ubuntu:', JUJU_GUI_DIR) |
233 | build_dir = JUJU_GUI_DIR + '/build-' |
234 | - build_dir += 'debug' if staging else 'prod' |
235 | + build_dir += 'debug' if in_staging else 'prod' |
236 | log('Setting up Juju GUI start up script.') |
237 | render_to_file('juju-gui.conf.template', {}, config_path) |
238 | log('Generating the Juju GUI configuration file.') |
239 | @@ -244,12 +247,12 @@ |
240 | service_control(GUI, START) |
241 | |
242 | |
243 | -def stop(staging): |
244 | +def stop(in_staging): |
245 | """Stop the Juju API agent.""" |
246 | with su('root'): |
247 | log('Stopping Juju GUI.') |
248 | service_control(GUI, STOP) |
249 | - if staging: |
250 | + if in_staging: |
251 | log('Stopping the staging backend.') |
252 | service_control(IMPROV, STOP) |
253 | else: |
254 | @@ -330,13 +333,13 @@ |
255 | If both *ssl_cert_contents* and *ssl_key_contents* are provided, use them |
256 | as certificates; otherwise, generate them. |
257 | """ |
258 | - pem_path = os.path.join(ssl_cert_path, 'server.pem') |
259 | - key_path = os.path.join(ssl_cert_path, 'server.key') |
260 | + crt_path = os.path.join(ssl_cert_path, 'juju.crt') |
261 | + key_path = os.path.join(ssl_cert_path, 'juju.key') |
262 | if not os.path.exists(ssl_cert_path): |
263 | os.makedirs(ssl_cert_path) |
264 | if ssl_cert_contents and ssl_key_contents: |
265 | # Save the provided certificates. |
266 | - with open(pem_path, 'w') as cert_file: |
267 | + with open(crt_path, 'w') as cert_file: |
268 | cert_file.write(ssl_cert_contents) |
269 | with open(key_path, 'w') as key_file: |
270 | key_file.write(ssl_key_contents) |
271 | @@ -348,4 +351,4 @@ |
272 | '-days', '365', '-nodes', '-x509', '-subj', |
273 | # These are arbitrary test values for the certificate. |
274 | '/C=GB/ST=Juju/L=GUI/O=Ubuntu/CN=juju.ubuntu.com', |
275 | - '-keyout', key_path, '-out', pem_path)) |
276 | + '-keyout', key_path, '-out', crt_path)) |
277 | |
278 | === modified file 'revision' |
279 | --- revision 2012-12-20 10:52:39 +0000 |
280 | +++ revision 2013-01-04 14:51:21 +0000 |
281 | @@ -1,1 +1,1 @@ |
282 | -17 |
283 | +18 |
284 | |
285 | === modified file 'tests/deploy.test' |
286 | --- tests/deploy.test 2013-01-02 13:31:03 +0000 |
287 | +++ tests/deploy.test 2013-01-04 14:51:21 +0000 |
288 | @@ -56,7 +56,7 @@ |
289 | url = 'https://{0}:{1}'.format(hostname, self.port) |
290 | response = open_url(url) |
291 | self.assertEqual(200, response.getcode()) |
292 | - ws_url = 'http://{0}:{1}/ws'.format(hostname, ws_port) |
293 | + ws_url = 'https://{0}:{1}/ws'.format(hostname, ws_port) |
294 | # A bad request status code here means the websocket resource is found. |
295 | # It would take an actual websocket client to properly interact with |
296 | # the websocket server. |
297 | @@ -104,7 +104,7 @@ |
298 | |
299 | def test_staging(self): |
300 | # Ensure the Juju GUI and improv services are correctly set up. |
301 | - config = {self.charm: {'staging': 'True'}} |
302 | + config = {self.charm: {'staging': 'true'}} |
303 | config_file = make_charm_config_file(config) |
304 | hostname = self.deploy(config_path=config_file.name) |
305 | # XXX 2012-11-29 frankban bug=872264: see *stop_services* above. |
306 | |
307 | === modified file 'tests/test_utils.py' |
308 | --- tests/test_utils.py 2012-12-21 16:46:20 +0000 |
309 | +++ tests/test_utils.py 2013-01-04 14:51:21 +0000 |
310 | @@ -295,8 +295,8 @@ |
311 | base_dir = tempfile.mkdtemp() |
312 | self.addCleanup(shutil.rmtree, base_dir) |
313 | self.cert_path = os.path.join(base_dir, 'certificates') |
314 | - self.cert_file = os.path.join(self.cert_path, 'server.pem') |
315 | - self.key_file = os.path.join(self.cert_path, 'server.key') |
316 | + self.cert_file = os.path.join(self.cert_path, 'juju.crt') |
317 | + self.key_file = os.path.join(self.cert_path, 'juju.key') |
318 | |
319 | def test_generation(self): |
320 | """Ensure certificates are correctly generated.""" |
321 | @@ -372,6 +372,7 @@ |
322 | |
323 | self.destination_file = tempfile.NamedTemporaryFile() |
324 | self.addCleanup(self.destination_file.close) |
325 | + self.ssl_cert_path = 'ssl/cert/path' |
326 | |
327 | def tearDown(self): |
328 | # Undo all of the monkey patching. |
329 | @@ -382,20 +383,23 @@ |
330 | def test_start_improv(self): |
331 | port = '1234' |
332 | staging_env = 'large' |
333 | - start_improv(port, staging_env, self.destination_file.name) |
334 | + start_improv(port, staging_env, self.ssl_cert_path, |
335 | + self.destination_file.name) |
336 | conf = self.destination_file.read() |
337 | self.assertTrue('--port %s' % port in conf) |
338 | self.assertTrue(staging_env + '.json' in conf) |
339 | + self.assertTrue(self.ssl_cert_path in conf) |
340 | self.assertEqual(self.svc_ctl_call_count, 1) |
341 | self.assertEqual(self.service_names, ['juju-api-improv']) |
342 | self.assertEqual(self.actions, [charmhelpers.START]) |
343 | |
344 | def test_start_agent(self): |
345 | port = '1234' |
346 | - start_agent(port, self.destination_file.name) |
347 | + start_agent(port, self.ssl_cert_path, self.destination_file.name) |
348 | conf = self.destination_file.read() |
349 | self.assertTrue('--port %s' % port in conf) |
350 | self.assertTrue('JUJU_ZOOKEEPER=%s' % self.fake_zk_address in conf) |
351 | + self.assertTrue(self.ssl_cert_path in conf) |
352 | self.assertEqual(self.svc_ctl_call_count, 1) |
353 | self.assertEqual(self.service_names, ['juju-api-agent']) |
354 | self.assertEqual(self.actions, [charmhelpers.START]) |
355 | @@ -413,8 +417,8 @@ |
356 | self.assertTrue('/usr/sbin/nginx' in conf) |
357 | nginx_conf = nginx_file.read() |
358 | self.assertTrue('juju-gui/build-debug' in nginx_conf) |
359 | - self.assertIn('/tmp/certificates/server.pem', nginx_conf) |
360 | - self.assertIn('/tmp/certificates/server.key', nginx_conf) |
361 | + self.assertIn('/tmp/certificates/juju.crt', nginx_conf) |
362 | + self.assertIn('/tmp/certificates/juju.key', nginx_conf) |
363 | self.assertEqual(self.svc_ctl_call_count, 1) |
364 | self.assertEqual(self.service_names, ['juju-gui']) |
365 | self.assertEqual(self.actions, [charmhelpers.START]) |
Reviewers: mp+141107_ code.launchpad. net,
Message:
Please take a look.
Description:
Setup encrypted conn. to the API environment
Pass the same certificate and private key used by nginx to the
API environment, so that the websocket connection can use WSS.
This sets the code up, but HTTPS is still disabled, and WSS too. nginx.conf. template, config. js.template, and expose the 443 port in
To test this you need to enable HTTPS in config/
WSS in config/
hooks/start.
Also, this is not yet working while deploying manually, and needs
further testing. Do not land without checking first.
https:/ /code.launchpad .net/~teknico/ charms/ precise/ juju-gui/ encrypt- api-env- connection/ +merge/ 141107
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/7007045/
Affected files: juju-api- agent.conf. template juju-api- improv. conf.template nginx.conf. template
M HACKING.md
A [revision details]
M config.yaml
M config/
M config/
M config/
M hooks/start
M hooks/utils.py
M revision
M tests/test_utils.py
Index: HACKING.md
=== modified file 'HACKING.md'
--- HACKING.md 2012-12-19 15:27:53 +0000
+++ HACKING.md 2012-12-21 18:06:41 +0000
@@ -114,7 +114,7 @@
this (again, assuming you have set up your repo the way the functional
tests
need them, as described above).
- juju deploy --repository= /path/to/ charm/repo local:precise/ juju-gui /path/to/ charm/repo --upgrade juju-gui
+ juju deploy --repository=
local:precise/
juju expose juju-gui
Now you are working with a test run, as described in
Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision:
<email address hidden>
+New revision: <email address hidden>
Index: config.yaml private/ juju-gui private/ juju-gui/
=== modified file 'config.yaml'
--- config.yaml 2012-12-20 14:56:29 +0000
+++ config.yaml 2012-12-21 18:06:41 +0000
@@ -50,4 +50,4 @@
description: |
The path to the directory where the SSL certificates are stored.
type: string
- default: /etc/ssl/
+ default: /etc/ssl/
Index: config/ juju-api- agent.conf. template juju-api- agent.conf. template' juju-api- agent.conf. template 2012-11-29 13:23:28 +0000 juju-api- agent.conf. template 2012-12-21 15:12:03 +0000 juju/api- agent.log \ juju/api- agent.zksession juju/api- agent.zksession \
=== modified file 'config/
--- config/
+++ config/
@@ -10,4 +10,5 @@
# Use --nodaemon so that upstart can correctly retrieve the process ID.
exec /usr/bin/python -m juju.agents.api --nodaemon --port %(port)s \
--logfile /var/log/
- --session-file /var/run/
+ --session-file /var/run/
+ --keys %(keys)s
Index: config/ juju-api- improv. conf.template juju-api- improv. conf.template' juju-api- improv. conf.template 2012-12-03 10:02:45 +0000 juju-api- improv. conf.template 2012-12-21 15:12:03 +0000 %(juju_ dir)s:$ PYTHONPATH
=== modified file 'config/
--- config/
+++ config/
@@ -8,4 +8,5 @@
env PYTHONPATH=
exec /usr/bin/python %(juju_ dir)s/improv. py --port %(port)s \
- -f %...