From 22304afd1db399cfb94ae485486384ca3c9c0e33 Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Fri, 13 Mar 2015 15:31:20 -0500 Subject: [PATCH] More fixing of become stuff in v2 --- v2/ansible/executor/connection_info.py | 62 +++++++++++++------------ v2/ansible/playbook/play.py | 1 - v2/ansible/plugins/action/__init__.py | 2 +- v2/ansible/plugins/connections/local.py | 19 ++------ v2/ansible/plugins/connections/ssh.py | 15 +----- v2/samples/test_become.yml | 3 +- 6 files changed, 39 insertions(+), 63 deletions(-) diff --git a/v2/ansible/executor/connection_info.py b/v2/ansible/executor/connection_info.py index f2eaec630d4..b918dc6b214 100644 --- a/v2/ansible/executor/connection_info.py +++ b/v2/ansible/executor/connection_info.py @@ -164,7 +164,7 @@ class ConnectionInformation: return new_info - def make_become_cmd(self, cmd, shell, become_settings=None): + def make_become_cmd(self, cmd, executable, become_settings=None): """ helper function to create privilege escalation commands @@ -179,39 +179,43 @@ class ConnectionInformation: prompt = None becomecmd = None - shell = shell or '$SHELL' + executable = executable or '$SHELL' - if self.become_method == 'sudo': - # Rather than detect if sudo wants a password this time, -k makes sudo always ask for - # a password if one is required. Passing a quoted compound command to sudo (or sudo -s) - # directly doesn't work, so we shellquote it with pipes.quote() and pass the quoted - # string to the user's shell. We loop reading output until we see the randomly-generated - # sudo prompt set with the -p option. - prompt = '[sudo via ansible, key=%s] password: ' % randbits - exe = become_settings.get('sudo_exe', C.DEFAULT_SUDO_EXE) - flags = become_settings.get('sudo_flags', C.DEFAULT_SUDO_FLAGS) - becomecmd = '%s -k && %s %s -S -p "%s" -u %s %s -c "%s"' % \ - (exe, exe, flags or C.DEFAULT_SUDO_FLAGS, prompt, self.become_user, shell, 'echo %s; %s' % (success_key, cmd)) + if self.become: + if self.become_method == 'sudo': + # Rather than detect if sudo wants a password this time, -k makes sudo always ask for + # a password if one is required. Passing a quoted compound command to sudo (or sudo -s) + # directly doesn't work, so we shellquote it with pipes.quote() and pass the quoted + # string to the user's shell. We loop reading output until we see the randomly-generated + # sudo prompt set with the -p option. + prompt = '[sudo via ansible, key=%s] password: ' % randbits + exe = become_settings.get('sudo_exe', C.DEFAULT_SUDO_EXE) + flags = become_settings.get('sudo_flags', C.DEFAULT_SUDO_FLAGS) + becomecmd = '%s -k && %s %s -S -p "%s" -u %s %s -c "%s"' % \ + (exe, exe, flags or C.DEFAULT_SUDO_FLAGS, prompt, self.become_user, executable, 'echo %s; %s' % (success_key, cmd)) - elif self.become_method == 'su': - exe = become_settings.get('su_exe', C.DEFAULT_SU_EXE) - flags = become_settings.get('su_flags', C.DEFAULT_SU_FLAGS) - becomecmd = '%s %s %s -c "%s -c %s"' % (exe, flags, self.become_user, shell, pipes.quote('echo %s; %s' % (success_key, cmd))) + elif self.become_method == 'su': + exe = become_settings.get('su_exe', C.DEFAULT_SU_EXE) + flags = become_settings.get('su_flags', C.DEFAULT_SU_FLAGS) + becomecmd = '%s %s %s -c "%s -c %s"' % (exe, flags, self.become_user, executable, pipes.quote('echo %s; %s' % (success_key, cmd))) - elif self.become_method == 'pbrun': - exe = become_settings.get('pbrun_exe', 'pbrun') - flags = become_settings.get('pbrun_flags', '') - becomecmd = '%s -b -l %s -u %s "%s"' % (exe, flags, self.become_user, 'echo %s; %s' % (success_key,cmd)) + elif self.become_method == 'pbrun': + exe = become_settings.get('pbrun_exe', 'pbrun') + flags = become_settings.get('pbrun_flags', '') + becomecmd = '%s -b -l %s -u %s "%s"' % (exe, flags, self.become_user, 'echo %s; %s' % (success_key,cmd)) - elif self.become_method == 'pfexec': - exe = become_settings.get('pfexec_exe', 'pbrun') - flags = become_settings.get('pfexec_flags', '') - # No user as it uses it's own exec_attr to figure it out - becomecmd = '%s %s "%s"' % (exe, flags, 'echo %s; %s' % (success_key,cmd)) - elif self.become: - raise errors.AnsibleError("Privilege escalation method not found: %s" % method) + elif self.become_method == 'pfexec': + exe = become_settings.get('pfexec_exe', 'pbrun') + flags = become_settings.get('pfexec_flags', '') + # No user as it uses it's own exec_attr to figure it out + becomecmd = '%s %s "%s"' % (exe, flags, 'echo %s; %s' % (success_key,cmd)) - return (('%s -c ' % shell) + pipes.quote(becomecmd), prompt, success_key) + else: + raise errors.AnsibleError("Privilege escalation method not found: %s" % method) + + return (('%s -c ' % executable) + pipes.quote(becomecmd), prompt, success_key) + + return (cmd, "", "") def check_become_success(self, output, become_settings): #TODO: implement diff --git a/v2/ansible/playbook/play.py b/v2/ansible/playbook/play.py index e9847fccd90..cbe4e038617 100644 --- a/v2/ansible/playbook/play.py +++ b/v2/ansible/playbook/play.py @@ -100,7 +100,6 @@ class Play(Base, Taggable, Become): @staticmethod def load(data, variable_manager=None, loader=None): p = Play() - print("in play load, become is: %s" % getattr(p, 'become')) return p.load_data(data, variable_manager=variable_manager, loader=loader) def munge(self, ds): diff --git a/v2/ansible/plugins/action/__init__.py b/v2/ansible/plugins/action/__init__.py index 46f25ec503c..d430bd748be 100644 --- a/v2/ansible/plugins/action/__init__.py +++ b/v2/ansible/plugins/action/__init__.py @@ -454,7 +454,7 @@ class ActionBase: success_key = None if sudoable: - cmd, prompt, success_key = self._connection_info.make_become_cmd(executable, cmd) + cmd, prompt, success_key = self._connection_info.make_become_cmd(cmd, executable) debug("executing the command %s through the connection" % cmd) rc, stdin, stdout, stderr = self._connection.exec_command(cmd, tmp, executable=executable, in_data=in_data) diff --git a/v2/ansible/plugins/connections/local.py b/v2/ansible/plugins/connections/local.py index d75ee70159e..c847ee79d5d 100644 --- a/v2/ansible/plugins/connections/local.py +++ b/v2/ansible/plugins/connections/local.py @@ -50,27 +50,14 @@ class Connection(ConnectionBase): if in_data: raise AnsibleError("Internal Error: this module does not support optimized module pipelining") - # FIXME: su/sudo stuff needs to be generalized - #if not self.runner.sudo or not sudoable: - # if executable: - # local_cmd = executable.split() + ['-c', cmd] - # else: - # local_cmd = cmd - #else: - # local_cmd, prompt, success_key = utils.make_become_cmd(self.runner.sudo_exe, sudo_user, executable, cmd) - if executable: - local_cmd = executable.split() + ['-c', cmd] - else: - local_cmd = cmd - executable = executable.split()[0] if executable else None - self._display.vvv("%s EXEC %s" % (self._connection_info.remote_addr, local_cmd)) + self._display.vvv("%s EXEC %s" % (self._connection_info.remote_addr, cmd)) # FIXME: cwd= needs to be set to the basedir of the playbook debug("opening command with Popen()") p = subprocess.Popen( - local_cmd, - shell=isinstance(local_cmd, basestring), + cmd, + shell=isinstance(cmd, basestring), executable=executable, #cwd=... stdin=subprocess.PIPE, stdout=subprocess.PIPE, diff --git a/v2/ansible/plugins/connections/ssh.py b/v2/ansible/plugins/connections/ssh.py index e5b397f5659..e233a704f98 100644 --- a/v2/ansible/plugins/connections/ssh.py +++ b/v2/ansible/plugins/connections/ssh.py @@ -281,20 +281,7 @@ class Connection(ConnectionBase): # ssh_cmd += ['-6'] ssh_cmd += [self._connection_info.remote_addr] - #if not (self._connection_info.sudo or self._connection_info.su): - # prompt = None - # if executable: - # ssh_cmd.append(executable + ' -c ' + pipes.quote(cmd)) - # else: - # ssh_cmd.append(cmd) - #elif self._connection_info.su and self._connection_info.su_user: - # su_cmd, prompt, success_key = self._connection_info.make_su_cmd(executable, cmd) - # ssh_cmd.append(su_cmd) - #else: - # # FIXME: hard-coded sudo_exe here - # sudo_cmd, prompt, success_key = self._connection_info.make_become_cmd('/usr/bin/sudo', executable, cmd) - # ssh_cmd.append(sudo_cmd) - + ssh_cmd.append(cmd) self._display.vvv("EXEC %s" % ' '.join(ssh_cmd), host=self._connection_info.remote_addr) not_in_host_file = self.not_in_host_file(self._connection_info.remote_addr) diff --git a/v2/samples/test_become.yml b/v2/samples/test_become.yml index 7e229af5de2..8e753beade3 100644 --- a/v2/samples/test_become.yml +++ b/v2/samples/test_become.yml @@ -2,6 +2,5 @@ gather_facts: no tasks: - command: whoami - become: yes - become_user: jamesc + become_user: testing become_method: su