Merge lp:~smoser/cloud-init/mirror-rework into lp:~cloud-init-dev/cloud-init/trunk
- mirror-rework
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 630 |
Proposed branch: | lp:~smoser/cloud-init/mirror-rework |
Merge into: | lp:~cloud-init-dev/cloud-init/trunk |
Diff against target: |
591 lines (+309/-108) 11 files modified
ChangeLog (+4/-0) cloudinit/cloud.py (+0/-3) cloudinit/config/cc_apt_update_upgrade.py (+74/-57) cloudinit/distros/__init__.py (+71/-2) cloudinit/distros/debian.py (+4/-0) cloudinit/sources/DataSourceCloudStack.py (+2/-1) cloudinit/sources/DataSourceEc2.py (+6/-34) cloudinit/sources/__init__.py (+7/-3) config/cloud.cfg (+14/-2) templates/sources.list.tmpl (+6/-6) tests/unittests/test_distros/test_generic.py (+121/-0) |
To merge this branch: | bzr merge lp:~smoser/cloud-init/mirror-rework |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
cloud-init Commiters | Pending | ||
Review via email: mp+120852@code.launchpad.net |
Commit message
rework package mirror selection
There are several changes here.
* Datasource now has a 'availability_zone' getter.
* get_package_
* Datasource convenience 'get_package_
the configured distro, and passes it the availability-zone
* distro has a get_package_
* get_package_
this is to facilitate use of 'security' and 'primary' archive.
* this supports searching based on templates. Any template
that references undefined values is skipped. These templates
can contain 'availability_zone' (LP: #1037727)
* distro's mirrors can be arch specific (LP: #1028501)
* rename_apt_lists supports the "mirror_info" rather than single mirror
* generate_
ubuntu mirrors reference '$security' rather than security (LP: #1006963)
* remove the DataSourceEc2 specific mirror selection, but instead
rely on the above filtering, and the fact that 'ec2_region' is only
defined if the availability_zone looks like a ec2 az.
Description of the change
- 634. By Scott Moser
-
improve the check for "uses unknown key" in mirror templates
instead of substituting and then checking for presense of a unlikely to
occur string, this only adds to the search list if there is no KeyError
raised.
Preview Diff
1 | === modified file 'ChangeLog' |
2 | --- ChangeLog 2012-08-21 01:27:04 +0000 |
3 | +++ ChangeLog 2012-08-22 19:21:17 +0000 |
4 | @@ -1,4 +1,8 @@ |
5 | 0.7.0: |
6 | + - allow distro mirror selection to include availability-zone (LP: #1037727) |
7 | + - allow arch specific mirror selection (select ports.ubuntu.com on arm) |
8 | + LP: #1028501 |
9 | + - allow specification of security mirrors (LP: #1006963) |
10 | - add the 'None' datasource (LP: #906669), which will allow jobs |
11 | to run even if there is no "real" datasource found. |
12 | - write ssh authorized keys to console, ssh_authkey_fingerprints |
13 | |
14 | === modified file 'cloudinit/cloud.py' |
15 | --- cloudinit/cloud.py 2012-06-21 16:12:16 +0000 |
16 | +++ cloudinit/cloud.py 2012-08-22 19:21:17 +0000 |
17 | @@ -82,9 +82,6 @@ |
18 | def get_locale(self): |
19 | return self.datasource.get_locale() |
20 | |
21 | - def get_local_mirror(self): |
22 | - return self.datasource.get_local_mirror() |
23 | - |
24 | def get_hostname(self, fqdn=False): |
25 | return self.datasource.get_hostname(fqdn=fqdn) |
26 | |
27 | |
28 | === modified file 'cloudinit/config/cc_apt_update_upgrade.py' |
29 | --- cloudinit/config/cc_apt_update_upgrade.py 2012-08-22 18:12:32 +0000 |
30 | +++ cloudinit/config/cc_apt_update_upgrade.py 2012-08-22 19:21:17 +0000 |
31 | @@ -50,20 +50,25 @@ |
32 | upgrade = util.get_cfg_option_bool(cfg, 'apt_upgrade', False) |
33 | |
34 | release = get_release() |
35 | - mirror = find_apt_mirror(cloud, cfg) |
36 | - if not mirror: |
37 | + mirrors = find_apt_mirror_info(cloud, cfg) |
38 | + if not mirrors or "primary" not in mirrors: |
39 | log.debug(("Skipping module named %s," |
40 | " no package 'mirror' located"), name) |
41 | return |
42 | |
43 | - log.debug("Selected mirror at: %s" % mirror) |
44 | + # backwards compatibility |
45 | + mirror = mirrors["primary"] |
46 | + mirrors["mirror"] = mirror |
47 | + |
48 | + log.debug("mirror info: %s" % mirrors) |
49 | |
50 | if not util.get_cfg_option_bool(cfg, |
51 | 'apt_preserve_sources_list', False): |
52 | - generate_sources_list(release, mirror, cloud, log) |
53 | - old_mir = util.get_cfg_option_str(cfg, 'apt_old_mirror', |
54 | - "archive.ubuntu.com/ubuntu") |
55 | - rename_apt_lists(old_mir, mirror) |
56 | + generate_sources_list(release, mirrors, cloud, log) |
57 | + old_mirrors = cfg.get('apt_old_mirrors', |
58 | + {"primary": "archive.ubuntu.com/ubuntu", |
59 | + "security": "security.ubuntu.com/ubuntu"}) |
60 | + rename_apt_lists(old_mirrors, mirrors) |
61 | |
62 | # Set up any apt proxy |
63 | proxy = cfg.get("apt_proxy", None) |
64 | @@ -81,8 +86,10 @@ |
65 | |
66 | # Process 'apt_sources' |
67 | if 'apt_sources' in cfg: |
68 | - errors = add_sources(cloud, cfg['apt_sources'], |
69 | - {'MIRROR': mirror, 'RELEASE': release}) |
70 | + params = mirrors |
71 | + params['RELEASE'] = release |
72 | + params['MIRROR'] = mirror |
73 | + errors = add_sources(cloud, cfg['apt_sources'], params) |
74 | for e in errors: |
75 | log.warn("Source Error: %s", ':'.join(e)) |
76 | |
77 | @@ -146,15 +153,18 @@ |
78 | return string |
79 | |
80 | |
81 | -def rename_apt_lists(omirror, new_mirror, lists_d="/var/lib/apt/lists"): |
82 | - oprefix = os.path.join(lists_d, mirror2lists_fileprefix(omirror)) |
83 | - nprefix = os.path.join(lists_d, mirror2lists_fileprefix(new_mirror)) |
84 | - if oprefix == nprefix: |
85 | - return |
86 | - olen = len(oprefix) |
87 | - for filename in glob.glob("%s_*" % oprefix): |
88 | - # TODO(harlowja) use the cloud.paths.join... |
89 | - util.rename(filename, "%s%s" % (nprefix, filename[olen:])) |
90 | +def rename_apt_lists(old_mirrors, new_mirrors, lists_d="/var/lib/apt/lists"): |
91 | + for (name, omirror) in old_mirrors.iteritems(): |
92 | + nmirror = new_mirrors.get(name) |
93 | + if not nmirror: |
94 | + continue |
95 | + oprefix = os.path.join(lists_d, mirror2lists_fileprefix(omirror)) |
96 | + nprefix = os.path.join(lists_d, mirror2lists_fileprefix(nmirror)) |
97 | + if oprefix == nprefix: |
98 | + continue |
99 | + olen = len(oprefix) |
100 | + for filename in glob.glob("%s_*" % oprefix): |
101 | + util.rename(filename, "%s%s" % (nprefix, filename[olen:])) |
102 | |
103 | |
104 | def get_release(): |
105 | @@ -162,14 +172,17 @@ |
106 | return stdout.strip() |
107 | |
108 | |
109 | -def generate_sources_list(codename, mirror, cloud, log): |
110 | +def generate_sources_list(codename, mirrors, cloud, log): |
111 | template_fn = cloud.get_template_filename('sources.list') |
112 | - if template_fn: |
113 | - params = {'mirror': mirror, 'codename': codename} |
114 | - out_fn = cloud.paths.join(False, '/etc/apt/sources.list') |
115 | - templater.render_to_file(template_fn, out_fn, params) |
116 | - else: |
117 | + if not template_fn: |
118 | log.warn("No template found, not rendering /etc/apt/sources.list") |
119 | + return |
120 | + |
121 | + params = {'codename': codename} |
122 | + for k in mirrors: |
123 | + params[k] = mirrors[k] |
124 | + out_fn = cloud.paths.join(False, '/etc/apt/sources.list') |
125 | + templater.render_to_file(template_fn, out_fn, params) |
126 | |
127 | |
128 | def add_sources(cloud, srclist, template_params=None): |
129 | @@ -231,43 +244,47 @@ |
130 | return errorlist |
131 | |
132 | |
133 | -def find_apt_mirror(cloud, cfg): |
134 | +def find_apt_mirror_info(cloud, cfg): |
135 | """find an apt_mirror given the cloud and cfg provided.""" |
136 | |
137 | mirror = None |
138 | |
139 | - cfg_mirror = cfg.get("apt_mirror", None) |
140 | - if cfg_mirror: |
141 | - mirror = cfg["apt_mirror"] |
142 | - elif "apt_mirror_search" in cfg: |
143 | - mirror = util.search_for_mirror(cfg['apt_mirror_search']) |
144 | - else: |
145 | - mirror = cloud.get_local_mirror() |
146 | - |
147 | + # this is less preferred way of specifying mirror preferred would be to |
148 | + # use the distro's search or package_mirror. |
149 | + mirror = cfg.get("apt_mirror", None) |
150 | + |
151 | + search = cfg.get("apt_mirror_search", None) |
152 | + if not mirror and search: |
153 | + mirror = util.search_for_mirror(search) |
154 | + |
155 | + if (not mirror and |
156 | + util.get_cfg_option_bool(cfg, "apt_mirror_search_dns", False)): |
157 | mydom = "" |
158 | - |
159 | doms = [] |
160 | |
161 | - if not mirror: |
162 | - # if we have a fqdn, then search its domain portion first |
163 | - (_hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud) |
164 | - mydom = ".".join(fqdn.split(".")[1:]) |
165 | - if mydom: |
166 | - doms.append(".%s" % mydom) |
167 | - |
168 | - if (not mirror and |
169 | - util.get_cfg_option_bool(cfg, "apt_mirror_search_dns", False)): |
170 | - doms.extend((".localdomain", "",)) |
171 | - |
172 | - mirror_list = [] |
173 | - distro = cloud.distro.name |
174 | - mirrorfmt = "http://%s-mirror%s/%s" % (distro, "%s", distro) |
175 | - for post in doms: |
176 | - mirror_list.append(mirrorfmt % (post)) |
177 | - |
178 | - mirror = util.search_for_mirror(mirror_list) |
179 | - |
180 | - if not mirror: |
181 | - mirror = cloud.distro.get_package_mirror() |
182 | - |
183 | - return mirror |
184 | + # if we have a fqdn, then search its domain portion first |
185 | + (_hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud) |
186 | + mydom = ".".join(fqdn.split(".")[1:]) |
187 | + if mydom: |
188 | + doms.append(".%s" % mydom) |
189 | + |
190 | + doms.extend((".localdomain", "",)) |
191 | + |
192 | + mirror_list = [] |
193 | + distro = cloud.distro.name |
194 | + mirrorfmt = "http://%s-mirror%s/%s" % (distro, "%s", distro) |
195 | + for post in doms: |
196 | + mirror_list.append(mirrorfmt % (post)) |
197 | + |
198 | + mirror = util.search_for_mirror(mirror_list) |
199 | + |
200 | + mirror_info = cloud.datasource.get_package_mirror_info() |
201 | + |
202 | + # this is a bit strange. |
203 | + # if mirror is set, then one of the legacy options above set it |
204 | + # but they do not cover security. so we need to get that from |
205 | + # get_package_mirror_info |
206 | + if mirror: |
207 | + mirror_info.update({'primary': mirror}) |
208 | + |
209 | + return mirror_info |
210 | |
211 | === modified file 'cloudinit/distros/__init__.py' |
212 | --- cloudinit/distros/__init__.py 2012-08-22 18:12:32 +0000 |
213 | +++ cloudinit/distros/__init__.py 2012-08-22 19:21:17 +0000 |
214 | @@ -23,6 +23,8 @@ |
215 | from StringIO import StringIO |
216 | |
217 | import abc |
218 | +import os |
219 | +import re |
220 | |
221 | from cloudinit import importer |
222 | from cloudinit import log as logging |
223 | @@ -75,8 +77,26 @@ |
224 | def update_package_sources(self): |
225 | raise NotImplementedError() |
226 | |
227 | - def get_package_mirror(self): |
228 | - return self.get_option('package_mirror') |
229 | + def get_primary_arch(self): |
230 | + arch = os.uname[4] |
231 | + if arch in ("i386", "i486", "i586", "i686"): |
232 | + return "i386" |
233 | + return arch |
234 | + |
235 | + def _get_arch_package_mirror_info(self, arch=None): |
236 | + mirror_info = self.get_option("package_mirrors", None) |
237 | + if arch == None: |
238 | + arch = self.get_primary_arch() |
239 | + return _get_arch_package_mirror_info(mirror_info, arch) |
240 | + |
241 | + def get_package_mirror_info(self, arch=None, |
242 | + availability_zone=None): |
243 | + # this resolves the package_mirrors config option |
244 | + # down to a single dict of {mirror_name: mirror_url} |
245 | + arch_info = self._get_arch_package_mirror_info(arch) |
246 | + |
247 | + return _get_package_mirror_info(availability_zone=availability_zone, |
248 | + mirror_info=arch_info) |
249 | |
250 | def apply_network(self, settings, bring_up=True): |
251 | # Write it out |
252 | @@ -151,6 +171,55 @@ |
253 | return False |
254 | |
255 | |
256 | +def _get_package_mirror_info(mirror_info, availability_zone=None, |
257 | + mirror_filter=util.search_for_mirror): |
258 | + # given a arch specific 'mirror_info' entry (from package_mirrors) |
259 | + # search through the 'search' entries, and fallback appropriately |
260 | + # return a dict with only {name: mirror} entries. |
261 | + |
262 | + ec2_az_re = ("^[a-z][a-z]-(%s)-[1-9][0-9]*[a-z]$" % |
263 | + "north|northeast|east|southeast|south|southwest|west|northwest") |
264 | + |
265 | + subst = {} |
266 | + if availability_zone: |
267 | + subst['availability_zone'] = availability_zone |
268 | + |
269 | + if availability_zone and re.match(ec2_az_re, availability_zone): |
270 | + subst['ec2_region'] = "%s" % availability_zone[0:-1] |
271 | + |
272 | + results = {} |
273 | + for (name, mirror) in mirror_info.get('failsafe', {}).iteritems(): |
274 | + results[name] = mirror |
275 | + |
276 | + for (name, searchlist) in mirror_info.get('search', {}).iteritems(): |
277 | + mirrors = [] |
278 | + for tmpl in searchlist: |
279 | + try: |
280 | + mirrors.append(tmpl % subst) |
281 | + except KeyError: |
282 | + pass |
283 | + |
284 | + found = mirror_filter(mirrors) |
285 | + if found: |
286 | + results[name] = found |
287 | + |
288 | + LOG.debug("filtered distro mirror info: %s" % results) |
289 | + |
290 | + return results |
291 | + |
292 | + |
293 | +def _get_arch_package_mirror_info(package_mirrors, arch): |
294 | + # pull out the specific arch from a 'package_mirrors' config option |
295 | + default = None |
296 | + for item in package_mirrors: |
297 | + arches = item.get("arches") |
298 | + if arch in arches: |
299 | + return item |
300 | + if "default" in arches: |
301 | + default = item |
302 | + return default |
303 | + |
304 | + |
305 | def fetch(name): |
306 | locs = importer.find_module(name, |
307 | ['', __name__], |
308 | |
309 | === modified file 'cloudinit/distros/debian.py' |
310 | --- cloudinit/distros/debian.py 2012-06-30 00:06:32 +0000 |
311 | +++ cloudinit/distros/debian.py 2012-08-22 19:21:17 +0000 |
312 | @@ -147,3 +147,7 @@ |
313 | def update_package_sources(self): |
314 | self._runner.run("update-sources", self.package_command, |
315 | ["update"], freq=PER_INSTANCE) |
316 | + |
317 | + def get_primary_arch(self): |
318 | + (arch, _err) = util.subp(['dpkg', '--print-architecture']) |
319 | + return str(arch).strip() |
320 | |
321 | === modified file 'cloudinit/sources/DataSourceCloudStack.py' |
322 | --- cloudinit/sources/DataSourceCloudStack.py 2012-08-22 18:12:32 +0000 |
323 | +++ cloudinit/sources/DataSourceCloudStack.py 2012-08-22 19:21:17 +0000 |
324 | @@ -131,7 +131,8 @@ |
325 | def get_instance_id(self): |
326 | return self.metadata['instance-id'] |
327 | |
328 | - def get_availability_zone(self): |
329 | + @property |
330 | + def availability_zone(self): |
331 | return self.metadata['availability-zone'] |
332 | |
333 | |
334 | |
335 | === modified file 'cloudinit/sources/DataSourceEc2.py' |
336 | --- cloudinit/sources/DataSourceEc2.py 2012-07-16 20:16:27 +0000 |
337 | +++ cloudinit/sources/DataSourceEc2.py 2012-08-22 19:21:17 +0000 |
338 | @@ -83,40 +83,6 @@ |
339 | def get_availability_zone(self): |
340 | return self.metadata['placement']['availability-zone'] |
341 | |
342 | - def get_local_mirror(self): |
343 | - return self.get_mirror_from_availability_zone() |
344 | - |
345 | - def get_mirror_from_availability_zone(self, availability_zone=None): |
346 | - # Return type None indicates there is no cloud specific mirror |
347 | - # Availability is like 'us-west-1b' or 'eu-west-1a' |
348 | - if availability_zone is None: |
349 | - availability_zone = self.get_availability_zone() |
350 | - |
351 | - if self.is_vpc(): |
352 | - return None |
353 | - |
354 | - if not availability_zone: |
355 | - return None |
356 | - |
357 | - mirror_tpl = self.distro.get_option('package_mirror_ec2_template', |
358 | - None) |
359 | - |
360 | - if mirror_tpl is None: |
361 | - return None |
362 | - |
363 | - # in EC2, the 'region' is 'us-east-1' if 'zone' is 'us-east-1a' |
364 | - tpl_params = { |
365 | - 'zone': availability_zone.strip(), |
366 | - 'region': availability_zone[:-1] |
367 | - } |
368 | - mirror_url = mirror_tpl % (tpl_params) |
369 | - |
370 | - found = util.search_for_mirror([mirror_url]) |
371 | - if found is not None: |
372 | - return mirror_url |
373 | - |
374 | - return None |
375 | - |
376 | def _get_url_settings(self): |
377 | mcfg = self.ds_cfg |
378 | if not mcfg: |
379 | @@ -255,6 +221,12 @@ |
380 | return True |
381 | return False |
382 | |
383 | + @property |
384 | + def availability_zone(self): |
385 | + try: |
386 | + return self.metadata['placement']['availability-zone'] |
387 | + except KeyError: |
388 | + return None |
389 | |
390 | # Used to match classes to dependencies |
391 | datasources = [ |
392 | |
393 | === modified file 'cloudinit/sources/__init__.py' |
394 | --- cloudinit/sources/__init__.py 2012-08-20 05:28:14 +0000 |
395 | +++ cloudinit/sources/__init__.py 2012-08-22 19:21:17 +0000 |
396 | @@ -117,9 +117,9 @@ |
397 | def get_locale(self): |
398 | return 'en_US.UTF-8' |
399 | |
400 | - def get_local_mirror(self): |
401 | - # ?? |
402 | - return None |
403 | + @property |
404 | + def availability_zone(self): |
405 | + return self.metadata.get('availability-zone') |
406 | |
407 | def get_instance_id(self): |
408 | if not self.metadata or 'instance-id' not in self.metadata: |
409 | @@ -166,6 +166,10 @@ |
410 | else: |
411 | return hostname |
412 | |
413 | + def get_package_mirror_info(self): |
414 | + return self.distro.get_package_mirror_info( |
415 | + availability_zone=self.availability_zone) |
416 | + |
417 | |
418 | def find_source(sys_cfg, distro, paths, ds_deps, cfg_list, pkg_list): |
419 | ds_list = list_sources(cfg_list, ds_deps, pkg_list) |
420 | |
421 | === modified file 'config/cloud.cfg' |
422 | --- config/cloud.cfg 2012-08-20 21:11:46 +0000 |
423 | +++ config/cloud.cfg 2012-08-22 19:21:17 +0000 |
424 | @@ -74,6 +74,18 @@ |
425 | cloud_dir: /var/lib/cloud/ |
426 | templates_dir: /etc/cloud/templates/ |
427 | upstart_dir: /etc/init/ |
428 | - package_mirror: http://archive.ubuntu.com/ubuntu |
429 | - package_mirror_ec2_template: http://%(region)s.ec2.archive.ubuntu.com/ubuntu/ |
430 | + package_mirrors: |
431 | + - arches: [i386, amd64] |
432 | + failsafe: |
433 | + primary: http://archive.ubuntu.com/ubuntu |
434 | + security: http://security.ubuntu.com/ubuntu |
435 | + search: |
436 | + primary: |
437 | + - http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/ |
438 | + - http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/ |
439 | + security: [] |
440 | + - arches: [armhf, armel, default] |
441 | + failsafe: |
442 | + primary: http://ports.ubuntu.com/ubuntu |
443 | + security: http://ports.ubuntu.com/ubuntu |
444 | ssh_svcname: ssh |
445 | |
446 | === modified file 'templates/sources.list.tmpl' |
447 | --- templates/sources.list.tmpl 2012-07-09 20:41:45 +0000 |
448 | +++ templates/sources.list.tmpl 2012-08-22 19:21:17 +0000 |
449 | @@ -52,9 +52,9 @@ |
450 | # deb http://archive.canonical.com/ubuntu $codename partner |
451 | # deb-src http://archive.canonical.com/ubuntu $codename partner |
452 | |
453 | -deb http://security.ubuntu.com/ubuntu $codename-security main |
454 | -deb-src http://security.ubuntu.com/ubuntu $codename-security main |
455 | -deb http://security.ubuntu.com/ubuntu $codename-security universe |
456 | -deb-src http://security.ubuntu.com/ubuntu $codename-security universe |
457 | -# deb http://security.ubuntu.com/ubuntu $codename-security multiverse |
458 | -# deb-src http://security.ubuntu.com/ubuntu $codename-security multiverse |
459 | +deb $security $codename-security main |
460 | +deb-src $security $codename-security main |
461 | +deb $security $codename-security universe |
462 | +deb-src $security $codename-security universe |
463 | +# deb $security $codename-security multiverse |
464 | +# deb-src $security $codename-security multiverse |
465 | |
466 | === added directory 'tests/unittests/test_distros' |
467 | === added file 'tests/unittests/test_distros/test_generic.py' |
468 | --- tests/unittests/test_distros/test_generic.py 1970-01-01 00:00:00 +0000 |
469 | +++ tests/unittests/test_distros/test_generic.py 2012-08-22 19:21:17 +0000 |
470 | @@ -0,0 +1,121 @@ |
471 | +from mocker import MockerTestCase |
472 | + |
473 | +from cloudinit import distros |
474 | + |
475 | +unknown_arch_info = { |
476 | + 'arches': ['default'], |
477 | + 'failsafe': {'primary': 'http://fs-primary-default', |
478 | + 'security': 'http://fs-security-default'} |
479 | +} |
480 | + |
481 | +package_mirrors = [ |
482 | + {'arches': ['i386', 'amd64'], |
483 | + 'failsafe': {'primary': 'http://fs-primary-intel', |
484 | + 'security': 'http://fs-security-intel'}, |
485 | + 'search': { |
486 | + 'primary': ['http://%(ec2_region)s.ec2/', |
487 | + 'http://%(availability_zone)s.clouds/'], |
488 | + 'security': ['http://security-mirror1-intel', |
489 | + 'http://security-mirror2-intel']}}, |
490 | + {'arches': ['armhf', 'armel'], |
491 | + 'failsafe': {'primary': 'http://fs-primary-arm', |
492 | + 'security': 'http://fs-security-arm'}}, |
493 | + unknown_arch_info |
494 | +] |
495 | + |
496 | +gpmi = distros._get_package_mirror_info # pylint: disable=W0212 |
497 | +gapmi = distros._get_arch_package_mirror_info # pylint: disable=W0212 |
498 | + |
499 | + |
500 | +class TestGenericDistro(MockerTestCase): |
501 | + |
502 | + def return_first(self, mlist): |
503 | + if not mlist: |
504 | + return None |
505 | + return mlist[0] |
506 | + |
507 | + def return_second(self, mlist): |
508 | + if not mlist: |
509 | + return None |
510 | + return mlist[1] |
511 | + |
512 | + def return_none(self, _mlist): |
513 | + return None |
514 | + |
515 | + def return_last(self, mlist): |
516 | + if not mlist: |
517 | + return None |
518 | + return(mlist[-1]) |
519 | + |
520 | + def setUp(self): |
521 | + super(TestGenericDistro, self).setUp() |
522 | + # Make a temp directoy for tests to use. |
523 | + self.tmp = self.makeDir() |
524 | + |
525 | + def test_arch_package_mirror_info_unknown(self): |
526 | + """for an unknown arch, we should get back that with arch 'default'.""" |
527 | + arch_mirrors = gapmi(package_mirrors, arch="unknown") |
528 | + self.assertEqual(unknown_arch_info, arch_mirrors) |
529 | + |
530 | + def test_arch_package_mirror_info_known(self): |
531 | + arch_mirrors = gapmi(package_mirrors, arch="amd64") |
532 | + self.assertEqual(package_mirrors[0], arch_mirrors) |
533 | + |
534 | + def test_get_package_mirror_info_az_ec2(self): |
535 | + arch_mirrors = gapmi(package_mirrors, arch="amd64") |
536 | + |
537 | + results = gpmi(arch_mirrors, availability_zone="us-east-1a", |
538 | + mirror_filter=self.return_first) |
539 | + self.assertEqual(results, |
540 | + {'primary': 'http://us-east-1.ec2/', |
541 | + 'security': 'http://security-mirror1-intel'}) |
542 | + |
543 | + results = gpmi(arch_mirrors, availability_zone="us-east-1a", |
544 | + mirror_filter=self.return_second) |
545 | + self.assertEqual(results, |
546 | + {'primary': 'http://us-east-1a.clouds/', |
547 | + 'security': 'http://security-mirror2-intel'}) |
548 | + |
549 | + results = gpmi(arch_mirrors, availability_zone="us-east-1a", |
550 | + mirror_filter=self.return_none) |
551 | + self.assertEqual(results, package_mirrors[0]['failsafe']) |
552 | + |
553 | + def test_get_package_mirror_info_az_non_ec2(self): |
554 | + arch_mirrors = gapmi(package_mirrors, arch="amd64") |
555 | + |
556 | + results = gpmi(arch_mirrors, availability_zone="nova.cloudvendor", |
557 | + mirror_filter=self.return_first) |
558 | + self.assertEqual(results, |
559 | + {'primary': 'http://nova.cloudvendor.clouds/', |
560 | + 'security': 'http://security-mirror1-intel'}) |
561 | + |
562 | + results = gpmi(arch_mirrors, availability_zone="nova.cloudvendor", |
563 | + mirror_filter=self.return_last) |
564 | + self.assertEqual(results, |
565 | + {'primary': 'http://nova.cloudvendor.clouds/', |
566 | + 'security': 'http://security-mirror2-intel'}) |
567 | + |
568 | + def test_get_package_mirror_info_none(self): |
569 | + arch_mirrors = gapmi(package_mirrors, arch="amd64") |
570 | + |
571 | + # because both search entries here replacement based on |
572 | + # availability-zone, the filter will be called with an empty list and |
573 | + # failsafe should be taken. |
574 | + results = gpmi(arch_mirrors, availability_zone=None, |
575 | + mirror_filter=self.return_first) |
576 | + self.assertEqual(results, |
577 | + {'primary': 'http://fs-primary-intel', |
578 | + 'security': 'http://security-mirror1-intel'}) |
579 | + |
580 | + results = gpmi(arch_mirrors, availability_zone=None, |
581 | + mirror_filter=self.return_last) |
582 | + self.assertEqual(results, |
583 | + {'primary': 'http://fs-primary-intel', |
584 | + 'security': 'http://security-mirror2-intel'}) |
585 | + |
586 | + |
587 | +#def _get_package_mirror_info(mirror_info, availability_zone=None, |
588 | +# mirror_filter=util.search_for_mirror): |
589 | + |
590 | + |
591 | +# vi: ts=4 expandtab |