mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-05-06 21:32:49 +00:00
Add shell_plugins to abstract shell-specific functions out of runner, add winrm connection plugin, add initial Windows modules.
This commit is contained in:
0
lib/ansible/runner/shell_plugins/__init__.py
Normal file
0
lib/ansible/runner/shell_plugins/__init__.py
Normal file
6
lib/ansible/runner/shell_plugins/csh.py
Normal file
6
lib/ansible/runner/shell_plugins/csh.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from ansible.runner.shell_plugins.sh import ShellModule as ShModule
|
||||
|
||||
class ShellModule(ShModule):
|
||||
|
||||
def env_prefix(self, **kwargs):
|
||||
return 'env %s' % super(ShellModule, self).env_prefix(**kwargs)
|
||||
6
lib/ansible/runner/shell_plugins/fish.py
Normal file
6
lib/ansible/runner/shell_plugins/fish.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from ansible.runner.shell_plugins.sh import ShellModule as ShModule
|
||||
|
||||
class ShellModule(ShModule):
|
||||
|
||||
def env_prefix(self, **kwargs):
|
||||
return 'env %s' % super(ShellModule, self).env_prefix(**kwargs)
|
||||
72
lib/ansible/runner/shell_plugins/powershell.py
Normal file
72
lib/ansible/runner/shell_plugins/powershell.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import base64
|
||||
import os
|
||||
import re
|
||||
import random
|
||||
import shlex
|
||||
import time
|
||||
|
||||
class ShellModule(object):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def _escape(self, value, include_vars=False):
|
||||
'''
|
||||
Return value escaped for use in PowerShell command.
|
||||
'''
|
||||
# http://www.techotopia.com/index.php/Windows_PowerShell_1.0_String_Quoting_and_Escape_Sequences
|
||||
# http://stackoverflow.com/questions/764360/a-list-of-string-replacements-in-python
|
||||
subs = [('\n', '`n'), ('\r', '`r'), ('\t', '`t'), ('\a', '`a'),
|
||||
('\b', '`b'), ('\f', '`f'), ('\v', '`v'), ('"', '`"'),
|
||||
('\'', '`\''), ('`', '``'), ('\x00', '`0')]
|
||||
if include_vars:
|
||||
subs.append(('$', '`$'))
|
||||
pattern = '|'.join('(%s)' % re.escape(p) for p, s in subs)
|
||||
substs = [s for p, s in subs]
|
||||
replace = lambda m: substs[m.lastindex - 1]
|
||||
return re.sub(pattern, replace, value)
|
||||
|
||||
def _get_script_cmd(self, script):
|
||||
'''
|
||||
Convert a PowerShell script to a single base64-encoded command.
|
||||
'''
|
||||
encoded_script = base64.b64encode(script.encode('utf-16-le'))
|
||||
return ' '.join(['PowerShell', '-NoProfile', '-NonInteractive',
|
||||
'-EncodedCommand', encoded_script])
|
||||
|
||||
def env_prefix(self, **kwargs):
|
||||
return ''
|
||||
|
||||
def join_path(self, *args):
|
||||
return os.path.join(*args).replace('/', '\\')
|
||||
|
||||
def chmod(self, mode, path):
|
||||
return ''
|
||||
|
||||
def remove(self, path, recurse=False):
|
||||
path = self._escape(path)
|
||||
if recurse:
|
||||
return self._get_script_cmd('''Remove-Item "%s" -Force -Recurse;''' % path)
|
||||
else:
|
||||
return self._get_script_cmd('''Remove-Item "%s" -Force;''' % path)
|
||||
|
||||
def mkdtemp(self, basefile=None, system=False, mode=None):
|
||||
if not basefile:
|
||||
basefile = 'ansible-tmp-%s-%s' % (time.time(), random.randint(0, 2**48))
|
||||
basefile = self._escape(basefile)
|
||||
# FIXME: Support system temp path!
|
||||
return self._get_script_cmd('''(New-Item -Type Directory -Path $env:temp -Name "%s").FullName;''' % basefile)
|
||||
|
||||
def md5(self, path):
|
||||
path = self._escape(path)
|
||||
return self._get_script_cmd('''(Get-FileHash -Path "%s" -Algorithm MD5).Hash.ToLower();''' % path)
|
||||
|
||||
def build_module_command(self, env_string, shebang, cmd, rm_tmp=None):
|
||||
cmd_parts = shlex.split(cmd, posix=False)
|
||||
if not cmd_parts[0].lower().endswith('.ps1'):
|
||||
cmd_parts[0] = '%s.ps1' % cmd_parts[0]
|
||||
cmd_parts = ['PowerShell', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Unrestricted', '-File'] + ['"%s"' % x for x in cmd_parts]
|
||||
script = ' '.join(cmd_parts)
|
||||
if rm_tmp:
|
||||
script = '%s; Remove-Item "%s" -Force -Recurse;' % (script, self._escape(rm_tmp))
|
||||
return self._get_script_cmd(script)
|
||||
71
lib/ansible/runner/shell_plugins/sh.py
Normal file
71
lib/ansible/runner/shell_plugins/sh.py
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
import os
|
||||
import pipes
|
||||
import ansible.constants as C
|
||||
|
||||
class ShellModule(object):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def env_prefix(self, **kwargs):
|
||||
'''Build command prefix with environment variables.'''
|
||||
env = dict(
|
||||
LANG = C.DEFAULT_MODULE_LANG,
|
||||
LC_CTYPE = C.DEFAULT_MODULE_LANG,
|
||||
)
|
||||
env.update(kwargs)
|
||||
return ' '.join(['%s=%s' % (k, pipes.quote(unicode(v))) for k,v in env.items()])
|
||||
|
||||
def join_path(self, *args):
|
||||
return os.path.join(*args)
|
||||
|
||||
def chmod(self, mode, path):
|
||||
path = pipes.quote(path)
|
||||
return 'chmod %s %s' % (mode, path)
|
||||
|
||||
def remove(self, path, recurse=False):
|
||||
path = pipes.quote(path)
|
||||
if recurse:
|
||||
return "rm -rf %s >/dev/null 2>&1" % path
|
||||
else:
|
||||
return "rm -f %s >/dev/null 2>&1" % path
|
||||
|
||||
def mkdtemp(self, basefile=None, system=False, mode=None):
|
||||
if not basefile:
|
||||
basefile = 'ansible-tmp-%s-%s' % (time.time(), random.randint(0, 2**48))
|
||||
basetmp = self.join_path(C.DEFAULT_REMOTE_TMP, basefile)
|
||||
if system and basetmp.startswith('$HOME'):
|
||||
basetmp = self.join_path('/tmp', basefile)
|
||||
cmd = 'mkdir -p %s' % basetmp
|
||||
if mode:
|
||||
cmd += ' && chmod %s %s' % (mode, basetmp)
|
||||
cmd += ' && echo %s' % basetmp
|
||||
return cmd
|
||||
|
||||
def md5(self, path):
|
||||
path = pipes.quote(path)
|
||||
# The following test needs to be SH-compliant. BASH-isms will
|
||||
# not work if /bin/sh points to a non-BASH shell.
|
||||
test = "rc=0; [ -r \"%s\" ] || rc=2; [ -f \"%s\" ] || rc=1; [ -d \"%s\" ] && echo 3 && exit 0" % ((path,) * 3)
|
||||
md5s = [
|
||||
"(/usr/bin/md5sum %s 2>/dev/null)" % path, # Linux
|
||||
"(/sbin/md5sum -q %s 2>/dev/null)" % path, # ?
|
||||
"(/usr/bin/digest -a md5 %s 2>/dev/null)" % path, # Solaris 10+
|
||||
"(/sbin/md5 -q %s 2>/dev/null)" % path, # Freebsd
|
||||
"(/usr/bin/md5 -n %s 2>/dev/null)" % path, # Netbsd
|
||||
"(/bin/md5 -q %s 2>/dev/null)" % path, # Openbsd
|
||||
"(/usr/bin/csum -h MD5 %s 2>/dev/null)" % path, # AIX
|
||||
"(/bin/csum -h MD5 %s 2>/dev/null)" % path # AIX also
|
||||
]
|
||||
|
||||
cmd = " || ".join(md5s)
|
||||
cmd = "%s; %s || (echo \"${rc} %s\")" % (test, cmd, path)
|
||||
return cmd
|
||||
|
||||
def build_module_command(self, env_string, shebang, cmd, rm_tmp=None):
|
||||
cmd_parts = [env_string.strip(), shebang.replace("#!", "").strip(), cmd]
|
||||
new_cmd = " ".join(cmd_parts)
|
||||
if rm_tmp:
|
||||
new_cmd = '%s; rm -rf %s >/dev/null 2>&1' % (new_cmd, rm_tmp)
|
||||
return new_cmd
|
||||
Reference in New Issue
Block a user