PageRenderTime 101ms CodeModel.GetById 79ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/ansible/runner/shell_plugins/sh.py

https://github.com/ajanthanm/ansible
Python | 87 lines | 57 code | 11 blank | 19 comment | 8 complexity | d09b153389ead23febf04f65eedab2a5 MD5 | raw file
 1# (c) 2014, Chris Church <chris@ninemoreminutes.com>
 2#
 3# This file is part of Ansible.
 4#
 5# Ansible is free software: you can redistribute it and/or modify
 6# it under the terms of the GNU General Public License as published by
 7# the Free Software Foundation, either version 3 of the License, or
 8# (at your option) any later version.
 9#
10# Ansible is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
17
18import os
19import pipes
20import ansible.constants as C
21
22class ShellModule(object):
23
24    def env_prefix(self, **kwargs):
25        '''Build command prefix with environment variables.'''
26        env = dict(
27            LANG     = C.DEFAULT_MODULE_LANG,
28            LC_CTYPE = C.DEFAULT_MODULE_LANG,
29        )
30        env.update(kwargs)
31        return ' '.join(['%s=%s' % (k, pipes.quote(unicode(v))) for k,v in env.items()])
32
33    def join_path(self, *args):
34        return os.path.join(*args)
35
36    def path_has_trailing_slash(self, path):
37        return path.endswith('/')
38
39    def chmod(self, mode, path):
40        path = pipes.quote(path)
41        return 'chmod %s %s' % (mode, path)
42
43    def remove(self, path, recurse=False):
44        path = pipes.quote(path)
45        if recurse:
46            return "rm -rf %s >/dev/null 2>&1" % path
47        else:
48            return "rm -f %s >/dev/null 2>&1" % path
49
50    def mkdtemp(self, basefile=None, system=False, mode=None):
51        if not basefile:
52            basefile = 'ansible-tmp-%s-%s' % (time.time(), random.randint(0, 2**48))
53        basetmp = self.join_path(C.DEFAULT_REMOTE_TMP, basefile)
54        if system and basetmp.startswith('$HOME'):
55            basetmp = self.join_path('/tmp', basefile)
56        cmd = 'mkdir -p %s' % basetmp
57        if mode:
58            cmd += ' && chmod %s %s' % (mode, basetmp)
59        cmd += ' && echo %s' % basetmp
60        return cmd
61
62    def md5(self, path):
63        path = pipes.quote(path)
64        # The following test needs to be SH-compliant.  BASH-isms will
65        # not work if /bin/sh points to a non-BASH shell.
66        test = "rc=0; [ -r \"%s\" ] || rc=2; [ -f \"%s\" ] || rc=1; [ -d \"%s\" ] && echo 3 && exit 0" % ((path,) * 3)
67        md5s = [
68            "(/usr/bin/md5sum %s 2>/dev/null)" % path,          # Linux
69            "(/sbin/md5sum -q %s 2>/dev/null)" % path,          # ?
70            "(/usr/bin/digest -a md5 %s 2>/dev/null)" % path,   # Solaris 10+
71            "(/sbin/md5 -q %s 2>/dev/null)" % path,             # Freebsd
72            "(/usr/bin/md5 -n %s 2>/dev/null)" % path,          # Netbsd
73            "(/bin/md5 -q %s 2>/dev/null)" % path,              # Openbsd
74            "(/usr/bin/csum -h MD5 %s 2>/dev/null)" % path,     # AIX
75            "(/bin/csum -h MD5 %s 2>/dev/null)" % path          # AIX also
76        ]
77
78        cmd = " || ".join(md5s)
79        cmd = "%s; %s || (echo \"${rc}  %s\")" % (test, cmd, path)
80        return cmd
81
82    def build_module_command(self, env_string, shebang, cmd, rm_tmp=None):
83        cmd_parts = [env_string.strip(), shebang.replace("#!", "").strip(), cmd]
84        new_cmd = " ".join(cmd_parts)
85        if rm_tmp:
86            new_cmd = '%s; rm -rf %s >/dev/null 2>&1' % (new_cmd, rm_tmp)
87        return new_cmd