1. Update with smosers code review and comments (and put some of those comments into the files)
2. Rename consume() to consume_userdata() as it helps in figuring out what this does. 3. Fixup the tests due to #2
This commit is contained in:
parent
29cad69e2e
commit
a47bfae2ee
@ -34,13 +34,15 @@ if os.path.exists(os.path.join(possible_topdir, "cloudinit", "__init__.py")):
|
|||||||
|
|
||||||
from cloudinit import log as logging
|
from cloudinit import log as logging
|
||||||
from cloudinit import netinfo
|
from cloudinit import netinfo
|
||||||
from cloudinit import settings
|
|
||||||
from cloudinit import sources
|
from cloudinit import sources
|
||||||
from cloudinit import stages
|
from cloudinit import stages
|
||||||
from cloudinit import templater
|
from cloudinit import templater
|
||||||
from cloudinit import util
|
from cloudinit import util
|
||||||
from cloudinit import version
|
from cloudinit import version
|
||||||
|
|
||||||
|
from cloudinit.settings import (PER_INSTANCE, PER_ALWAYS, PER_ONCE,
|
||||||
|
CLOUD_CONFIG)
|
||||||
|
|
||||||
|
|
||||||
# Module section template
|
# Module section template
|
||||||
MOD_SECTION_TPL = "cloud_%s_modules"
|
MOD_SECTION_TPL = "cloud_%s_modules"
|
||||||
@ -54,9 +56,9 @@ QUERY_DATA_TYPES = [
|
|||||||
|
|
||||||
# Frequency shortname to full name
|
# Frequency shortname to full name
|
||||||
FREQ_SHORT_NAMES = {
|
FREQ_SHORT_NAMES = {
|
||||||
'instance': settings.PER_INSTANCE,
|
'instance': PER_INSTANCE,
|
||||||
'always': settings.PER_ALWAYS,
|
'always': PER_ALWAYS,
|
||||||
'once': settings.PER_ONCE,
|
'once': PER_ONCE,
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG = logging.getLogger()
|
LOG = logging.getLogger()
|
||||||
@ -111,8 +113,15 @@ def main_init(name, args):
|
|||||||
deps = [sources.DEP_FILESYSTEM]
|
deps = [sources.DEP_FILESYSTEM]
|
||||||
|
|
||||||
if not args.local:
|
if not args.local:
|
||||||
# TODO: What is this for??
|
# See doc/kernel-cmdline.txt
|
||||||
root_name = "%s.d" % (settings.CLOUD_CONFIG)
|
#
|
||||||
|
# This is used in maas datasource, in "ephemeral" (read-only root)
|
||||||
|
# environment where the instance netboots to iscsi ro root.
|
||||||
|
# and the entity that controls the pxe config has to configure
|
||||||
|
# the maas datasource.
|
||||||
|
#
|
||||||
|
# Could be used elsewhere, only works on network based (not local).
|
||||||
|
root_name = "%s.d" % (CLOUD_CONFIG)
|
||||||
target_fn = os.path.join(root_name, "91_kernel_cmdline_url.cfg")
|
target_fn = os.path.join(root_name, "91_kernel_cmdline_url.cfg")
|
||||||
util.read_write_cmdline_url(target_fn)
|
util.read_write_cmdline_url(target_fn)
|
||||||
|
|
||||||
@ -194,22 +203,34 @@ def main_init(name, args):
|
|||||||
init.fetch()
|
init.fetch()
|
||||||
except sources.DataSourceNotFoundException:
|
except sources.DataSourceNotFoundException:
|
||||||
util.logexc(LOG, "No instance datasource found!")
|
util.logexc(LOG, "No instance datasource found!")
|
||||||
# TODO: Return 0 or 1??
|
# In the case of cloud-init (net mode) it is a bit
|
||||||
return 1
|
# more likely that the user would consider it
|
||||||
|
# failure if nothing was found. When using
|
||||||
|
# upstart it will also mentions job failure
|
||||||
|
# in console log if exit code is != 0.
|
||||||
|
if args.local:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
return 1
|
||||||
# Stage 6
|
# Stage 6
|
||||||
iid = init.instancify()
|
iid = init.instancify()
|
||||||
LOG.debug("%s will now be targeting instance id: %s", name, iid)
|
LOG.debug("%s will now be targeting instance id: %s", name, iid)
|
||||||
init.update()
|
init.update()
|
||||||
# Stage 7
|
# Stage 7
|
||||||
try:
|
try:
|
||||||
|
# Attempt to consume the data per instance.
|
||||||
|
# This may run user-data handlers and/or perform
|
||||||
|
# url downloads and such as needed.
|
||||||
(ran, _results) = init.cloudify().run('consume_userdata',
|
(ran, _results) = init.cloudify().run('consume_userdata',
|
||||||
init.consume,
|
init.consume_userdata,
|
||||||
args=[settings.PER_INSTANCE],
|
args=[PER_INSTANCE],
|
||||||
freq=settings.PER_INSTANCE)
|
freq=PER_INSTANCE)
|
||||||
if not ran:
|
if not ran:
|
||||||
# Just consume anything that is set to run per
|
# Just consume anything that is set to run per-always
|
||||||
# always if nothing ran in the per instance section
|
# if nothing ran in the per-instance code
|
||||||
init.consume(settings.PER_ALWAYS)
|
#
|
||||||
|
# TODO: should this always happen?? (even if the above runs?)
|
||||||
|
init.consume_userdata(PER_ALWAYS)
|
||||||
except Exception:
|
except Exception:
|
||||||
util.logexc(LOG, "Consuming user data failed!")
|
util.logexc(LOG, "Consuming user data failed!")
|
||||||
return 1
|
return 1
|
||||||
|
@ -192,13 +192,13 @@ class Init(object):
|
|||||||
cfg_list = self.cfg.get('datasource_list') or []
|
cfg_list = self.cfg.get('datasource_list') or []
|
||||||
return (cfg_list, pkg_list)
|
return (cfg_list, pkg_list)
|
||||||
|
|
||||||
def _get_data_source(self, local_only=False):
|
def _get_data_source(self):
|
||||||
if self.datasource:
|
if self.datasource:
|
||||||
return self.datasource
|
return self.datasource
|
||||||
ds = self._restore_from_cache()
|
ds = self._restore_from_cache()
|
||||||
if ds:
|
if ds:
|
||||||
LOG.debug("Restored from cache, datasource: %s", ds)
|
LOG.debug("Restored from cache, datasource: %s", ds)
|
||||||
if not ds and not local_only:
|
if not ds:
|
||||||
(cfg_list, pkg_list) = self._get_datasources()
|
(cfg_list, pkg_list) = self._get_datasources()
|
||||||
# Deep copy so that user-data handlers can not modify
|
# Deep copy so that user-data handlers can not modify
|
||||||
# (which will affect user-data handlers down the line...)
|
# (which will affect user-data handlers down the line...)
|
||||||
@ -209,11 +209,10 @@ class Init(object):
|
|||||||
cfg_list,
|
cfg_list,
|
||||||
pkg_list)
|
pkg_list)
|
||||||
LOG.debug("Loaded datasource %s - %s", dsname, ds)
|
LOG.debug("Loaded datasource %s - %s", dsname, ds)
|
||||||
if ds:
|
self.datasource = ds
|
||||||
self.datasource = ds
|
# Ensure we adjust our path members datasource
|
||||||
# Ensure we adjust our path members datasource
|
# now that we have one (thus allowing ipath to be used)
|
||||||
# now that we have one (thus allowing ipath to be used)
|
self.paths.datasource = ds
|
||||||
self.paths.datasource = ds
|
|
||||||
return ds
|
return ds
|
||||||
|
|
||||||
def _get_instance_subdirs(self):
|
def _get_instance_subdirs(self):
|
||||||
@ -275,8 +274,8 @@ class Init(object):
|
|||||||
"%s\n" % (previous_iid))
|
"%s\n" % (previous_iid))
|
||||||
return iid
|
return iid
|
||||||
|
|
||||||
def fetch(self, local_only=False):
|
def fetch(self):
|
||||||
return self._get_data_source(local_only)
|
return self._get_data_source()
|
||||||
|
|
||||||
def instancify(self):
|
def instancify(self):
|
||||||
return self._reflect_cur_instance()
|
return self._reflect_cur_instance()
|
||||||
@ -312,7 +311,7 @@ class Init(object):
|
|||||||
]
|
]
|
||||||
return def_handlers
|
return def_handlers
|
||||||
|
|
||||||
def consume(self, frequency=PER_INSTANCE):
|
def consume_userdata(self, frequency=PER_INSTANCE):
|
||||||
cdir = self.paths.get_cpath("handlers")
|
cdir = self.paths.get_cpath("handlers")
|
||||||
idir = self._get_ipath("handlers")
|
idir = self._get_ipath("handlers")
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class TestConsumeUserData(MockerTestCase):
|
|||||||
|
|
||||||
log_file = self.capture_log(logging.WARNING)
|
log_file = self.capture_log(logging.WARNING)
|
||||||
ci.fetch()
|
ci.fetch()
|
||||||
ci.consume()
|
ci.consume_userdata()
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"Unhandled non-multipart (text/x-not-multipart) userdata:",
|
"Unhandled non-multipart (text/x-not-multipart) userdata:",
|
||||||
log_file.getvalue())
|
log_file.getvalue())
|
||||||
@ -85,7 +85,7 @@ class TestConsumeUserData(MockerTestCase):
|
|||||||
|
|
||||||
log_file = self.capture_log(logging.WARNING)
|
log_file = self.capture_log(logging.WARNING)
|
||||||
ci.fetch()
|
ci.fetch()
|
||||||
ci.consume()
|
ci.consume_userdata()
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"Unhandled unknown content-type (text/plain)",
|
"Unhandled unknown content-type (text/plain)",
|
||||||
log_file.getvalue())
|
log_file.getvalue())
|
||||||
@ -104,7 +104,7 @@ class TestConsumeUserData(MockerTestCase):
|
|||||||
|
|
||||||
log_file = self.capture_log(logging.WARNING)
|
log_file = self.capture_log(logging.WARNING)
|
||||||
ci.fetch()
|
ci.fetch()
|
||||||
ci.consume()
|
ci.consume_userdata()
|
||||||
self.assertEqual("", log_file.getvalue())
|
self.assertEqual("", log_file.getvalue())
|
||||||
|
|
||||||
def test_mime_text_x_shellscript(self):
|
def test_mime_text_x_shellscript(self):
|
||||||
@ -122,7 +122,7 @@ class TestConsumeUserData(MockerTestCase):
|
|||||||
|
|
||||||
log_file = self.capture_log(logging.WARNING)
|
log_file = self.capture_log(logging.WARNING)
|
||||||
ci.fetch()
|
ci.fetch()
|
||||||
ci.consume()
|
ci.consume_userdata()
|
||||||
self.assertEqual("", log_file.getvalue())
|
self.assertEqual("", log_file.getvalue())
|
||||||
|
|
||||||
def test_mime_text_plain_shell(self):
|
def test_mime_text_plain_shell(self):
|
||||||
@ -140,5 +140,5 @@ class TestConsumeUserData(MockerTestCase):
|
|||||||
|
|
||||||
log_file = self.capture_log(logging.WARNING)
|
log_file = self.capture_log(logging.WARNING)
|
||||||
ci.fetch()
|
ci.fetch()
|
||||||
ci.consume()
|
ci.consume_userdata()
|
||||||
self.assertEqual("", log_file.getvalue())
|
self.assertEqual("", log_file.getvalue())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user