From 2403fc59ee0cf7f81cff1aa17954ad8ca05579df Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 7 Aug 2013 09:24:10 +0200 Subject: [PATCH] refactor commandline: merge into its own class (and add first shell code) Signed-off-by: Nico Schottelius --- cdist/config.py | 2 +- cdist/config_install.py | 95 ++++++++++++++++++++++++++++++++++++ cdist/shell.py | 40 +++++++++++++++ scripts/cdist | 105 +++++----------------------------------- 4 files changed, 147 insertions(+), 95 deletions(-) create mode 100644 cdist/shell.py diff --git a/cdist/config.py b/cdist/config.py index 9af25b75..2c6c2e6d 100644 --- a/cdist/config.py +++ b/cdist/config.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- # -# 2010-2011 Nico Schottelius (nico-cdist at schottelius.org) +# 2010-2013 Nico Schottelius (nico-cdist at schottelius.org) # # This file is part of cdist. # diff --git a/cdist/config_install.py b/cdist/config_install.py index 72061ca2..f179972f 100644 --- a/cdist/config_install.py +++ b/cdist/config_install.py @@ -23,6 +23,7 @@ import logging import os import shutil +import sys import time import pprint @@ -47,6 +48,100 @@ class ConfigInstall(object): self.context.local.create_files_dirs() self.context.remote.create_files_dirs() + @classmethod + def commandline(cls, args): + """Configure or install remote system""" + import multiprocessing + + # FIXME: Refactor relict - remove later + log = logging.getLogger("cdist") + + initial_manifest_tempfile = None + if args.manifest == '-': + # read initial manifest from stdin + import tempfile + try: + handle, initial_manifest_temp_path = tempfile.mkstemp(prefix='cdist.stdin.') + with os.fdopen(handle, 'w') as fd: + fd.write(sys.stdin.read()) + except (IOError, OSError) as e: + raise cdist.Error("Creating tempfile for stdin data failed: %s" % e) + + args.manifest = initial_manifest_temp_path + import atexit + atexit.register(lambda: os.remove(initial_manifest_temp_path)) + + process = {} + failed_hosts = [] + time_start = time.time() + + for host in args.host: + if args.parallel: + log.debug("Creating child process for %s", host) + process[host] = multiprocessing.Process(target=cls.onehost, args=(host, args, True)) + process[host].start() + else: + try: + cls.onehost(host, args, parallel=False) + except cdist.Error as e: + failed_hosts.append(host) + + # Catch errors in parallel mode when joining + if args.parallel: + for host in process.keys(): + log.debug("Joining process %s", host) + process[host].join() + + if not process[host].exitcode == 0: + failed_hosts.append(host) + + time_end = time.time() + log.info("Total processing time for %s host(s): %s", len(args.host), + (time_end - time_start)) + + if len(failed_hosts) > 0: + raise cdist.Error("Failed to configure the following hosts: " + + " ".join(failed_hosts)) + + @classmethod + def onehost(cls, host, args, parallel): + """Configure or install ONE system""" + + # FIXME: Refactor relict - remove later + log = logging.getLogger("cdist") + + try: + import cdist.context + + context = cdist.context.Context( + target_host=host, + remote_copy=args.remote_copy, + remote_exec=args.remote_exec, + initial_manifest=args.manifest, + add_conf_dirs=args.conf_dir, + exec_path=sys.argv[0], + debug=args.debug) + + c = cls(context) + c.run() + context.cleanup() + + except cdist.Error as e: + context.log.error(e) + if parallel: + # We are running in our own process here, need to sys.exit! + sys.exit(1) + else: + raise + + except KeyboardInterrupt: + # Ignore in parallel mode, we are existing anyway + if parallel: + sys.exit(0) + # Pass back to controlling code in sequential mode + else: + raise + def run(self): """Do what is most often done: deploy & cleanup""" start_time = time.time() diff --git a/cdist/shell.py b/cdist/shell.py new file mode 100644 index 00000000..f68a47ed --- /dev/null +++ b/cdist/shell.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# +# 2013 Nico Schottelius (nico-cdist at schottelius.org) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# + +import logging +import sys + +import cdist + +log = logging.getLogger(__name__) + +class Shell(object): + + def __init__(self): + pass + + @classmethod + def commandline(cls): + pass + # initialise cdist + # Startup Shell + + diff --git a/scripts/cdist b/scripts/cdist index 3c94b38b..79a89a7c 100755 --- a/scripts/cdist +++ b/scripts/cdist @@ -26,7 +26,8 @@ def commandline(): import cdist.banner import cdist.config - import cdist.install + # import cdist.install + import cdist.shell # Construct parser others can reuse parser = {} @@ -83,7 +84,13 @@ def commandline(): # Config parser['config'] = parser['sub'].add_parser('config', parents=[parser['loglevel'], parser['configinstall']]) - parser['config'].set_defaults(func=config) + parser['config'].set_defaults(func=cdist.config.Config.commandline) + + # Shell + parser['shell'] = parser['sub'].add_parser('shell', + parents=[parser['loglevel']]) + parser['shell'].set_defaults(func=cdist.shell.Shell.commandline) + # Install # 20120525/sar: commented until it actually does something @@ -112,98 +119,8 @@ def commandline(): except AttributeError: parser['main'].print_help() -def config(args): - configinstall(args, mode=cdist.config.Config) - -def install(args): - configinstall(args, mode=cdist.install.Install) - -def configinstall(args, mode): - """Configure or install remote system""" - import multiprocessing - import time - - initial_manifest_tempfile = None - if args.manifest == '-': - # read initial manifest from stdin - import tempfile - try: - handle, initial_manifest_temp_path = tempfile.mkstemp(prefix='cdist.stdin.') - with os.fdopen(handle, 'w') as fd: - fd.write(sys.stdin.read()) - except (IOError, OSError) as e: - raise cdist.Error("Creating tempfile for stdin data failed: %s" % e) - - args.manifest = initial_manifest_temp_path - import atexit - atexit.register(lambda: os.remove(initial_manifest_temp_path)) - - process = {} - failed_hosts = [] - time_start = time.time() - - for host in args.host: - if args.parallel: - log.debug("Creating child process for %s", host) - process[host] = multiprocessing.Process(target=configinstall_onehost, args=(host, args, mode, True)) - process[host].start() - else: - try: - configinstall_onehost(host, args, mode, parallel=False) - except cdist.Error as e: - failed_hosts.append(host) - - # Catch errors in parallel mode when joining - if args.parallel: - for host in process.keys(): - log.debug("Joining process %s", host) - process[host].join() - - if not process[host].exitcode == 0: - failed_hosts.append(host) - - time_end = time.time() - log.info("Total processing time for %s host(s): %s", len(args.host), - (time_end - time_start)) - - if len(failed_hosts) > 0: - raise cdist.Error("Failed to configure the following hosts: " + - " ".join(failed_hosts)) - -def configinstall_onehost(host, args, mode, parallel): - """Configure or install ONE remote system""" - - try: - import cdist.context - - context = cdist.context.Context( - target_host=host, - remote_copy=args.remote_copy, - remote_exec=args.remote_exec, - initial_manifest=args.manifest, - add_conf_dirs=args.conf_dir, - exec_path=sys.argv[0], - debug=args.debug) - - c = mode(context) - c.run() - context.cleanup() - - except cdist.Error as e: - context.log.error(e) - # We are running in our own process here, need to sys.exit! - if parallel: - sys.exit(1) - else: - raise - - except KeyboardInterrupt: - # Ignore in parallel mode, we are existing anyway - if parallel: - sys.exit(0) - # Pass back to controlling code in sequential mode - else: - raise +#def install(args): +# configinstall(args, mode=cdist.install.Install) def emulator(): """Prepare and run emulator"""