cdist-backup/cdist/preos.py

136 lines
4.1 KiB
Python
Raw Normal View History

2019-09-20 05:15:37 +00:00
import os
import os.path
import sys
import inspect
import argparse
import cdist
import logging
2019-12-06 18:40:05 +00:00
import re
import cdist.argparse
2019-09-20 05:15:37 +00:00
_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), ]
2019-12-06 18:40:05 +00:00
log = logging.getLogger("PreOS")
2019-09-20 05:15:37 +00:00
2019-12-06 18:40:05 +00:00
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)
cdist_home = cdist.home_dir()
if cdist_home:
extend_plugins_path((cdist_home, ))
x = 'CDIST_PATH'
if x in os.environ:
vals = re.split(r'(?<!\\):', os.environ[x])
vals = [x for x in vals if x]
extend_plugins_path(vals)
2019-09-20 05:15:37 +00:00
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")
2019-12-06 18:40:05 +00:00
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))
2019-09-20 05:15:37 +00:00
class PreOS(object):
preoses = None
@classmethod
def commandline(cls, argv):
2019-12-06 18:40:05 +00:00
cdist_parser = cdist.argparse.get_parsers()
2019-09-20 05:15:37 +00:00
parser = argparse.ArgumentParser(
2019-12-06 18:40:05 +00:00
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('-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))
if args.conf_dir:
extend_plugins_path(args.conf_dir)
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)
2019-09-20 05:15:37 +00:00
preos_name = args.preos
if preos_name in cls.preoses:
preos = cls.preoses[preos_name]
func = getattr(preos, _PREOS_CALL)
if inspect.ismodule(preos):
2019-12-06 18:40:05 +00:00
func_args = [preos, args.remainder_args, ]
2019-09-20 05:15:37 +00:00
else:
2019-12-06 18:40:05 +00:00
func_args = [args.remainder_args, ]
2019-09-20 05:15:37 +00:00
log.info("Running preos : {}".format(preos_name))
func(*func_args)
else:
2019-12-06 18:40:05 +00:00
raise cdist.Error(
"Invalid PreOS {}. {}".format(
preos_name, get_available_preoses_string(cls)))