Skip to content

Commit

Permalink
Move runparts to subp.
Browse files Browse the repository at this point in the history
runparts (run a directory of scripts) seems to fit well in subp
module.  The request to move it there was raised in #416.

Replace use of logexc with LOG.debug as logexc comes from util.
  • Loading branch information
smoser committed Jun 8, 2020
1 parent 3c551f6 commit 3c86ca8
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 40 deletions.
4 changes: 2 additions & 2 deletions cloudinit/config/cc_scripts_per_boot.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

import os

from cloudinit import util
from cloudinit import subp

from cloudinit.settings import PER_ALWAYS

Expand All @@ -38,7 +38,7 @@ def handle(name, _cfg, cloud, log, _args):
# https://forums.aws.amazon.com/thread.jspa?threadID=96918
runparts_path = os.path.join(cloud.get_cpath(), 'scripts', SCRIPT_SUBDIR)
try:
util.runparts(runparts_path)
subp.runparts(runparts_path)
except Exception:
log.warning("Failed to run module %s (%s in %s)",
name, SCRIPT_SUBDIR, runparts_path)
Expand Down
4 changes: 2 additions & 2 deletions cloudinit/config/cc_scripts_per_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

import os

from cloudinit import util
from cloudinit import subp

from cloudinit.settings import PER_INSTANCE

Expand All @@ -41,7 +41,7 @@ def handle(name, _cfg, cloud, log, _args):
# https://forums.aws.amazon.com/thread.jspa?threadID=96918
runparts_path = os.path.join(cloud.get_cpath(), 'scripts', SCRIPT_SUBDIR)
try:
util.runparts(runparts_path)
subp.runparts(runparts_path)
except Exception:
log.warning("Failed to run module %s (%s in %s)",
name, SCRIPT_SUBDIR, runparts_path)
Expand Down
4 changes: 2 additions & 2 deletions cloudinit/config/cc_scripts_per_once.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

import os

from cloudinit import util
from cloudinit import subp

from cloudinit.settings import PER_ONCE

Expand All @@ -39,7 +39,7 @@ def handle(name, _cfg, cloud, log, _args):
# https://forums.aws.amazon.com/thread.jspa?threadID=96918
runparts_path = os.path.join(cloud.get_cpath(), 'scripts', SCRIPT_SUBDIR)
try:
util.runparts(runparts_path)
subp.runparts(runparts_path)
except Exception:
log.warning("Failed to run module %s (%s in %s)",
name, SCRIPT_SUBDIR, runparts_path)
Expand Down
4 changes: 2 additions & 2 deletions cloudinit/config/cc_scripts_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

import os

from cloudinit import util
from cloudinit import subp

from cloudinit.settings import PER_INSTANCE

Expand All @@ -42,7 +42,7 @@ def handle(name, _cfg, cloud, log, _args):
# go here...
runparts_path = os.path.join(cloud.get_ipath_cur(), SCRIPT_SUBDIR)
try:
util.runparts(runparts_path)
subp.runparts(runparts_path)
except Exception:
log.warning("Failed to run module %s (%s in %s)",
name, SCRIPT_SUBDIR, runparts_path)
Expand Down
3 changes: 2 additions & 1 deletion cloudinit/config/cc_scripts_vendor.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import os

from cloudinit import subp
from cloudinit import util

from cloudinit.settings import PER_INSTANCE
Expand All @@ -46,7 +47,7 @@ def handle(name, cfg, cloud, log, _args):
prefix = util.get_cfg_by_path(cfg, ('vendor_data', 'prefix'), [])

try:
util.runparts(runparts_path, exe_prefix=prefix)
subp.runparts(runparts_path, exe_prefix=prefix)
except Exception:
log.warning("Failed to run module %s (%s in %s)",
name, SCRIPT_SUBDIR, runparts_path)
Expand Down
32 changes: 32 additions & 0 deletions cloudinit/subp.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,4 +351,36 @@ def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)


def runparts(dirp, skip_no_exist=True, exe_prefix=None):
if skip_no_exist and not os.path.isdir(dirp):
return

failed = []
attempted = []

if exe_prefix is None:
prefix = []
elif isinstance(exe_prefix, str):
prefix = [str(exe_prefix)]
elif isinstance(exe_prefix, list):
prefix = exe_prefix
else:
raise TypeError("exe_prefix must be None, str, or list")

for exe_name in sorted(os.listdir(dirp)):
exe_path = os.path.join(dirp, exe_name)
if is_exe(exe_path):
attempted.append(exe_path)
try:
subp(prefix + [exe_path], capture=False)
except ProcessExecutionError as e:
LOG.debug(e)
failed.append(exe_name)

if failed and attempted:
raise RuntimeError(
'Runparts: %s failures (%s) in %s attempted commands' %
(len(failed), ",".join(failed), len(attempted)))


# vi: ts=4 expandtab
31 changes: 0 additions & 31 deletions cloudinit/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,37 +749,6 @@ def del_dir(path):
shutil.rmtree(path)


def runparts(dirp, skip_no_exist=True, exe_prefix=None):
if skip_no_exist and not os.path.isdir(dirp):
return

failed = []
attempted = []

if exe_prefix is None:
prefix = []
elif isinstance(exe_prefix, str):
prefix = [str(exe_prefix)]
elif isinstance(exe_prefix, list):
prefix = exe_prefix
else:
raise TypeError("exe_prefix must be None, str, or list")

for exe_name in sorted(os.listdir(dirp)):
exe_path = os.path.join(dirp, exe_name)
if os.path.isfile(exe_path) and os.access(exe_path, os.X_OK):
attempted.append(exe_path)
try:
subp.subp(prefix + [exe_path], capture=False)
except subp.ProcessExecutionError as e:
logexc(LOG, "Failed running %s [%s]", exe_path, e.exit_code)
failed.append(e)

if failed and attempted:
raise RuntimeError('Runparts: %s failures in %s attempted commands'
% (len(failed), len(attempted)))


# read_optional_seed
# returns boolean indicating success or failure (presense of files)
# if files are present, populates 'fill' dictionary with 'user-data' and
Expand Down

0 comments on commit 3c86ca8

Please sign in to comment.