Merge lp:~benji/juju-deployer/add-fetching-configs into lp:~hazmat/juju-deployer/refactor

Proposed by Benji York
Status: Merged
Merged at revision: 98
Proposed branch: lp:~benji/juju-deployer/add-fetching-configs
Merge into: lp:~hazmat/juju-deployer/refactor
Diff against target: 137 lines (+73/-7)
3 files modified
README (+1/-1)
deployer.py (+19/-5)
test_deployment.py (+53/-1)
To merge this branch: bzr merge lp:~benji/juju-deployer/add-fetching-configs
Reviewer Review Type Date Requested Status
Adam Gandelman Pending
Review via email: mp+174875@code.launchpad.net

This proposal supersedes a proposal from 2013-07-15.

Description of the change

This branch adds the ability to specify a configuration file (in a -c option) by URL and have that configuration file loaded over the network, stored in a temp file locally, and used by the deployer.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README'
2--- README 2013-05-14 21:00:33 +0000
3+++ README 2013-07-15 21:51:32 +0000
4@@ -9,7 +9,7 @@
5 Installation
6 ------------
7
8- $ virtulenv --system-site-packages deployer
9+ $ virtualenv --system-site-packages deployer
10 $ ./deployer/bin/easy_install juju-deployer
11 $ ./deployer/bin/juju-deployer -h
12
13
14=== modified file 'deployer.py'
15--- deployer.py 2013-07-12 13:34:39 +0000
16+++ deployer.py 2013-07-15 21:51:32 +0000
17@@ -30,6 +30,7 @@
18 import tempfile
19 import time
20 import urllib
21+import urlparse
22 import zipfile
23
24 try:
25@@ -357,14 +358,27 @@
26 deploy_data = self._resolve_inherited(deploy_data)
27 return Deployment(key, deploy_data, self.include_dirs)
28
29- def load(self):
30+ def load(self, urlopen=urllib.urlopen):
31 data = {}
32 include_dirs = []
33 for fp in self.config_files:
34 if not path_exists(fp):
35- self.log.warning("Config file not found %s", fp)
36- raise ErrorExit()
37- include_dirs.append(dirname(abspath(fp)))
38+ # If the config file path is a URL, fetch it and use it.
39+ if urlparse.urlparse(fp).scheme:
40+ response = urlopen(fp)
41+ if response.getcode() == 200:
42+ temp = tempfile.NamedTemporaryFile(delete=True)
43+ shutil.copyfileobj(response, temp)
44+ temp.flush()
45+ fp = temp.name
46+ else:
47+ self.log.warning("Could not retrieve %s", fp)
48+ raise ErrorExit()
49+ else:
50+ self.log.warning("Config file not found %s", fp)
51+ raise ErrorExit()
52+ else:
53+ include_dirs.append(dirname(abspath(fp)))
54 with open(fp) as fh:
55 try:
56 d = yaml_load(fh.read())
57@@ -845,7 +859,7 @@
58 os.mkdir(self.series_path)
59 for charm in self.get_charms():
60 if charm.is_local():
61- if self.charm.exists():
62+ if charm.exists():
63 if no_local_mods:
64 if charm.is_modified():
65 self.log.warning(
66
67=== modified file 'test_deployment.py'
68--- test_deployment.py 2013-07-11 23:25:17 +0000
69+++ test_deployment.py 2013-07-15 21:51:32 +0000
70@@ -34,7 +34,7 @@
71 Service,
72 Charm,
73 Deployment,
74- Environment,
75+ EnvironmentClient,
76 Importer,
77 ErrorExit)
78
79@@ -169,6 +169,58 @@
80 self.assertTrue(deployment)
81
82
83+class NetworkConfigFetchingTests(Base):
84+ """Configuration files can be specified via URL that is then fetched."""
85+
86+ def setUp(self):
87+ self.output = self.capture_logging(
88+ "deployer.config", level=logging.DEBUG)
89+
90+ def test_urls_are_fetched(self):
91+ # If a config file is specified as a URL, that URL is fetched and
92+ # placed at a temporary location where it is read and treated as a
93+ # regular config file.
94+ CONFIG_URL = 'http://site.invalid/config-1'
95+ config = ConfigStack([])
96+ config.config_files = [CONFIG_URL]
97+
98+ class FauxResponse(file):
99+ def getcode(self):
100+ return 200
101+
102+ def faux_urlopen(url):
103+ self.assertEqual(url, CONFIG_URL)
104+ return FauxResponse('configs/ostack-testing-sample.cfg')
105+
106+ config.load(urlopen=faux_urlopen)
107+ self.assertEqual(
108+ config.keys(),
109+ [u'openstack-precise-ec2',
110+ u'openstack-precise-ec2-trunk',
111+ u'openstack-ubuntu-testing'])
112+ self.assertRaises(ErrorExit, config.get, 'zeeland')
113+ result = config.get("openstack-precise-ec2")
114+ self.assertTrue(isinstance(result, Deployment))
115+
116+ def test_unfetchable_urls_generate_an_error(self):
117+ # If a config file is specified as a URL, that URL is fetched and
118+ # placed at a temporary location where it is read and treated as a
119+ # regular config file.
120+ CONFIG_URL = 'http://site.invalid/config-1'
121+ config = ConfigStack([])
122+ config.config_files = [CONFIG_URL]
123+
124+ class FauxResponse(file):
125+ def getcode(self):
126+ return 400
127+
128+ def faux_urlopen(url):
129+ self.assertEqual(url, CONFIG_URL)
130+ return FauxResponse('configs/ostack-testing-sample.cfg')
131+
132+ self.assertRaises(ErrorExit, config.load, urlopen=faux_urlopen)
133+
134+
135 class ServiceTest(Base):
136
137 def test_service(self):

Subscribers

People subscribed via source and target branches