aboutsummaryrefslogblamecommitdiffstats
path: root/testing/cloud-init/07-add-power_state-module-support.patch
blob: 976bd11f8a86a08eeb1141198bbb2e7256d170e8 (plain) (tree)
































































































                                                                               
--- a/cloudinit/config/cc_power_state_change.py
+++ b/cloudinit/config/cc_power_state_change.py
@@ -33,6 +33,10 @@
 ``condition`` key is omitted or the command specified by the ``condition``
 key returns 0.
 
+.. note::
+    With Alpine Linux any message value specified is ignored as Alpine's halt,
+    poweroff, and reboot commands do not support broadcasting a message.
+
 **Internal name:** ``cc_power_state_change``
 
 **Module frequency:** per instance
@@ -113,7 +117,7 @@
 
 def handle(_name, cfg, _cloud, log, _args):
     try:
-        (args, timeout, condition) = load_power_state(cfg)
+        (args, timeout, condition) = load_power_state(cfg, _cloud.distro.name)
         if args is None:
             log.debug("no power_state provided. doing nothing")
             return
@@ -140,7 +144,7 @@
                  condition, execmd, [args, devnull_fp])
 
 
-def load_power_state(cfg):
+def load_power_state(cfg, distro):
     # returns a tuple of shutdown_command, timeout
     # shutdown_command is None if no config found
     pstate = cfg.get('power_state')
@@ -151,7 +155,10 @@
     if not isinstance(pstate, dict):
         raise TypeError("power_state is not a dict.")
 
-    opt_map = {'halt': '-H', 'poweroff': '-P', 'reboot': '-r'}
+    if distro == 'alpine':
+       opt_map = {'halt': '', 'poweroff': '', 'reboot': ''}
+    else:
+       opt_map = {'halt': '-H', 'poweroff': '-P', 'reboot': '-r'}
 
     mode = pstate.get("mode")
     if mode not in opt_map:
@@ -160,20 +167,39 @@
             (','.join(opt_map.keys()), mode))
 
     delay = pstate.get("delay", "now")
-    # convert integer 30 or string '30' to '+30'
-    try:
-        delay = "+%s" % int(delay)
-    except ValueError:
-        pass
-
-    if delay != "now" and not re.match(r"\+[0-9]+", delay):
-        raise TypeError(
-            "power_state[delay] must be 'now' or '+m' (minutes)."
-            " found '%s'." % delay)
-
-    args = ["shutdown", opt_map[mode], delay]
-    if pstate.get("message"):
-        args.append(pstate.get("message"))
+    if distro == 'alpine':
+        # Convert integer 30 or string '30' to '1800' (seconds) as Alpine's
+        # halt/poweroff/reboot commands take seconds as param with no "+"
+        try:
+            delay = "%s" % int( int(delay) * 60)
+        except ValueError:
+            pass
+
+        if delay != "now" and not re.match(r"[0-9]", delay):
+            raise TypeError(
+                "power_state[delay] must be 'now' or '+m' (minutes)."
+                " found '%s'." % delay)
+
+        if delay == "now":
+            # Alpine's halt/poweroff/reboot don't understand "now"
+            delay = "0"
+
+        args = [mode, "-d", delay]
+    else:
+        # convert integer 30 or string '30' to '+30'
+        try:
+            delay = "+%s" % int(delay)
+        except ValueError:
+            pass
+
+        if delay != "now" and not re.match(r"\+[0-9]+", delay):
+            raise TypeError(
+                "power_state[delay] must be 'now' or '+m' (minutes)."
+                " found '%s'." % delay)
+
+        args = ["shutdown", opt_map[mode], delay]
+        if pstate.get("message"):
+            args.append(pstate.get("message"))
 
     try:
         timeout = float(pstate.get('timeout', 30.0))