forked from ungleich-public/cdist
Merge pull request #418 from darko-poljak/ssh-mux-opts
ssh multiplexing options
This commit is contained in:
commit
c790a2e906
4 changed files with 69 additions and 2 deletions
|
@ -2,6 +2,7 @@ Changelog
|
|||
---------
|
||||
|
||||
next:
|
||||
* Core: Add CDIST_REMOTE_COPY/EXEC env variables and multiplexing options for default scp/ssh (Darko Poljak)
|
||||
* Types: Remove bashisms in scripts (Darko Poljak)
|
||||
* Core: Fix bug in remote command with environment (Darko Poljak)
|
||||
* Core: Fix bug in local code execution (Darko Poljak)
|
||||
|
|
|
@ -249,6 +249,12 @@ CDIST_OVERRIDE::
|
|||
CDIST_ORDER_DEPENDENCY::
|
||||
Create dependencies based on the execution order (see cdist-manifest(7))
|
||||
|
||||
CDIST_REMOTE_EXEC::
|
||||
Use this command for remote execution (should behave like ssh)
|
||||
|
||||
CDIST_REMOTE_COPY::
|
||||
Use this command for remote copy (should behave like scp)
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
- cdist(1)
|
||||
|
|
|
@ -138,6 +138,11 @@ CDIST_LOCAL_SHELL::
|
|||
CDIST_REMOTE_SHELL::
|
||||
Selects shell for remote scirpt execution, defaults to /bin/sh
|
||||
|
||||
CDIST_REMOTE_EXEC::
|
||||
Use this command for remote execution (should behave like ssh)
|
||||
|
||||
CDIST_REMOTE_COPY::
|
||||
Use this command for remote copy (should behave like scp)
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 2010-2013 Nico Schottelius (nico-cdist at schottelius.org)
|
||||
# 2016 Darko Poljak (darko.poljak at gmail.com)
|
||||
#
|
||||
# This file is part of cdist.
|
||||
#
|
||||
|
@ -20,6 +21,28 @@
|
|||
#
|
||||
#
|
||||
|
||||
def inspect_ssh_mux_opts(control_path_dir="~/.ssh/"):
|
||||
"""Inspect whether or not ssh supports multiplexing options"""
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
control_path = os.path.join(control_path_dir, "cdist.master-%l-%r@%h:%p")
|
||||
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"""
|
||||
import argparse
|
||||
|
@ -27,6 +50,9 @@ def commandline():
|
|||
import cdist.banner
|
||||
import cdist.config
|
||||
import cdist.shell
|
||||
import tempfile
|
||||
import shutil
|
||||
import os
|
||||
|
||||
# Construct parser others can reuse
|
||||
parser = {}
|
||||
|
@ -73,14 +99,17 @@ def commandline():
|
|||
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=cdist.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=cdist.REMOTE_EXEC)
|
||||
default=os.environ.get('CDIST_REMOTE_EXEC'))
|
||||
parser['config'].set_defaults(func=cdist.config.Config.commandline)
|
||||
|
||||
# Shell
|
||||
|
@ -101,6 +130,32 @@ 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 out_path is not set then create temp dir here so
|
||||
# Local uses it for base_path and ssh mux socket is
|
||||
# created in it.
|
||||
if args_dict['out_path'] is None:
|
||||
args.out_path = tempfile.mkdtemp()
|
||||
is_temp_dir = True
|
||||
else:
|
||||
is_temp_dir = False
|
||||
# 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 = args.out_path
|
||||
# only rmtree if it is temp directory;
|
||||
# if user specifies out_path do not remove it
|
||||
if is_temp_dir:
|
||||
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
|
||||
|
||||
log.debug(args)
|
||||
log.info("version %s" % cdist.VERSION)
|
||||
|
|
Loading…
Reference in a new issue