summaryrefslogtreecommitdiff
path: root/cloudinit
diff options
context:
space:
mode:
authorBen Howard <ben.howard@canonical.com>2014-03-18 15:57:30 -0600
committerBen Howard <ben.howard@canonical.com>2014-03-18 15:57:30 -0600
commite91fd55890922d9054523afab4d7e4b268c1be64 (patch)
tree1d3d1ab71180314f590d2d76a82102e5d7e323a2 /cloudinit
parentd9661a8ef4c6003ef48757715965ebb5c071c80b (diff)
downloadvyos-cloud-init-e91fd55890922d9054523afab4d7e4b268c1be64.tar.gz
vyos-cloud-init-e91fd55890922d9054523afab4d7e4b268c1be64.zip
Windows Azure defines the ephemeral0 mount as being a per-boot instead of
per instance. Under a variety of circumstances, the ephemeral device may be presented as a default device. This patch detects when that situation happens and triggers CC modules disk-setup and mounts to run again. Details of changes for cloudinit/sources/DataSourceAzure.py: - auto-detect the location of ephemeral0 - check each boot if ephemeral0 is new - done via NTFS w/ label of "Temporary Storage" w/ no files on it - if device is mounted, datasource will unmount it - if is new, change mounts and disk-setup to always for that boot only
Diffstat (limited to 'cloudinit')
-rw-r--r--cloudinit/sources/DataSourceAzure.py98
1 files changed, 94 insertions, 4 deletions
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
index c7331da5..256e0539 100644
--- a/cloudinit/sources/DataSourceAzure.py
+++ b/cloudinit/sources/DataSourceAzure.py
@@ -18,12 +18,14 @@
import base64
import crypt
+import fnmatch
import os
import os.path
import time
from xml.dom import minidom
from cloudinit import log as logging
+from cloudinit.settings import PER_ALWAYS
from cloudinit import sources
from cloudinit import util
@@ -53,14 +55,15 @@ BUILTIN_CLOUD_CONFIG = {
'disk_setup': {
'ephemeral0': {'table_type': 'mbr',
'layout': True,
- 'overwrite': False}
- },
+ 'overwrite': False},
+ },
'fs_setup': [{'filesystem': 'ext4',
'device': 'ephemeral0.1',
- 'replace_fs': 'ntfs'}]
+ 'replace_fs': 'ntfs'}],
}
DS_CFG_PATH = ['datasource', DS_NAME]
+DEF_EPHEMERAL_LABEL = 'Temporary Storage'
class DataSourceAzureNet(sources.DataSource):
@@ -189,8 +192,17 @@ class DataSourceAzureNet(sources.DataSource):
LOG.warn("failed to get instance id in %s: %s", shcfgxml, e)
pubkeys = pubkeys_from_crt_files(fp_files)
-
self.metadata['public-keys'] = pubkeys
+
+ found_ephemeral = find_ephemeral_disk()
+ if found_ephemeral:
+ self.ds_cfg['disk_aliases']['ephemeral0'] = found_ephemeral
+ LOG.debug("using detected ephemeral0 of %s" % found_ephemeral)
+
+ cc_modules_override = support_new_ephemeral(self.sys_cfg)
+ if cc_modules_override:
+ self.cfg['cloud_config_modules'] = cc_modules_override
+
return True
def device_name_to_device(self, name):
@@ -200,6 +212,84 @@ class DataSourceAzureNet(sources.DataSource):
return self.cfg
+def count_files(mp):
+ return len(fnmatch.filter(os.listdir(mp), '*[!cdrom]*'))
+
+
+def find_ephemeral_part():
+ """
+ Locate the default ephmeral0.1 device. This will be the first device
+ that has a LABEL of DEF_EPHEMERAL_LABEL and is a NTFS device. If Azure
+ gets more ephemeral devices, this logic will only identify the first
+ such device.
+ """
+ c_label_devs = util.find_devs_with("LABEL=%s" % DEF_EPHEMERAL_LABEL)
+ c_fstype_devs = util.find_devs_with("TYPE=ntfs")
+ for dev in c_label_devs:
+ if dev in c_fstype_devs:
+ return dev
+ return None
+
+
+def find_ephemeral_disk():
+ """
+ Get the ephemeral disk.
+ """
+ part_dev = find_ephemeral_part()
+ if part_dev and str(part_dev[-1]).isdigit():
+ return part_dev[:-1]
+ elif part_dev:
+ return part_dev
+ return None
+
+
+def support_new_ephemeral(cfg):
+ """
+ Windows Azure makes ephemeral devices ephemeral to boot; a ephemeral device
+ may be presented as a fresh device, or not.
+
+ Since the knowledge of when a disk is supposed to be plowed under is specific
+ to Windows Azure, the logic resides here in the datasource. When a new ephemeral
+ device is detected, cloud-init overrides the default frequency for both disk-setup
+ and mounts for the current boot only.
+ """
+ device = find_ephemeral_part()
+ if not device:
+ LOG.debug("no default fabric formated ephemeral0.1 found")
+ return None
+ LOG.debug("fabric formated ephemeral0.1 device at %s" % device)
+
+ file_count = 0
+ try:
+ file_count = util.mount_cb(device, count_files)
+ except:
+ return None
+ LOG.debug("fabric prepared ephmeral0.1 has %s files on it" % file_count)
+
+ if file_count >= 1:
+ LOG.debug("fabric prepared ephemeral0.1 will be preserved")
+ return None
+ else:
+ with util.unmounter(device):
+ LOG.debug("unmounted fabric prepared ephemeral0.1")
+
+ LOG.debug("cloud-init will format ephemeral0.1 this boot.")
+ LOG.debug("setting disk_setup and mounts modules 'always' for this boot")
+
+ cc_modules = cfg.get('cloud_config_modules')
+ if cc_modules:
+ mod_list = []
+ for mod in cc_modules:
+ if mod in ("disk_setup", "mounts"):
+ mod_list.append([mod, PER_ALWAYS])
+ LOG.debug("set module '%s' to 'always' for this boot" % mod)
+ else:
+ mod_list.append(mod)
+ return mod_list
+
+ return None
+
+
def handle_set_hostname(enabled, hostname, cfg):
if not util.is_true(enabled):
return