diff --git a/bin/ansible b/bin/ansible index 86b41910d10..42de6e1d3b5 100755 --- a/bin/ansible +++ b/bin/ansible @@ -52,7 +52,7 @@ class Cli(object): parser.add_option('-m', '--module-name', dest='module_name', help="module name to execute (default=%s)" % C.DEFAULT_MODULE_NAME, default=C.DEFAULT_MODULE_NAME) - parser.add_option('-U','--sudo_user', dest='sudo_user', help='desired sudo user', + parser.add_option('-U','--sudo-user', dest='sudo_user', help='desired sudo user (default=root)', default=C.DEFAULT_SUDO_USER) options, args = parser.parse_args() self.callbacks.options = options @@ -82,6 +82,8 @@ class Cli(object): sshpass = getpass.getpass(prompt="SSH password: ") if options.ask_sudo_pass: sudopass = getpass.getpass(prompt="sudo password: ") + if options.sudo_user: + options.sudo=True if options.tree: utils.prepare_writeable_dir(options.tree) diff --git a/lib/ansible/playbook.py b/lib/ansible/playbook.py index 57d9af5eddb..b9449bf4266 100644 --- a/lib/ansible/playbook.py +++ b/lib/ansible/playbook.py @@ -62,6 +62,7 @@ class PlayBook(object): runner_callbacks = None, stats = None, sudo = False, + sudo_user = 'root', extra_vars = None): """ @@ -102,6 +103,7 @@ class PlayBook(object): self.stats = stats self.sudo = sudo self.sudo_pass = sudo_pass + self.sudo_user = sudo_user self.extra_vars = extra_vars self.global_vars = {} @@ -275,7 +277,7 @@ class PlayBook(object): # ***************************************************** def _run_module(self, pattern, module, args, vars, remote_user, - async_seconds, async_poll_interval, only_if, sudo, transport, port): + async_seconds, async_poll_interval, only_if, sudo, sudo_user, transport, port): ''' run a particular module step in a playbook ''' hosts = [ h for h in self.inventory.list_hosts() if (h not in self.stats.failures) and (h not in self.stats.dark)] @@ -292,7 +294,7 @@ class PlayBook(object): remote_port=port, module_vars=vars, setup_cache=SETUP_CACHE, basedir=self.basedir, conditional=only_if, callbacks=self.runner_callbacks, - debug=self.debug, sudo=sudo, + debug=self.debug, sudo=sudo, sudo_user=sudo_user, transport=transport, sudo_pass=self.sudo_pass, is_playbook=True ) @@ -312,7 +314,8 @@ class PlayBook(object): # ***************************************************** def _run_task(self, pattern=None, task=None, - remote_user=None, handlers=None, conditional=False, sudo=False, transport=None, port=None): + remote_user=None, handlers=None, conditional=False, + sudo=False, sudo_user=None, transport=None, port=None): ''' run a single task in the playbook and recursively run any subtasks. ''' # load the module name and parameters from the task entry @@ -348,7 +351,7 @@ class PlayBook(object): # run the task in parallel results = self._run_module(pattern, module_name, module_args, module_vars, remote_user, async_seconds, - async_poll_interval, only_if, sudo, transport, port) + async_poll_interval, only_if, sudo, sudo_user, transport, port) # add facts to the global setup cache for host, result in results['contacted'].iteritems(): @@ -449,7 +452,7 @@ class PlayBook(object): # ***************************************************** - def _do_setup_step(self, pattern, vars, user, port, sudo, transport, vars_files=None): + def _do_setup_step(self, pattern, vars, user, port, sudo, sudo_user, transport, vars_files=None): ''' push variables down to the systems and get variables+facts back up ''' # this enables conditional includes like $facter_os.yml and is only done @@ -474,8 +477,9 @@ class PlayBook(object): timeout=self.timeout, remote_user=user, remote_pass=self.remote_pass, remote_port=port, setup_cache=SETUP_CACHE, - callbacks=self.runner_callbacks, sudo=sudo, debug=self.debug, - transport=transport, sudo_pass=self.sudo_pass, is_playbook=True + callbacks=self.runner_callbacks, sudo=sudo, sudo_user=sudo_user, + debug=self.debug, transport=transport, + sudo_pass=self.sudo_pass, is_playbook=True ).run() self.stats.compute(setup_results, setup=True) @@ -512,16 +516,21 @@ class PlayBook(object): user = pg.get('user', self.remote_user) port = pg.get('port', self.remote_port) sudo = pg.get('sudo', self.sudo) + sudo_user = pg.get('sudo_user', self.sudo_user) transport = pg.get('connection', self.transport) + # the default sudo user is root, so if you change it, sudo is implied + if sudo_user != 'root': + sudo = True + self.callbacks.on_play_start(name) # push any variables down to the system # and get facts/ohai/other data back up - self._do_setup_step(pattern, vars, user, port, sudo, transport, None) + self._do_setup_step(pattern, vars, user, port, sudo, sudo_user, transport, None) # now with that data, handle contentional variable file imports! if len(vars_files) > 0: - self._do_setup_step(pattern, vars, user, port, sudo, transport, vars_files) + self._do_setup_step(pattern, vars, user, port, sudo, sudo_user, transport, vars_files) # run all the top level tasks, these get run on every node for task in tasks: @@ -531,6 +540,7 @@ class PlayBook(object): handlers=handlers, remote_user=user, sudo=sudo, + sudo_user=sudo_user, transport=transport, port=port ) @@ -552,6 +562,7 @@ class PlayBook(object): conditional=True, remote_user=user, sudo=sudo, + sudo_user=sudo_user, transport=transport, port=port ) diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py index 5c52c17f13a..cde1ecee172 100644 --- a/lib/ansible/runner.py +++ b/lib/ansible/runner.py @@ -77,8 +77,8 @@ class Runner(object): remote_pass=C.DEFAULT_REMOTE_PASS, remote_port=C.DEFAULT_REMOTE_PORT, sudo_pass=C.DEFAULT_SUDO_PASS, background=0, basedir=None, setup_cache=None, transport=C.DEFAULT_TRANSPORT, conditional='True', - callbacks=None, debug=False, sudo=False, sudo_user=C.DEFAULT_SUDO_USER - ,module_vars=None, is_playbook=False, inventory=None): + callbacks=None, debug=False, sudo=False, sudo_user=C.DEFAULT_SUDO_USER, + module_vars=None, is_playbook=False, inventory=None): """ host_list : path to a host list file, like /etc/ansible/hosts @@ -626,7 +626,7 @@ class Runner(object): def _exec_command(self, conn, cmd, tmp, sudoable=False): ''' execute a command string over SSH, return the output ''' sudo_user = self.sudo_user - stdin, stdout, stderr = conn.exec_command(cmd, tmp, sudo_user,sudoable=sudoable) + stdin, stdout, stderr = conn.exec_command(cmd, tmp, sudo_user, sudoable=sudoable) err=None out=None if type(stderr) != str: