diff --git a/cdist/config.py b/cdist/config.py index 14c99fe8..2ce50b52 100644 --- a/cdist/config.py +++ b/cdist/config.py @@ -130,6 +130,25 @@ class Config(object): for host in source: yield host + @staticmethod + def construct_remote_exec_copy_patterns(args): + # default remote cmd patterns + args.remote_exec_pattern = None + args.remote_copy_pattern = None + + args_dict = vars(args) + # if remote-exec and/or remote-copy args are None then user + # didn't specify command line options nor env vars: + # inspect multiplexing options for default cdist.REMOTE_COPY/EXEC + if (args_dict['remote_copy'] is None or + args_dict['remote_exec'] is None): + mux_opts = inspect_ssh_mux_opts() + if args_dict['remote_exec'] is None: + args.remote_exec_pattern = cdist.REMOTE_EXEC + mux_opts + if args_dict['remote_copy'] is None: + args.remote_copy_pattern = cdist.REMOTE_COPY + mux_opts + + @classmethod def commandline(cls, args): """Configure remote system""" @@ -166,32 +185,14 @@ class Config(object): failed_hosts = [] time_start = time.time() - # default remote cmd patterns - args.remote_exec_pattern = None - args.remote_copy_pattern = None - - args_dict = vars(args) - # if remote-exec and/or remote-copy args are None then user - # didn't specify command line options nor env vars: - # inspect multiplexing options for default cdist.REMOTE_COPY/EXEC - if (args_dict['remote_copy'] is None or - args_dict['remote_exec'] is None): - mux_opts = inspect_ssh_mux_opts() - if args_dict['remote_exec'] is None: - args.remote_exec_pattern = cdist.REMOTE_EXEC + mux_opts - if args_dict['remote_copy'] is None: - args.remote_copy_pattern = cdist.REMOTE_COPY + mux_opts - - if args.out_path: - base_root_path = args.out_path - else: - base_root_path = tempfile.mkdtemp() + cls.construct_remote_exec_copy_patterns(args) + base_root_path = cls.create_base_root_path(args.out_path) hostcnt = 0 for host in itertools.chain(cls.hosts(args.host), cls.hosts(args.hostfile)): - hostdir = cdist.str_hash(host) - host_base_path = os.path.join(base_root_path, hostdir) + host_base_path, hostdir = cls.create_host_base_dirs( + host, hostdir) log.debug("Base root path for target host \"{}\" is \"{}\"".format( host, host_base_path)) @@ -320,13 +321,22 @@ class Config(object): raise - # FIXME begin to cleanup with this method @staticmethod - def create_host_tmpdir(host): - base_dir = tempfile.mkdtemp() - hostdir = cdist.str_hash(host) + def create_base_root_path(out_path=None): + if out_path: + base_root_path = out_path + else: + base_root_path = tempfile.mkdtemp() - return (base_dir, hostdir) + return base_root_path + + + @staticmethod + def create_host_base_dirs(host, base_root_path): + hostdir = cdist.str_hash(host) + host_base_path = os.path.join(base_root_path, hostdir) + + return (host_base_path, hostdir) def run(self): diff --git a/cdist/trigger.py b/cdist/trigger.py index ba94cba0..9027c063 100644 --- a/cdist/trigger.py +++ b/cdist/trigger.py @@ -37,13 +37,14 @@ log = logging.getLogger(__name__) class Trigger(): """cdist trigger handling""" - def __init__(self, http_port=None, dry_run=False, ipv4only=False): + def __init__(self, http_port=None, dry_run=False, ipv4only=False, + cdistargs=None): self.log = logging.getLogger("trigger") self.dry_run = dry_run self.http_port = int(http_port) self.ipv4only = ipv4only - self.args = "fun" + self.args = cdistargs # can only be set once multiprocessing.set_start_method('forkserver') @@ -68,7 +69,11 @@ class Trigger(): @staticmethod def commandline(args): - t = Trigger(http_port=args.http_port, ipv4only=args.ipv4) + http_port = args.http_port + ipv4only = args.ipv4 + del args.http_port + del args.ipv4 + t = Trigger(http_port=http_port, ipv4only=ipv4only, cdistargs=args) t.run() class TriggerHttp(BaseHTTPRequestHandler): @@ -78,13 +83,16 @@ class TriggerHttp(BaseHTTPRequestHandler): code = 200 mode = None - print(self.server.cdistargs) + self.cdistargs = self.server.cdistargs + print(self.cdistargs) + print('path: ' + str(self.path)) m = re.match("^/(?Pconfig|install)/.*", self.path) if m: mode = m.group('mode') else: code = 404 + print('mode: ' + str(mode)) if mode: self.run_cdist(mode, host) @@ -105,8 +113,15 @@ class TriggerHttp(BaseHTTPRequestHandler): module = getattr(cdist, mode) theclass = getattr(module, cname) - host_base_path, hostdir = theclass.create_host_tmpdir(host) - theclass.onehost(host, host_base_path, hostdir, args, parallel=False) + if hasattr(self.cdistargs, 'out_path'): + out_path = self.cdistargs.out_path + else: + out_path = None + host_base_path, hostdir = theclass.create_host_base_dirs( + host, theclass.create_base_root_path(out_path)) + theclass.construct_remote_exec_copy_patterns(self.cdistargs) + theclass.onehost(host, host_base_path, hostdir, self.cdistargs, + parallel=False) class HTTPServerV6(http.server.HTTPServer): diff --git a/scripts/cdist b/scripts/cdist index 1adbdc9c..621020f5 100755 --- a/scripts/cdist +++ b/scripts/cdist @@ -105,20 +105,57 @@ def commandline(): 'banner', parents=[parser['loglevel']]) parser['banner'].set_defaults(func=cdist.banner.banner) - # Config - parser['config'] = parser['sub'].add_parser( - 'config', parents=[parser['loglevel']]) - parser['config'].add_argument( - 'host', nargs='*', help='host(s) to operate on') - parser['config'].add_argument( - '-b', '--enable-beta', - help=('Enable beta functionalities. Beta functionalities ' - 'include the following options: -j/--jobs.'), - action='store_true', dest='beta', default=False) - parser['config'].add_argument( + parser['config_main'] = argparse.ArgumentParser(add_help=False) + parser['config_main'].add_argument( '-c', '--conf-dir', help=('Add configuration directory (can be repeated, ' 'last one wins)'), action='append') + parser['config_main'].add_argument( + '-i', '--initial-manifest', + help='path to a cdist manifest or \'-\' to read from stdin.', + dest='manifest', required=False) + parser['config_main'].add_argument( + '-j', '--jobs', nargs='?', type=check_positive_int, + help=('specify the maximum number of parallel jobs, currently ' + 'only global explorers are supported (currently in beta'), + action='store', dest='jobs', + const=multiprocessing.cpu_count()) + parser['config_main'].add_argument( + '-n', '--dry-run', + help='do not execute code', action='store_true') + parser['config_main'].add_argument( + '-o', '--out-dir', + help='directory to save cdist output in', dest="out_path") + + # remote-copy and remote-exec defaults are environment variables + # if set; if not then None - these will be futher handled after + # parsing to determine implementation default + parser['config_main'].add_argument( + '--remote-copy', + help='Command to use for remote copy (should behave like scp)', + action='store', dest='remote_copy', + default=os.environ.get('CDIST_REMOTE_COPY')) + parser['config_main'].add_argument( + '--remote-exec', + help=('Command to use for remote execution ' + '(should behave like ssh)'), + action='store', dest='remote_exec', + default=os.environ.get('CDIST_REMOTE_EXEC')) + + # Config + parser['config'] = parser['sub'].add_parser( + 'config', parents=[parser['loglevel'], parser['beta'], + parser['config_main']]) + parser['config'].add_argument( + 'host', nargs='*', help='host(s) to operate on') + parser['config'].add_argument( + '-s', '--sequential', + help='operate on multiple hosts sequentially (default)', + action='store_false', dest='parallel') + parser['config'].add_argument( + '-p', '--parallel', + help='operate on multiple hosts in parallel', + action='store_true', dest='parallel') parser['config'].add_argument( '-f', '--file', help=('Read additional hosts to operate on from specified file ' @@ -126,45 +163,6 @@ def commandline(): 'If no host or host file is specified then, by default, ' 'read hosts from stdin.'), dest='hostfile', required=False) - parser['config'].add_argument( - '-i', '--initial-manifest', - help='Path to a cdist manifest or \'-\' to read from stdin.', - dest='manifest', required=False) - parser['config'].add_argument( - '-j', '--jobs', nargs='?', type=check_positive_int, - help=('Specify the maximum number of parallel jobs, currently ' - 'only global explorers are supported (currently in beta'), - action='store', dest='jobs', - const=multiprocessing.cpu_count()) - parser['config'].add_argument( - '-n', '--dry-run', - help='Do not execute code', action='store_true') - parser['config'].add_argument( - '-o', '--out-dir', - help='Directory to save cdist output in', dest="out_path") - parser['config'].add_argument( - '-p', '--parallel', - help='Operate on multiple hosts in parallel', - action='store_true', dest='parallel') - parser['config'].add_argument( - '-s', '--sequential', - help='Operate on multiple hosts sequentially (default)', - action='store_false', dest='parallel') - - # remote-copy and remote-exec defaults are environment variables - # if set; if not then None - these will be futher handled after - # parsing to determine implementation default - parser['config'].add_argument( - '--remote-copy', - help='Command to use for remote copy (should behave like scp)', - action='store', dest='remote_copy', - default=os.environ.get('CDIST_REMOTE_COPY')) - parser['config'].add_argument( - '--remote-exec', - help=('Command to use for remote execution ' - '(should behave like ssh)'), - action='store', dest='remote_exec', - default=os.environ.get('CDIST_REMOTE_EXEC')) parser['config'].set_defaults(func=cdist.config.Config.commandline) # Shell @@ -178,16 +176,15 @@ def commandline(): # Trigger parser['trigger'] = parser['sub'].add_parser( - 'trigger', parents=[parser['loglevel'], parser['beta']]) + 'trigger', parents=[parser['loglevel'], + parser['beta'], + parser['config_main']]) parser['trigger'].add_argument( - '-4', '--ipv4', + '-4', '--ipv4', default=False, help=('Listen only to IPv4 (instead of IPv4 and IPv6)'), action='store_true') parser['trigger'].add_argument( - '-H', '--http-port', + '-H', '--http-port', action='store', default=3000, required=False, help=('Create trigger listener via http on specified port')) - parser['trigger'].add_argument( - '-n', '--dry-run', - help='Do not execute code', action='store_true') parser['trigger'].set_defaults(func=cdist.trigger.Trigger.commandline) # Install