summaryrefslogtreecommitdiff
path: root/cloudinit/net/dhcp.py
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/net/dhcp.py')
-rw-r--r--cloudinit/net/dhcp.py57
1 files changed, 45 insertions, 12 deletions
diff --git a/cloudinit/net/dhcp.py b/cloudinit/net/dhcp.py
index 12cf5097..0db991db 100644
--- a/cloudinit/net/dhcp.py
+++ b/cloudinit/net/dhcp.py
@@ -11,7 +11,8 @@ import re
import signal
from cloudinit.net import (
- EphemeralIPv4Network, find_fallback_nic, get_devicelist)
+ EphemeralIPv4Network, find_fallback_nic, get_devicelist,
+ has_url_connectivity)
from cloudinit.net.network_state import mask_and_ipv4_to_bcast_addr as bcip
from cloudinit import temp_utils
from cloudinit import util
@@ -37,37 +38,69 @@ class NoDHCPLeaseError(Exception):
class EphemeralDHCPv4(object):
- def __init__(self, iface=None):
+ def __init__(self, iface=None, connectivity_url=None):
self.iface = iface
self._ephipv4 = None
+ self.lease = None
+ self.connectivity_url = connectivity_url
def __enter__(self):
+ """Setup sandboxed dhcp context, unless connectivity_url can already be
+ reached."""
+ if self.connectivity_url:
+ if has_url_connectivity(self.connectivity_url):
+ LOG.debug(
+ 'Skip ephemeral DHCP setup, instance has connectivity'
+ ' to %s', self.connectivity_url)
+ return
+ return self.obtain_lease()
+
+ def __exit__(self, excp_type, excp_value, excp_traceback):
+ """Teardown sandboxed dhcp context."""
+ self.clean_network()
+
+ def clean_network(self):
+ """Exit _ephipv4 context to teardown of ip configuration performed."""
+ if self.lease:
+ self.lease = None
+ if not self._ephipv4:
+ return
+ self._ephipv4.__exit__(None, None, None)
+
+ def obtain_lease(self):
+ """Perform dhcp discovery in a sandboxed environment if possible.
+
+ @return: A dict representing dhcp options on the most recent lease
+ obtained from the dhclient discovery if run, otherwise an error
+ is raised.
+
+ @raises: NoDHCPLeaseError if no leases could be obtained.
+ """
+ if self.lease:
+ return self.lease
try:
leases = maybe_perform_dhcp_discovery(self.iface)
except InvalidDHCPLeaseFileError:
raise NoDHCPLeaseError()
if not leases:
raise NoDHCPLeaseError()
- lease = leases[-1]
+ self.lease = leases[-1]
LOG.debug("Received dhcp lease on %s for %s/%s",
- lease['interface'], lease['fixed-address'],
- lease['subnet-mask'])
+ self.lease['interface'], self.lease['fixed-address'],
+ self.lease['subnet-mask'])
nmap = {'interface': 'interface', 'ip': 'fixed-address',
'prefix_or_mask': 'subnet-mask',
'broadcast': 'broadcast-address',
'router': 'routers'}
- kwargs = dict([(k, lease.get(v)) for k, v in nmap.items()])
+ kwargs = dict([(k, self.lease.get(v)) for k, v in nmap.items()])
if not kwargs['broadcast']:
kwargs['broadcast'] = bcip(kwargs['prefix_or_mask'], kwargs['ip'])
+ if self.connectivity_url:
+ kwargs['connectivity_url'] = self.connectivity_url
ephipv4 = EphemeralIPv4Network(**kwargs)
ephipv4.__enter__()
self._ephipv4 = ephipv4
- return lease
-
- def __exit__(self, excp_type, excp_value, excp_traceback):
- if not self._ephipv4:
- return
- self._ephipv4.__exit__(excp_type, excp_value, excp_traceback)
+ return self.lease
def maybe_perform_dhcp_discovery(nic=None):