cdist configuration management Latest manual: https://www.cdi.st/manual/latest/ Home page: https://www.cdi.st
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

130 lines
4.1 KiB

import os
import os.path
import sys
import inspect
import argparse
import cdist
import logging
import cdist.argparse
import cdist.configuration
import cdist.exec.util as util
_PREOS_CALL = "commandline"
_PREOS_NAME = "_preos_name"
_PREOS_MARKER = "_cdist_preos"
_PLUGINS_DIR = "preos"
_PLUGINS_PATH = [os.path.join(os.path.dirname(__file__), _PLUGINS_DIR), ]
log = logging.getLogger("PreOS")
def extend_plugins_path(dirs):
for dir in dirs:
preos_dir = os.path.expanduser(os.path.join(dir, "preos"))
if os.path.isdir(preos_dir):
_PLUGINS_PATH.append(preos_dir)
def preos_plugin(obj):
"""It is preos if _PREOS_MARKER is True and has _PREOS_CALL."""
if hasattr(obj, _PREOS_MARKER):
is_preos = getattr(obj, _PREOS_MARKER)
else:
is_preos = False
if is_preos and hasattr(obj, _PREOS_CALL):
yield obj
def scan_preos_dir_plugins(dir):
for fname in os.listdir(dir):
if os.path.isfile(os.path.join(dir, fname)):
fname = os.path.splitext(fname)[0]
module_name = fname
try:
module = __import__(module_name)
yield from preos_plugin(module)
clsmembers = inspect.getmembers(module, inspect.isclass)
for cm in clsmembers:
c = cm[1]
yield from preos_plugin(c)
except ImportError as e:
log.warning("Cannot import '{}': {}".format(module_name, e))
def find_preos_plugins():
for dir in _PLUGINS_PATH:
yield from scan_preos_dir_plugins(dir)
def find_preoses():
preoses = {}
for preos in find_preos_plugins():
if hasattr(preos, _PREOS_NAME):
preos_name = getattr(preos, _PREOS_NAME)
else:
preos_name = preos.__name__.lower()
preoses[preos_name] = preos
return preoses
def check_root():
if os.geteuid() != 0:
raise cdist.Error("Must be run with root privileges")
def get_available_preoses_string(cls):
preoses = [' - {}'.format(x) for x in sorted(set(cls.preoses))]
return "Available PreOS-es:\n{}".format("\n".join(preoses))
class PreOS:
preoses = None
@classmethod
def commandline(cls, argv):
cdist_parser = cdist.argparse.get_parsers()
parser = argparse.ArgumentParser(
description="Create PreOS", prog="cdist preos",
parents=[cdist_parser['loglevel'], ])
parser.add_argument('preos', help='PreOS to create',
nargs='?', default=None)
parser.add_argument('-c', '--conf-dir',
help=('Add configuration directory (one that '
'contains "preos" subdirectory)'),
action='append')
parser.add_argument('-g', '--config-file',
help='Use specified custom configuration file.',
dest="config_file", required=False)
parser.add_argument('-L', '--list-preoses',
help='List available PreOS-es',
action='store_true', default=False)
parser.add_argument('remainder_args', nargs=argparse.REMAINDER)
args = parser.parse_args(argv[1:])
cdist.argparse.handle_loglevel(args)
log.debug("preos args : {}".format(args))
conf_dirs = util.resolve_conf_dirs_from_config_and_args(args)
extend_plugins_path(conf_dirs)
sys.path.extend(_PLUGINS_PATH)
cls.preoses = find_preoses()
if args.list_preoses or not args.preos:
print(get_available_preoses_string(cls))
sys.exit(0)
preos_name = args.preos
if preos_name in cls.preoses:
preos = cls.preoses[preos_name]
func = getattr(preos, _PREOS_CALL)
if inspect.ismodule(preos):
func_args = [preos, args.remainder_args, ]
else:
func_args = [args.remainder_args, ]
log.info("Running preos : {}".format(preos_name))
func(*func_args)
else:
raise cdist.Error(
"Invalid PreOS {}. {}".format(
preos_name, get_available_preoses_string(cls)))