diff options
Diffstat (limited to 'library/commands/command')
-rw-r--r-- | library/commands/command | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/library/commands/command b/library/commands/command deleted file mode 100644 index c1fabd4f9b..0000000000 --- a/library/commands/command +++ /dev/null @@ -1,275 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>, and others -# -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -import sys -import datetime -import traceback -import re -import shlex -import os - -DOCUMENTATION = ''' ---- -module: command -version_added: historical -short_description: Executes a command on a remote node -description: - - The M(command) module takes the command name followed by a list of space-delimited arguments. - - The given command will be executed on all selected nodes. It will not be - processed through the shell, so variables like C($HOME) and operations - like C("<"), C(">"), C("|"), and C("&") will not work (use the M(shell) - module if you need these features). -options: - free_form: - description: - - the command module takes a free form command to run. There is no parameter actually named 'free form'. - See the examples! - required: true - default: null - aliases: [] - creates: - description: - - a filename, when it already exists, this step will B(not) be run. - required: no - default: null - removes: - description: - - a filename, when it does not exist, this step will B(not) be run. - version_added: "0.8" - required: no - default: null - chdir: - description: - - cd into this directory before running the command - version_added: "0.6" - required: false - default: null - executable: - description: - - change the shell used to execute the command. Should be an absolute path to the executable. - required: false - default: null - version_added: "0.9" - warn: - version_added: "1.8" - default: yes - description: - - if command warnings are on in ansible.cfg, do not warn about this particular line if set to no/false. - required: false - default: True -notes: - - If you want to run a command through the shell (say you are using C(<), - C(>), C(|), etc), you actually want the M(shell) module instead. The - M(command) module is much more secure as it's not affected by the user's - environment. - - " C(creates), C(removes), and C(chdir) can be specified after the command. For instance, if you only want to run a command if a certain file does not exist, use this." -author: Michael DeHaan -''' - -EXAMPLES = ''' -# Example from Ansible Playbooks. -- command: /sbin/shutdown -t now - -# Run the command if the specified file does not exist. -- command: /usr/bin/make_database.sh arg1 arg2 creates=/path/to/database - -# You can also use the 'args' form to provide the options. This command -# will change the working directory to somedir/ and will only run when -# /path/to/database doesn't exist. -- command: /usr/bin/make_database.sh arg1 arg2 - args: - chdir: somedir/ - creates: /path/to/database -''' - -# This is a pretty complex regex, which functions as follows: -# -# 1. (^|\s) -# ^ look for a space or the beginning of the line -# 2. (creates|removes|chdir|executable|NO_LOG)= -# ^ look for a valid param, followed by an '=' -# 3. (?P<quote>[\'"])? -# ^ look for an optional quote character, which can either be -# a single or double quote character, and store it for later -# 4. (.*?) -# ^ match everything in a non-greedy manner until... -# 5. (?(quote)(?<!\\)(?P=quote))((?<!\\)(?=\s)|$) -# ^ a non-escaped space or a non-escaped quote of the same kind -# that was matched in the first 'quote' is found, or the end of -# the line is reached - -PARAM_REGEX = re.compile(r'(^|\s)(creates|removes|chdir|executable|NO_LOG|warn)=(?P<quote>[\'"])?(.*?)(?(quote)(?<!\\)(?P=quote))((?<!\\)(?=\s)|$)') - - -def check_command(commandline): - arguments = { 'chown': 'owner', 'chmod': 'mode', 'chgrp': 'group', - 'ln': 'state=link', 'mkdir': 'state=directory', - 'rmdir': 'state=absent', 'rm': 'state=absent', 'touch': 'state=touch' } - commands = { 'git': 'git', 'hg': 'hg', 'curl': 'get_url', 'wget': 'get_url', - 'svn': 'subversion', 'service': 'service', - 'mount': 'mount', 'rpm': 'yum', 'yum': 'yum', 'apt-get': 'apt-get', - 'tar': 'unarchive', 'unzip': 'unarchive', 'sed': 'template or lineinfile', - 'rsync': 'synchronize' } - warnings = list() - command = os.path.basename(commandline.split()[0]) - if command in arguments: - warnings.append("Consider using file module with %s rather than running %s" % (arguments[command], command)) - if command in commands: - warnings.append("Consider using %s module rather than running %s" % (commands[command], command)) - return warnings - - -def main(): - - # the command module is the one ansible module that does not take key=value args - # hence don't copy this one if you are looking to build others! - module = CommandModule(argument_spec=dict()) - - shell = module.params['shell'] - chdir = module.params['chdir'] - executable = module.params['executable'] - args = module.params['args'] - creates = module.params['creates'] - removes = module.params['removes'] - warn = module.params.get('warn', True) - - if args.strip() == '': - module.fail_json(rc=256, msg="no command given") - - if chdir: - os.chdir(chdir) - - if creates: - # do not run the command if the line contains creates=filename - # and the filename already exists. This allows idempotence - # of command executions. - v = os.path.expanduser(creates) - if os.path.exists(v): - module.exit_json( - cmd=args, - stdout="skipped, since %s exists" % v, - changed=False, - stderr=False, - rc=0 - ) - - if removes: - # do not run the command if the line contains removes=filename - # and the filename does not exist. This allows idempotence - # of command executions. - v = os.path.expanduser(removes) - if not os.path.exists(v): - module.exit_json( - cmd=args, - stdout="skipped, since %s does not exist" % v, - changed=False, - stderr=False, - rc=0 - ) - - warnings = list() - if warn: - warnings = check_command(args) - - if not shell: - args = shlex.split(args) - startd = datetime.datetime.now() - - rc, out, err = module.run_command(args, executable=executable, use_unsafe_shell=shell) - - endd = datetime.datetime.now() - delta = endd - startd - - if out is None: - out = '' - if err is None: - err = '' - - module.exit_json( - cmd = args, - stdout = out.rstrip("\r\n"), - stderr = err.rstrip("\r\n"), - rc = rc, - start = str(startd), - end = str(endd), - delta = str(delta), - changed = True, - warnings = warnings - ) - -# import module snippets -from ansible.module_utils.basic import * -from ansible.module_utils.splitter import * - -# only the command module should ever need to do this -# everything else should be simple key=value - -class CommandModule(AnsibleModule): - - def _handle_aliases(self): - return {} - - def _check_invalid_arguments(self): - pass - - def _load_params(self): - ''' read the input and return a dictionary and the arguments string ''' - args = MODULE_ARGS - params = {} - params['chdir'] = None - params['creates'] = None - params['removes'] = None - params['shell'] = False - params['executable'] = None - params['warn'] = True - if "#USE_SHELL" in args: - args = args.replace("#USE_SHELL", "") - params['shell'] = True - - items = split_args(args) - - for x in items: - quoted = x.startswith('"') and x.endswith('"') or x.startswith("'") and x.endswith("'") - if '=' in x and not quoted: - # check to see if this is a special parameter for the command - k, v = x.split('=', 1) - v = unquote(v) - # because we're not breaking out quotes in the shlex split - # above, the value of the k=v pair may still be quoted. If - # so, remove them. - if len(v) > 1 and (v.startswith('"') and v.endswith('"') or v.startswith("'") and v.endswith("'")): - v = v[1:-1] - if k in ('creates', 'removes', 'chdir', 'executable', 'NO_LOG'): - if k == "chdir": - v = os.path.abspath(os.path.expanduser(v)) - if not (os.path.exists(v) and os.path.isdir(v)): - self.fail_json(rc=258, msg="cannot change to directory '%s': path does not exist" % v) - elif k == "executable": - v = os.path.abspath(os.path.expanduser(v)) - if not (os.path.exists(v)): - self.fail_json(rc=258, msg="cannot use executable '%s': file does not exist" % v) - params[k] = v - # Remove any of the above k=v params from the args string - args = PARAM_REGEX.sub('', args) - params['args'] = args.strip() - - return (params, params['args']) - -main() |