/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. import os
  18. import pipes
  19. import ansible.constants as C
  20. class ShellModule(object):
  21. def env_prefix(self, **kwargs):
  22. '''Build command prefix with environment variables.'''
  23. env = dict(
  24. LANG = C.DEFAULT_MODULE_LANG,
  25. LC_CTYPE = C.DEFAULT_MODULE_LANG,
  26. )
  27. env.update(kwargs)
  28. return ' '.join(['%s=%s' % (k, pipes.quote(unicode(v))) for k,v in env.items()])
  29. def join_path(self, *args):
  30. return os.path.join(*args)
  31. def path_has_trailing_slash(self, path):
  32. return path.endswith('/')
  33. def chmod(self, mode, path):
  34. path = pipes.quote(path)
  35. return 'chmod %s %s' % (mode, path)
  36. def remove(self, path, recurse=False):
  37. path = pipes.quote(path)
  38. if recurse:
  39. return "rm -rf %s >/dev/null 2>&1" % path
  40. else:
  41. return "rm -f %s >/dev/null 2>&1" % path
  42. def mkdtemp(self, basefile=None, system=False, mode=None):
  43. if not basefile:
  44. basefile = 'ansible-tmp-%s-%s' % (time.time(), random.randint(0, 2**48))
  45. basetmp = self.join_path(C.DEFAULT_REMOTE_TMP, basefile)
  46. if system and basetmp.startswith('$HOME'):
  47. basetmp = self.join_path('/tmp', basefile)
  48. cmd = 'mkdir -p %s' % basetmp
  49. if mode:
  50. cmd += ' && chmod %s %s' % (mode, basetmp)
  51. cmd += ' && echo %s' % basetmp
  52. return cmd
  53. def md5(self, path):
  54. path = pipes.quote(path)
  55. # The following test needs to be SH-compliant. BASH-isms will
  56. # not work if /bin/sh points to a non-BASH shell.
  57. test = "rc=0; [ -r \"%s\" ] || rc=2; [ -f \"%s\" ] || rc=1; [ -d \"%s\" ] && echo 3 && exit 0" % ((path,) * 3)
  58. md5s = [
  59. "(/usr/bin/md5sum %s 2>/dev/null)" % path, # Linux
  60. "(/sbin/md5sum -q %s 2>/dev/null)" % path, # ?
  61. "(/usr/bin/digest -a md5 %s 2>/dev/null)" % path, # Solaris 10+
  62. "(/sbin/md5 -q %s 2>/dev/null)" % path, # Freebsd
  63. "(/usr/bin/md5 -n %s 2>/dev/null)" % path, # Netbsd
  64. "(/bin/md5 -q %s 2>/dev/null)" % path, # Openbsd
  65. "(/usr/bin/csum -h MD5 %s 2>/dev/null)" % path, # AIX
  66. "(/bin/csum -h MD5 %s 2>/dev/null)" % path # AIX also
  67. ]
  68. cmd = " || ".join(md5s)
  69. cmd = "%s; %s || (echo \"${rc} %s\")" % (test, cmd, path)
  70. return cmd
  71. def build_module_command(self, env_string, shebang, cmd, rm_tmp=None):
  72. cmd_parts = [env_string.strip(), shebang.replace("#!", "").strip(), cmd]
  73. new_cmd = " ".join(cmd_parts)
  74. if rm_tmp:
  75. new_cmd = '%s; rm -rf %s >/dev/null 2>&1' % (new_cmd, rm_tmp)
  76. return new_cmd