From 2011db16a8ef409cf8219118e11734adc3e91bf3 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 23 Jul 2016 15:10:32 +0200 Subject: [PATCH 1/7] Add scripts/cdist to pep8 check. --- bin/build-helper | 2 +- bin/build-helper.freebsd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/build-helper b/bin/build-helper index 16ad67ee..2a6e61da 100755 --- a/bin/build-helper +++ b/bin/build-helper @@ -360,7 +360,7 @@ eof ;; pep8) - pep8 ${basedir} | less + pep8 "${basedir}" "${basedir}/scripts/cdist" | less echo "Please review pep8 report." while true do diff --git a/bin/build-helper.freebsd b/bin/build-helper.freebsd index 829fbf09..4e4c4c9d 100755 --- a/bin/build-helper.freebsd +++ b/bin/build-helper.freebsd @@ -422,7 +422,7 @@ eof ;; pep8) - pep8 ${basedir} | less + pep8 "${basedir}" "${basedir}/scripts/cdist" | less echo "Please review pep8 report." while true do From dacb5720c51da94706fa6d5fbd89c37e9d2ed560 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 23 Jul 2016 15:11:14 +0200 Subject: [PATCH 2/7] Create hash func for string args to be used cdist wide. --- cdist/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cdist/__init__.py b/cdist/__init__.py index b7436b5a..f58bc15b 100644 --- a/cdist/__init__.py +++ b/cdist/__init__.py @@ -21,6 +21,7 @@ import os import subprocess +import hashlib import cdist.version @@ -82,3 +83,11 @@ def file_to_list(filename): lines = [] return lines + + +def str_hash(s): + """Return hash of string s""" + if isinstance(s, str): + return hashlib.md5(s.encode('utf-8')).hexdigest() + else: + raise Error("str_hash param should be string") From ca3644a08a11326f834b005d927c97d149dabb9b Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 23 Jul 2016 16:00:07 +0200 Subject: [PATCH 3/7] Add pep8 target. --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 71d128fa..417140c5 100644 --- a/Makefile +++ b/Makefile @@ -246,3 +246,6 @@ pub: test: $(helper) $@ + +pep8: + $(helper) $@ From 6f28fc2db2c856761a7b5fff2466afac7685c1a6 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 23 Jul 2016 16:13:59 +0200 Subject: [PATCH 4/7] Fix ssh mux socket file error. ssh ControlPath socket file needs to be unique for each host. To avoid using ssh ControlPath option placeholders move socket file to host's temp directory. Since each host has unique temp directory then, although file name for socket file is fixed, its path is unique. --- cdist/config.py | 93 +++++++++++++++-- cdist/exec/local.py | 40 ++------ cdist/test/code/__init__.py | 5 +- cdist/test/config/__init__.py | 15 ++- cdist/test/emulator/__init__.py | 30 ++++-- cdist/test/exec/local.py | 16 ++- cdist/test/explorer/__init__.py | 5 +- cdist/test/manifest/__init__.py | 5 +- scripts/cdist | 172 +++++++++++++------------------- 9 files changed, 221 insertions(+), 160 deletions(-) diff --git a/cdist/config.py b/cdist/config.py index 5ebeab14..da560e91 100644 --- a/cdist/config.py +++ b/cdist/config.py @@ -27,6 +27,7 @@ import sys import time import pprint import itertools +import tempfile import cdist @@ -36,6 +37,36 @@ import cdist.exec.remote from cdist import core +def inspect_ssh_mux_opts(): + """Inspect whether or not ssh supports multiplexing options. + + Return string containing multiplexing options if supported. + If ControlPath is supported then placeholder for that path is + specified and can be used for final string formatting. + For example, this function can return string: + "-o ControlMaster=auto -o ControlPersist=125 -o ControlPath={}". + Then it can be formatted: + mux_opts_string.format('/tmp/tmpxxxxxx/ssh-control-path'). + """ + import subprocess + + wanted_mux_opts = { + "ControlPath": "{}", + "ControlMaster": "auto", + "ControlPersist": "125", + } + mux_opts = " ".join([" -o {}={}".format( + x, wanted_mux_opts[x]) for x in wanted_mux_opts]) + try: + subprocess.check_output("ssh {}".format(mux_opts), + stderr=subprocess.STDOUT, shell=True) + except subprocess.CalledProcessError as e: + subproc_output = e.output.decode().lower() + if "bad configuration option" in subproc_output: + return "" + return mux_opts + + class Config(object): """Cdist main class to hold arbitrary data""" @@ -94,7 +125,6 @@ class Config(object): 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.') @@ -112,18 +142,47 @@ 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() + 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) + + log.debug("Base root path for target host \"{}\" is \"{}\"".format( + host, host_base_path)) + hostcnt += 1 if args.parallel: log.debug("Creating child process for %s", host) process[host] = multiprocessing.Process( - target=cls.onehost, args=(host, args, True)) + target=cls.onehost, + args=(host, host_base_path, hostdir, args, True)) process[host].start() else: try: - cls.onehost(host, args, parallel=False) + cls.onehost(host, host_base_path, hostdir, + args, parallel=False) except cdist.Error as e: failed_hosts.append(host) @@ -145,22 +204,42 @@ class Config(object): " ".join(failed_hosts)) @classmethod - def onehost(cls, host, args, parallel): + def onehost(cls, host, host_base_path, host_dir_name, args, parallel): """Configure ONE system""" log = logging.getLogger(host) try: + control_path = os.path.join(host_base_path, "ssh-control-path") + # If we constructed patterns for remote commands then there is + # placeholder for ssh ControlPath, format it and we have unique + # ControlPath for each host. + # + # If not then use args.remote_exec/copy that user specified. + if args.remote_exec_pattern: + remote_exec = args.remote_exec_pattern.format(control_path) + else: + remote_exec = args.remote_exec + if args.remote_copy_pattern: + remote_copy = args.remote_copy_pattern.format(control_path) + else: + remote_copy = args.remote_copy + log.debug("remote_exec for host \"{}\": {}".format( + host, remote_exec)) + log.debug("remote_copy for host \"{}\": {}".format( + host, remote_copy)) + local = cdist.exec.local.Local( target_host=host, + base_root_path=host_base_path, + host_dir_name=host_dir_name, initial_manifest=args.manifest, - base_path=args.out_path, add_conf_dirs=args.conf_dir) remote = cdist.exec.remote.Remote( target_host=host, - remote_exec=args.remote_exec, - remote_copy=args.remote_copy) + remote_exec=remote_exec, + remote_copy=remote_copy) c = cls(local, remote, dry_run=args.dry_run) c.run() diff --git a/cdist/exec/local.py b/cdist/exec/local.py index d115bf24..4fdb5170 100644 --- a/cdist/exec/local.py +++ b/cdist/exec/local.py @@ -29,7 +29,6 @@ import subprocess import shutil import logging import tempfile -import hashlib import cdist import cdist.message @@ -48,40 +47,25 @@ class Local(object): """ def __init__(self, target_host, + base_root_path, + host_dir_name, exec_path=sys.argv[0], initial_manifest=None, - base_path=None, add_conf_dirs=None): self.target_host = target_host - self._init_log() - - # FIXME: stopped: create base that does not require moving later - if base_path: - base_path_parent = base_path - else: - base_path_parent = tempfile.mkdtemp() - # TODO: the below atexit hook nukes any debug info we would have - # if cdist exits with error. - # import atexit - # atexit.register(lambda: shutil.rmtree(base_path_parent)) - self.hostdir = self._hostdir() - self.log.info("Calculated temp dir for target \"{}\" is " - "\"{}\"".format(self.target_host, self.hostdir)) - self.base_path = os.path.join(base_path_parent, self.hostdir) - - self._init_permissions() - - self.mkdir(self.base_path) - - # FIXME: as well - self._init_cache_dir(None) + self.hostdir = host_dir_name + self.base_path = os.path.join(base_root_path, "data") self.exec_path = exec_path self.custom_initial_manifest = initial_manifest - self._add_conf_dirs = add_conf_dirs + self._init_log() + self._init_permissions() + self.mkdir(self.base_path) + # FIXME: create dir that does not require moving later + self._init_cache_dir(None) self._init_paths() self._init_object_marker() self._init_conf_dirs() @@ -98,12 +82,6 @@ class Local(object): else: return None - def _hostdir(self): - # Do not assume target_host is anything that can be used as a - # directory name. - # Instead use a hash, which is known to work as directory name. - return hashlib.md5(self.target_host.encode('utf-8')).hexdigest() - def _init_log(self): self.log = logging.getLogger(self.target_host) diff --git a/cdist/test/code/__init__.py b/cdist/test/code/__init__.py index 7ec9e3c4..7f61c13f 100644 --- a/cdist/test/code/__init__.py +++ b/cdist/test/code/__init__.py @@ -41,10 +41,13 @@ class CodeTestCase(test.CdistTestCase): def setUp(self): self.local_dir = self.mkdtemp() + self.hostdir = cdist.str_hash(self.target_host) + self.host_base_path = os.path.join(self.local_dir, self.hostdir) self.local = local.Local( target_host=self.target_host, - base_path=self.local_dir, + base_root_path=self.host_base_path, + host_dir_name=self.hostdir, exec_path=cdist.test.cdist_exec_path, add_conf_dirs=[conf_dir]) self.local.create_files_dirs() diff --git a/cdist/test/config/__init__.py b/cdist/test/config/__init__.py index 3fd415fd..cfcc3c70 100644 --- a/cdist/test/config/__init__.py +++ b/cdist/test/config/__init__.py @@ -55,10 +55,13 @@ class ConfigRunTestCase(test.CdistTestCase): self.temp_dir = self.mkdtemp() self.local_dir = os.path.join(self.temp_dir, "local") - os.mkdir(self.local_dir) + self.hostdir = cdist.str_hash(self.target_host) + self.host_base_path = os.path.join(self.local_dir, self.hostdir) + os.makedirs(self.host_base_path) self.local = cdist.exec.local.Local( target_host=self.target_host, - base_path=self.local_dir) + base_root_path=self.host_base_path, + host_dir_name=self.hostdir) # Setup test objects self.object_base_path = op.join(self.temp_dir, 'object') @@ -161,7 +164,8 @@ class ConfigRunTestCase(test.CdistTestCase): """Test if the dryrun option is working like expected""" drylocal = cdist.exec.local.Local( target_host=self.target_host, - base_path=self.local_dir, + base_root_path=self.host_base_path, + host_dir_name=self.hostdir, # exec_path can not derivated from sys.argv in case of unittest exec_path=os.path.abspath(os.path.join( my_dir, '../../../scripts/cdist')), @@ -184,3 +188,8 @@ class ConfigRunTestCase(test.CdistTestCase): # first.requirements = ['__singleton_test/foo'] # with self.assertRaises(cdist.core.?????): # self.config.iterate_until_finished() + +if __name__ == "__main__": + import unittest + + unittest.main() diff --git a/cdist/test/emulator/__init__.py b/cdist/test/emulator/__init__.py index 69ca0fd9..3fe9a4e5 100644 --- a/cdist/test/emulator/__init__.py +++ b/cdist/test/emulator/__init__.py @@ -48,10 +48,13 @@ class EmulatorTestCase(test.CdistTestCase): handle, self.script = self.mkstemp(dir=self.temp_dir) os.close(handle) base_path = self.temp_dir + hostdir = cdist.str_hash(self.target_host) + host_base_path = os.path.join(base_path, hostdir) self.local = local.Local( target_host=self.target_host, - base_path=base_path, + base_root_path=host_base_path, + host_dir_name=hostdir, exec_path=test.cdist_exec_path, add_conf_dirs=[conf_dir]) self.local.create_files_dirs() @@ -148,10 +151,13 @@ class EmulatorConflictingRequirementsTestCase(test.CdistTestCase): handle, self.script = self.mkstemp(dir=self.temp_dir) os.close(handle) base_path = self.temp_dir + hostdir = cdist.str_hash(self.target_host) + host_base_path = os.path.join(base_path, hostdir) self.local = local.Local( target_host=self.target_host, - base_path=base_path, + base_root_path=host_base_path, + host_dir_name=hostdir, exec_path=test.cdist_exec_path, add_conf_dirs=[conf_dir]) self.local.create_files_dirs() @@ -235,10 +241,13 @@ class AutoRequireEmulatorTestCase(test.CdistTestCase): def setUp(self): self.temp_dir = self.mkdtemp() base_path = os.path.join(self.temp_dir, "out") + hostdir = cdist.str_hash(self.target_host) + host_base_path = os.path.join(base_path, hostdir) self.local = local.Local( target_host=self.target_host, - base_path=base_path, + base_root_path=host_base_path, + host_dir_name=hostdir, exec_path=test.cdist_exec_path, add_conf_dirs=[conf_dir]) self.local.create_files_dirs() @@ -265,10 +274,13 @@ class OverrideTestCase(test.CdistTestCase): handle, self.script = self.mkstemp(dir=self.temp_dir) os.close(handle) base_path = self.temp_dir + hostdir = cdist.str_hash(self.target_host) + host_base_path = os.path.join(base_path, hostdir) self.local = local.Local( target_host=self.target_host, - base_path=base_path, + base_root_path=host_base_path, + host_dir_name=hostdir, exec_path=test.cdist_exec_path, add_conf_dirs=[conf_dir]) self.local.create_files_dirs() @@ -303,12 +315,15 @@ class ArgumentsTestCase(test.CdistTestCase): def setUp(self): self.temp_dir = self.mkdtemp() base_path = self.temp_dir + hostdir = cdist.str_hash(self.target_host) + host_base_path = os.path.join(base_path, hostdir) handle, self.script = self.mkstemp(dir=self.temp_dir) os.close(handle) self.local = local.Local( target_host=self.target_host, - base_path=base_path, + base_root_path=host_base_path, + host_dir_name=hostdir, exec_path=test.cdist_exec_path, add_conf_dirs=[conf_dir]) self.local.create_files_dirs() @@ -425,10 +440,13 @@ class StdinTestCase(test.CdistTestCase): self.temp_dir = self.mkdtemp() base_path = os.path.join(self.temp_dir, "out") + hostdir = cdist.str_hash(self.target_host) + host_base_path = os.path.join(base_path, hostdir) self.local = local.Local( target_host=self.target_host, - base_path=base_path, + base_root_path=host_base_path, + host_dir_name=hostdir, exec_path=test.cdist_exec_path, add_conf_dirs=[conf_dir]) diff --git a/cdist/test/exec/local.py b/cdist/test/exec/local.py index 2cd8b6db..f83fd6b7 100644 --- a/cdist/test/exec/local.py +++ b/cdist/test/exec/local.py @@ -47,11 +47,14 @@ class LocalTestCase(test.CdistTestCase): target_host = 'localhost' self.temp_dir = self.mkdtemp() self.out_parent_path = self.temp_dir - self.out_path = op.join(self.out_parent_path, target_host) + self.hostdir = cdist.str_hash(target_host) + self.host_base_path = op.join(self.out_parent_path, self.hostdir) + self.out_path = op.join(self.host_base_path, "data") self.local = local.Local( target_host=target_host, - base_path=self.out_parent_path, + base_root_path=self.host_base_path, + host_dir_name=self.hostdir, exec_path=test.cdist_exec_path ) @@ -109,7 +112,8 @@ class LocalTestCase(test.CdistTestCase): link_test_local = local.Local( target_host='localhost', - base_path=self.out_parent_path, + base_root_path=self.host_base_path, + host_dir_name=self.hostdir, exec_path=test.cdist_exec_path, ) @@ -127,7 +131,8 @@ class LocalTestCase(test.CdistTestCase): link_test_local = local.Local( target_host='localhost', - base_path=self.out_parent_path, + base_root_path=self.host_base_path, + host_dir_name=self.hostdir, exec_path=test.cdist_exec_path, add_conf_dirs=[conf_dir] ) @@ -148,7 +153,8 @@ class LocalTestCase(test.CdistTestCase): link_test_local = local.Local( target_host='localhost', - base_path=self.out_parent_path, + base_root_path=self.host_base_path, + host_dir_name=self.hostdir, exec_path=test.cdist_exec_path, ) diff --git a/cdist/test/explorer/__init__.py b/cdist/test/explorer/__init__.py index 2ca50b7c..9a4555b8 100644 --- a/cdist/test/explorer/__init__.py +++ b/cdist/test/explorer/__init__.py @@ -42,12 +42,15 @@ class ExplorerClassTestCase(test.CdistTestCase): def setUp(self): self.temp_dir = self.mkdtemp() self.local_path = os.path.join(self.temp_dir, "local") + hostdir = cdist.str_hash(self.target_host) + base_root_path = os.path.join(self.local_path, hostdir) self.remote_base_path = os.path.join(self.temp_dir, "remote") os.makedirs(self.remote_base_path) self.local = local.Local( target_host=self.target_host, - base_path=self.local_path, + base_root_path=base_root_path, + host_dir_name=hostdir, exec_path=test.cdist_exec_path, add_conf_dirs=[conf_dir], ) diff --git a/cdist/test/manifest/__init__.py b/cdist/test/manifest/__init__.py index 84c69ce1..cfaefe5c 100644 --- a/cdist/test/manifest/__init__.py +++ b/cdist/test/manifest/__init__.py @@ -49,9 +49,12 @@ class ManifestTestCase(test.CdistTestCase): self.temp_dir = self.mkdtemp() out_path = self.temp_dir + hostdir = cdist.str_hash(self.target_host) + base_root_path = os.path.join(out_path, hostdir) self.local = local.Local( target_host=self.target_host, - base_path=out_path, + base_root_path=base_root_path, + host_dir_name=hostdir, exec_path=cdist.test.cdist_exec_path, add_conf_dirs=[conf_dir]) self.local.create_files_dirs() diff --git a/scripts/cdist b/scripts/cdist index 55113be0..953cad78 100755 --- a/scripts/cdist +++ b/scripts/cdist @@ -21,31 +21,6 @@ # # -def inspect_ssh_mux_opts(control_path_dir="~/.ssh/"): - """Inspect whether or not ssh supports multiplexing options""" - import subprocess - import os - - # socket is always local to each cdist run, it is created in - # temp directory that is created at starting cdist, so - # control_path file name can be static, it will always be - # unique due to unique temp directory name - control_path = os.path.join(control_path_dir, "ssh-control-path") - wanted_mux_opts = { - "ControlPath": control_path, - "ControlMaster": "auto", - "ControlPersist": "125", - } - mux_opts = " ".join([" -o {}={}".format(x, - wanted_mux_opts[x]) for x in wanted_mux_opts]) - try: - subprocess.check_output("ssh {}".format(mux_opts), - stderr=subprocess.STDOUT, shell=True) - except subprocess.CalledProcessError as e: - subproc_output = e.output.decode().lower() - if "bad configuration option" in subproc_output: - return "" - return mux_opts def commandline(): """Parse command line""" @@ -54,7 +29,6 @@ def commandline(): import cdist.banner import cdist.config import cdist.shell - import tempfile import shutil import os @@ -62,79 +36,88 @@ def commandline(): parser = {} # Options _all_ parsers have in common parser['loglevel'] = argparse.ArgumentParser(add_help=False) - parser['loglevel'].add_argument('-d', '--debug', - help='Set log level to debug', action='store_true', - default=False) - parser['loglevel'].add_argument('-v', '--verbose', - help='Set log level to info, be more verbose', - action='store_true', default=False) + parser['loglevel'].add_argument( + '-d', '--debug', help='Set log level to debug', + action='store_true', default=False) + parser['loglevel'].add_argument( + '-v', '--verbose', help='Set log level to info, be more verbose', + action='store_true', default=False) # Main subcommand parser - parser['main'] = argparse.ArgumentParser(description='cdist ' - + cdist.VERSION, - parents=[parser['loglevel']]) - parser['main'].add_argument('-V', '--version', - help='Show version', action='version', - version='%(prog)s ' + cdist.VERSION) - parser['sub'] = parser['main'].add_subparsers(title="Commands", - dest="command") + parser['main'] = argparse.ArgumentParser( + description='cdist ' + cdist.VERSION, parents=[parser['loglevel']]) + parser['main'].add_argument( + '-V', '--version', help='Show version', action='version', + version='%(prog)s ' + cdist.VERSION) + parser['sub'] = parser['main'].add_subparsers( + title="Commands", dest="command") # Banner - parser['banner'] = parser['sub'].add_parser('banner', - parents=[parser['loglevel']]) + parser['banner'] = parser['sub'].add_parser( + '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('-c', '--conf-dir', - help=('Add configuration directory (can be repeated, ' - 'last one wins)'), action='append') - parser['config'].add_argument('-f', '--file', - help=('Read additional hosts to operate on from specified file ' - 'or from stdin if \'-\' (each host on separate line). ' - '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('-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') + 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( + '-c', '--conf-dir', + help=('Add configuration directory (can be repeated, ' + 'last one wins)'), action='append') + parser['config'].add_argument( + '-f', '--file', + help=('Read additional hosts to operate on from specified file ' + 'or from stdin if \'-\' (each host on separate line). ' + '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( + '-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'].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 - parser['shell'] = parser['sub'].add_parser('shell', - parents=[parser['loglevel']]) - parser['shell'].add_argument('-s', '--shell', - help='Select shell to use, defaults to current shell') + parser['shell'] = parser['sub'].add_parser( + 'shell', parents=[parser['loglevel']]) + parser['shell'].add_argument( + '-s', '--shell', + help='Select shell to use, defaults to current shell') parser['shell'].set_defaults(func=cdist.shell.Shell.commandline) - for p in parser: - parser[p].epilog = "Get cdist at http://www.nico.schottelius.org/software/cdist/" + parser[p].epilog = ( + "Get cdist at http://www.nico.schottelius.org/software/cdist/") args = parser['main'].parse_args(sys.argv[1:]) @@ -143,26 +126,6 @@ def commandline(): logging.root.setLevel(logging.INFO) if args.debug: logging.root.setLevel(logging.DEBUG) - args_dict = vars(args) - # if command with remote_copy and remote_exec params - if 'remote_copy' in args_dict and 'remote_exec' in args_dict: - # 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: - control_path_dir = tempfile.mkdtemp(prefix="cdist") - import atexit - atexit.register(lambda: shutil.rmtree(control_path_dir)) - mux_opts = inspect_ssh_mux_opts(control_path_dir) - if args_dict['remote_exec'] is None: - args.remote_exec = cdist.REMOTE_EXEC + mux_opts - if args_dict['remote_copy'] is None: - args.remote_copy = cdist.REMOTE_COPY + mux_opts - - if args.command == 'config': - if args.manifest == '-' and args.hostfile == '-': - print('cdist config: error: cannot read both, manifest and host file, from stdin') - sys.exit(1) log.debug(args) log.info("version %s" % cdist.VERSION) @@ -191,10 +154,9 @@ if __name__ == "__main__": cdistpythonversion = '3.2' if sys.version < cdistpythonversion: print('Python >= ' + cdistpythonversion + - ' is required on the source host.', file=sys.stderr) + ' is required on the source host.', file=sys.stderr) sys.exit(1) - exit_code = 0 try: From 135b4fbadf8f5b977fe1b50bca2130181e75a305 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 23 Jul 2016 16:17:43 +0200 Subject: [PATCH 5/7] Update changelog. --- docs/changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog b/docs/changelog index d85af785..1c894ba7 100644 --- a/docs/changelog +++ b/docs/changelog @@ -1,6 +1,9 @@ Changelog --------- +next: + * Core: Fix ssh ControlPath socket file error (Darko Poljak) + 4.2.1: 2016-07-18 * Build: Fix signed release (Darko Poljak) * Build: Fix building docs (Darko Poljak) From 1959e9cdd82db479ec411743c279a97628812d38 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 23 Jul 2016 16:29:51 +0200 Subject: [PATCH 6/7] Fix error message. --- cdist/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/__init__.py b/cdist/__init__.py index f58bc15b..74db1a13 100644 --- a/cdist/__init__.py +++ b/cdist/__init__.py @@ -90,4 +90,4 @@ def str_hash(s): if isinstance(s, str): return hashlib.md5(s.encode('utf-8')).hexdigest() else: - raise Error("str_hash param should be string") + raise Error("Param should be string") From f5dd4e0a766db40a4c02c398ccf877f90e80fe55 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sun, 24 Jul 2016 22:24:15 +0200 Subject: [PATCH 7/7] Improve pep8 targets and checking in release. --- bin/build-helper | 6 +++++- bin/build-helper.freebsd | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/bin/build-helper b/bin/build-helper index 2a6e61da..46b139d1 100755 --- a/bin/build-helper +++ b/bin/build-helper @@ -249,7 +249,7 @@ eof # First check everything is sane "$0" check-date "$0" check-unittest - "$0" pep8 + "$0" check-pep8 # Generate version file to be included in packaging "$0" target-version @@ -361,6 +361,10 @@ eof pep8) pep8 "${basedir}" "${basedir}/scripts/cdist" | less + ;; + + check-pep8) + "$0" pep8 echo "Please review pep8 report." while true do diff --git a/bin/build-helper.freebsd b/bin/build-helper.freebsd index 4e4c4c9d..183129db 100755 --- a/bin/build-helper.freebsd +++ b/bin/build-helper.freebsd @@ -284,7 +284,7 @@ eof # First check everything is sane "$0" check-date "$0" check-unittest - "$0" pep8 + "$0" check-pep8 # Generate version file to be included in packaging "$0" target-version @@ -423,6 +423,10 @@ eof pep8) pep8 "${basedir}" "${basedir}/scripts/cdist" | less + ;; + + check-pep8) + "$0" pep8 echo "Please review pep8 report." while true do