diff options
Diffstat (limited to 'cloudinit')
-rw-r--r-- | cloudinit/CloudConfig/cc_apt_update_upgrade.py | 49 | ||||
-rw-r--r-- | cloudinit/DataSource.py | 2 | ||||
-rw-r--r-- | cloudinit/DataSourceEc2.py | 2 | ||||
-rw-r--r-- | cloudinit/util.py | 29 |
4 files changed, 74 insertions, 8 deletions
diff --git a/cloudinit/CloudConfig/cc_apt_update_upgrade.py b/cloudinit/CloudConfig/cc_apt_update_upgrade.py index 495b8522..10707c77 100644 --- a/cloudinit/CloudConfig/cc_apt_update_upgrade.py +++ b/cloudinit/CloudConfig/cc_apt_update_upgrade.py @@ -27,10 +27,8 @@ def handle(name,cfg,cloud,log,args): upgrade = util.get_cfg_option_bool(cfg, 'apt_upgrade', False) release = get_release() - if cfg.has_key("apt_mirror"): - mirror = cfg["apt_mirror"] - else: - mirror = cloud.get_mirror() + + mirror = find_apt_mirror(cloud, cfg) if not util.get_cfg_option_bool(cfg, \ 'apt_preserve_sources_list', False): @@ -162,3 +160,46 @@ def add_sources(srclist, searchList={ }): return(elst) +def find_apt_mirror(cloud, cfg): + """ find an apt_mirror given the cloud and cfg provided """ + + # TODO: distro and defaults should be configurable + distro = "ubuntu" + defaults = { + 'ubuntu': "http://archive.ubuntu.com/ubuntu", + 'debian': "http://archive.debian.org/debian", + } + mirror = None + + if cfg.has_key("apt_mirror"): + mirror = [cfg["apt_mirror"],] + elif cfg.has_key("apt_mirror_search"): + mirror = util.search_for_mirror(cfg['apt_mirror_search']) + else: + if cloud: + mirror = cloud.get_mirror() + + mydom = "" + + doms = [] + + if not mirror and cloud: + # if we have a fqdn, then search its domain portion first + ( hostname, fqdn ) = util.get_hostname_fqdn(cfg, cloud) + mydom = ".".join(fqdn.split(".")[1:]) + if mydom: + doms.append(".%s" % mydom) + + doms.extend((".localdomain", "",)) + + mirror_list = [] + for post in doms: + mirror_list.append("http://ubuntu-mirror%s/ubuntu" % post) + + print "searching %s" % mirror_list + mirror = util.search_for_mirror(mirror_list) + + if not mirror: + mirror = defaults[distro] + + return mirror diff --git a/cloudinit/DataSource.py b/cloudinit/DataSource.py index 597760fa..06061a2e 100644 --- a/cloudinit/DataSource.py +++ b/cloudinit/DataSource.py @@ -94,7 +94,7 @@ class DataSource: return('en_US.UTF-8') def get_local_mirror(self): - return('http://archive.ubuntu.com/ubuntu/') + return None def get_instance_id(self): if 'instance-id' not in self.metadata: diff --git a/cloudinit/DataSourceEc2.py b/cloudinit/DataSourceEc2.py index 0d8f358f..908a29cd 100644 --- a/cloudinit/DataSourceEc2.py +++ b/cloudinit/DataSourceEc2.py @@ -69,7 +69,7 @@ class DataSourceEc2(DataSource.DataSource): if availability_zone == None: availability_zone = self.get_availability_zone() - fallback = 'http://archive.ubuntu.com/ubuntu/' + fallback = None if self.is_vpc(): return fallback diff --git a/cloudinit/util.py b/cloudinit/util.py index 0c457128..dc461f6c 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -24,9 +24,11 @@ from Cheetah.Template import Template import urllib2 import urllib import logging +import re +import socket import time import traceback -import re +import urlparse try: import selinux @@ -97,7 +99,7 @@ def get_cfg_by_path(yobj,keyp,default=None): cur = cur[tok] return(cur) -# merge values from src into cand. +# merge values from cand into source # if src has a key, cand will not override def mergedict(src,cand): if isinstance(src,dict) and isinstance(cand,dict): @@ -498,3 +500,26 @@ def get_fqdn_from_hosts(hostname, filename="/etc/hosts"): pass return fqdn + +def is_resolvable(name): + """ determine if a url is resolvable, return a boolean """ + try: + socket.getaddrinfo(name, None) + return True + except socket.gaierror as e: + return False + +def is_resolvable_url(url): + """ determine if this url is resolvable (existing or ip) """ + return(is_resolvable(urlparse.urlparse(url).hostname)) + +def search_for_mirror(candidates): + """ Search through a list of mirror urls for one that works """ + for cand in candidates: + try: + if is_resolvable_url(cand): + return cand + except Exception as e: + raise + + return None |