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:
|
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)
|
* Types: Remove bashisms in scripts (Darko Poljak)
|
||||||
* Core: Fix bug in remote command with environment (Darko Poljak)
|
* Core: Fix bug in remote command with environment (Darko Poljak)
|
||||||
* Core: Fix bug in local code execution (Darko Poljak)
|
* Core: Fix bug in local code execution (Darko Poljak)
|
||||||
|
|
|
@ -249,6 +249,12 @@ CDIST_OVERRIDE::
|
||||||
CDIST_ORDER_DEPENDENCY::
|
CDIST_ORDER_DEPENDENCY::
|
||||||
Create dependencies based on the execution order (see cdist-manifest(7))
|
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
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
- cdist(1)
|
- cdist(1)
|
||||||
|
|
|
@ -138,6 +138,11 @@ CDIST_LOCAL_SHELL::
|
||||||
CDIST_REMOTE_SHELL::
|
CDIST_REMOTE_SHELL::
|
||||||
Selects shell for remote scirpt execution, defaults to /bin/sh
|
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
|
EXIT STATUS
|
||||||
-----------
|
-----------
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# 2010-2013 Nico Schottelius (nico-cdist at schottelius.org)
|
# 2010-2013 Nico Schottelius (nico-cdist at schottelius.org)
|
||||||
|
# 2016 Darko Poljak (darko.poljak at gmail.com)
|
||||||
#
|
#
|
||||||
# This file is part of cdist.
|
# 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():
|
def commandline():
|
||||||
"""Parse command line"""
|
"""Parse command line"""
|
||||||
import argparse
|
import argparse
|
||||||
|
@ -27,6 +50,9 @@ def commandline():
|
||||||
import cdist.banner
|
import cdist.banner
|
||||||
import cdist.config
|
import cdist.config
|
||||||
import cdist.shell
|
import cdist.shell
|
||||||
|
import tempfile
|
||||||
|
import shutil
|
||||||
|
import os
|
||||||
|
|
||||||
# Construct parser others can reuse
|
# Construct parser others can reuse
|
||||||
parser = {}
|
parser = {}
|
||||||
|
@ -73,14 +99,17 @@ def commandline():
|
||||||
parser['config'].add_argument('-s', '--sequential',
|
parser['config'].add_argument('-s', '--sequential',
|
||||||
help='Operate on multiple hosts sequentially (default)',
|
help='Operate on multiple hosts sequentially (default)',
|
||||||
action='store_false', dest='parallel')
|
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',
|
parser['config'].add_argument('--remote-copy',
|
||||||
help='Command to use for remote copy (should behave like scp)',
|
help='Command to use for remote copy (should behave like scp)',
|
||||||
action='store', dest='remote_copy',
|
action='store', dest='remote_copy',
|
||||||
default=cdist.REMOTE_COPY)
|
default=os.environ.get('CDIST_REMOTE_COPY'))
|
||||||
parser['config'].add_argument('--remote-exec',
|
parser['config'].add_argument('--remote-exec',
|
||||||
help='Command to use for remote execution (should behave like ssh)',
|
help='Command to use for remote execution (should behave like ssh)',
|
||||||
action='store', dest='remote_exec',
|
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)
|
parser['config'].set_defaults(func=cdist.config.Config.commandline)
|
||||||
|
|
||||||
# Shell
|
# Shell
|
||||||
|
@ -101,6 +130,32 @@ def commandline():
|
||||||
logging.root.setLevel(logging.INFO)
|
logging.root.setLevel(logging.INFO)
|
||||||
if args.debug:
|
if args.debug:
|
||||||
logging.root.setLevel(logging.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.debug(args)
|
||||||
log.info("version %s" % cdist.VERSION)
|
log.info("version %s" % cdist.VERSION)
|
||||||
|
|
Loading…
Reference in a new issue