refactor commandline: merge into its own class (and add first shell code)

Signed-off-by: Nico Schottelius <nico@bento.schottelius.org>
This commit is contained in:
Nico Schottelius 2013-08-07 09:24:10 +02:00
parent 4d47467944
commit 2403fc59ee
4 changed files with 147 additions and 95 deletions

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- 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. # This file is part of cdist.
# #

View file

@ -23,6 +23,7 @@
import logging import logging
import os import os
import shutil import shutil
import sys
import time import time
import pprint import pprint
@ -47,6 +48,100 @@ class ConfigInstall(object):
self.context.local.create_files_dirs() self.context.local.create_files_dirs()
self.context.remote.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): def run(self):
"""Do what is most often done: deploy & cleanup""" """Do what is most often done: deploy & cleanup"""
start_time = time.time() start_time = time.time()

40
cdist/shell.py Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
#
#
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

View file

@ -26,7 +26,8 @@ def commandline():
import cdist.banner import cdist.banner
import cdist.config import cdist.config
import cdist.install # import cdist.install
import cdist.shell
# Construct parser others can reuse # Construct parser others can reuse
parser = {} parser = {}
@ -83,7 +84,13 @@ def commandline():
# Config # Config
parser['config'] = parser['sub'].add_parser('config', parser['config'] = parser['sub'].add_parser('config',
parents=[parser['loglevel'], parser['configinstall']]) 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 # Install
# 20120525/sar: commented until it actually does something # 20120525/sar: commented until it actually does something
@ -112,98 +119,8 @@ def commandline():
except AttributeError: except AttributeError:
parser['main'].print_help() parser['main'].print_help()
def config(args): #def install(args):
configinstall(args, mode=cdist.config.Config) # configinstall(args, mode=cdist.install.Install)
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 emulator(): def emulator():
"""Prepare and run emulator""" """Prepare and run emulator"""