summaryrefslogtreecommitdiff
path: root/cloudinit
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit')
-rw-r--r--cloudinit/CloudConfig/cc_apt_update_upgrade.py49
-rw-r--r--cloudinit/DataSource.py2
-rw-r--r--cloudinit/DataSourceEc2.py2
-rw-r--r--cloudinit/util.py29
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