From c21ef05925954e5781c793429316cd4eff64ee37 Mon Sep 17 00:00:00 2001
From: Scott Moser <smoser@ubuntu.com>
Date: Thu, 26 May 2016 15:51:09 -0400
Subject: fixes. seemingly working first boot on config drive

bigger things here:
 * fix the checking for stop_files.
   the check for no-net actually checked the size of the file
   and the implementation was just touching it. so it never would
   have been found. no-net is valid only in upstart anyway.

   do not stop early on presense of the obj_pkl but check it.
   this is required since we write the obj_pkl on exit when
   local mode finds a datasource but found in network mode.

 * use 'mode' rather than checking args.local.
   set mode to be sources.DSMODE_NETWORK or sources.DSMODE_LOCAL
   for easier / more consistent checking.

 * log exit paths.
---
 bin/cloud-init | 52 ++++++++++++++++++++++++++++++++++------------------
 1 file changed, 34 insertions(+), 18 deletions(-)

diff --git a/bin/cloud-init b/bin/cloud-init
index ffd1f2cc..29e9b521 100755
--- a/bin/cloud-init
+++ b/bin/cloud-init
@@ -211,32 +211,31 @@ def main_init(name, args):
         util.logexc(LOG, "Failed to initialize, likely bad things to come!")
     # Stage 4
     path_helper = init.paths
-    if not args.local:
+    mode = sources.DSMODE_LOCAL if args.local else sources.DSMODE_NETWORK
+
+    if mode == sources.DSMODE_NETWORK:
         existing = "trust"
         sys.stderr.write("%s\n" % (netinfo.debug_info()))
         LOG.debug(("Checking to see if files that we need already"
                    " exist from a previous run that would allow us"
                    " to stop early."))
+        # no-net is written by upstart cloud-init-nonet when network failed
+        # to come up
         stop_files = [
             os.path.join(path_helper.get_cpath("data"), "no-net"),
-            path_helper.get_ipath_cur("obj_pkl"),
         ]
         existing_files = []
         for fn in stop_files:
-            try:
-                c = util.load_file(fn)
-                if len(c):
-                    existing_files.append((fn, len(c)))
-            except Exception:
-                pass
+            if os.path.isfile(fn):
+                existing_files.append(fn)
+
         if existing_files:
-            LOG.debug("Exiting early due to the existence of %s files",
-                      existing_files)
+            LOG.debug("[%s] Exiting. stop file %s existed",
+                      mode, existing_files)
             return (None, [])
         else:
             LOG.debug("Execution continuing, no previous run detected that"
                       " would allow us to stop early.")
-
     else:
         existing = "check"
         if util.get_cfg_option_bool(init.cfg, 'manual_cache_clean', False):
@@ -249,35 +248,52 @@ def main_init(name, args):
     # Stage 5
     try:
         init.fetch(existing=existing)
+        # if in network mode, and the datasource is local
+        # then work was done at that stage.
+        if mode == sources.DSMODE_NETWORK and init.datasource.dsmode != mode:
+            LOG.debug("[%s] Exiting. datasource %s in local mode",
+                      mode, init.datasource)
+            return (None, [])
     except sources.DataSourceNotFoundException:
         # In the case of 'cloud-init init' without '--local' it is a bit
         # 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:
+        if mode == sources.DSMODE_LOCAL:
             LOG.debug("No local datasource found")
         else:
             util.logexc(LOG, ("No instance datasource found!"
                               " Likely bad things to come!"))
         if not args.force:
             init.apply_network_config(bring_up=not args.local)
-            if args.local:
+            LOG.debug("[%s] Exiting without datasource in local mode", mode)
+            if mode == sources.DSMODE_LOCAL:
                 return (None, [])
             else:
                 return (None, ["No instance datasource found."])
+        else:
+            LOG.debug("[%s] barreling on in force mode without datasource",
+                      mode)
 
     # Stage 6
     iid = init.instancify()
-    LOG.debug("%s will now be targeting instance id: %s", name, iid)
+    LOG.debug("[%s] %s will now be targeting instance id: %s. new=%s",
+              mode, name, iid, init.is_new_instance())
 
     if init.is_new_instance():
         # on new instance, apply network config.
         # in network mode 'bring_up' must be passed in as the OS
         # has already brought up networking.
-        init.apply_network_config(bring_up=not args.local)
+        init.apply_network_config(bring_up=bool(mode != sources.DSMODE_LOCAL))
 
-    if args.local and init.datasource.dsmode != sources.DSMODE_LOCAL:
-        return (init.datasource, [])
+    if mode == sources.DSMODE_LOCAL:
+        if init.datasource.dsmode != mode:
+            LOG.debug("[%s] Exiting. datasource %s not in local mode.",
+                      mode, init.datasource)
+            return (init.datasource, [])
+        else:
+            LOG.debug("[%s] %s is in local mode, will apply init modules now.",
+                      mode, init.datasource)
 
     # update fully realizes user-data (pulling in #include if necessary)
     init.update()
@@ -532,7 +548,7 @@ def status_wrapper(name, args, data_d=None, link_d=None):
         v1[mode]['errors'] = [str(e) for e in errors]
 
     except Exception as e:
-        util.logexc(LOG, "failed of stage %s", mode)
+        util.logexc(LOG, "failed stage %s", mode)
         print_exc("failed run of stage %s" % mode)
         v1[mode]['errors'] = [str(e)]
 
-- 
cgit v1.2.3