Skip to content

Commit

Permalink
Merge remote-tracking branch 'akaihola/master'
Browse files Browse the repository at this point in the history
Conflicts:
	docs/api/core/operations.rst
	docs/changelog.rst
  • Loading branch information
bitprophet committed Sep 14, 2012
2 parents 8c6ddcf + 294b869 commit 69f77f3
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 19 deletions.
2 changes: 1 addition & 1 deletion docs/api/core/operations.rst
Expand Up @@ -10,5 +10,5 @@ Operations
.. autofunction:: put(local_path, remote_path, use_sudo=False, mirror_local_mode=False, mode=None)
.. autofunction:: reboot(wait=120)
.. autofunction:: run(command, shell=True, pty=True, combine_stderr=True, quiet=False, warn_only=False, stdout=None, stderr=None)
.. autofunction:: sudo(command, shell=True, pty=True, combine_stderr=True, user=None, quiet=False, warn_only=False, stdout=None, stderr=None)
.. autofunction:: sudo(command, shell=True, pty=True, combine_stderr=True, user=None, quiet=False, warn_only=False, stdout=None, stderr=None, group=None)
.. autofunction:: local(command, capture=False)
2 changes: 2 additions & 0 deletions docs/changelog.rst
Expand Up @@ -25,6 +25,8 @@ would have also been included in the 1.2 line.
Changelog
=========

* :feature:`723` Add the ``group=`` argument to
`~fabric.operations.sudo`. Thanks to Antti Kaihola for the pull request.
* :feature:`725` Updated `~fabric.operations.local` to allow override
of which local shell is used. Thanks to Mustafa Khattab.
* :bug:`704` Fix up a bunch of Python 2.x style ``print`` statements to be
Expand Down
41 changes: 26 additions & 15 deletions fabric/operations.py
Expand Up @@ -590,16 +590,24 @@ def get(remote_path, local_path=None):
return ret


def _sudo_prefix(user):
def _sudo_prefix_argument(argument, value):
if value is None:
return ""
if str(value).isdigit():
value = "#%s" % value
return ' %s "%s"' % (argument, value)


def _sudo_prefix(user, group=None):
"""
Return ``env.sudo_prefix`` with ``user`` inserted if necessary.
Return ``env.sudo_prefix`` with ``user``/``group`` inserted if necessary.
"""
# Insert env.sudo_prompt into env.sudo_prefix
prefix = env.sudo_prefix % env
if user is not None:
if str(user).isdigit():
user = "#%s" % user
return "%s -u \"%s\" " % (prefix, user)
if user is not None or group is not None:
return "%s%s%s " % (prefix,
_sudo_prefix_argument('-u', user),
_sudo_prefix_argument('-g', group))
return prefix


Expand Down Expand Up @@ -838,7 +846,7 @@ def _noop():

def _run_command(command, shell=True, pty=True, combine_stderr=True,
sudo=False, user=None, quiet=False, warn_only=False, stdout=None,
stderr=None):
stderr=None, group=None):
"""
Underpinnings of `run` and `sudo`. See their docstrings for more info.
"""
Expand All @@ -855,7 +863,7 @@ def _run_command(command, shell=True, pty=True, combine_stderr=True,
wrapped_command = _shell_wrap(
_prefix_commands(_prefix_env_vars(command), 'remote'),
shell,
_sudo_prefix(user) if sudo else None
_sudo_prefix(user, group) if sudo else None
)
# Execute info line
which = 'sudo' if sudo else 'run'
Expand Down Expand Up @@ -986,18 +994,19 @@ def run(command, shell=True, pty=True, combine_stderr=None, quiet=False,

@needs_host
def sudo(command, shell=True, pty=True, combine_stderr=None, user=None,
quiet=False, warn_only=False, stdout=None, stderr=None):
quiet=False, warn_only=False, stdout=None, stderr=None, group=None):
"""
Run a shell command on a remote host, with superuser privileges.
`sudo` is identical in every way to `run`, except that it will always wrap
the given ``command`` in a call to the ``sudo`` program to provide
superuser privileges.
`sudo` accepts an additional ``user`` argument, which is passed to ``sudo``
and allows you to run as some user other than root. On most systems, the
``sudo`` program can take a string username or an integer userid (uid);
``user`` may likewise be a string or an int.
`sudo` accepts additional ``user`` and ``group`` arguments, which are
passed to ``sudo`` and allow you to run as some user and/or group other
than root. On most systems, the ``sudo`` program can take a string
username/group or an integer userid/groupid (uid/gid); ``user`` and
``group`` may likewise be strings or integers.
You may set :ref:`env.sudo_user <sudo_user>` at module level or via
`~fabric.context_managers.settings` if you want multiple ``sudo`` calls to
Expand Down Expand Up @@ -1025,8 +1034,10 @@ def sudo(command, shell=True, pty=True, combine_stderr=None, user=None,
.. versionadded:: 1.5
The return value attributes ``.command`` and ``.real_command``.
"""
return _run_command(command, shell, pty, combine_stderr, sudo=True,
user=user if user else env.sudo_user, quiet=quiet,
return _run_command(
command, shell, pty, combine_stderr, sudo=True,
user=user if user else env.sudo_user,
group=group, quiet=quiet,
warn_only=warn_only, stdout=stdout, stderr=stderr)


Expand Down
2 changes: 1 addition & 1 deletion tests/server.py
Expand Up @@ -401,7 +401,7 @@ def init_transport(self):
self.transport = transport

def split_sudo_prompt(self):
prefix = re.escape(_sudo_prefix(None).rstrip()) + ' +'
prefix = re.escape(_sudo_prefix(None, None).rstrip()) + ' +'
result = re.findall(r'^(%s)?(.*)$' % prefix, self.command)[0]
self.sudo_prompt, self.command = result

Expand Down
24 changes: 22 additions & 2 deletions tests/test_operations.py
Expand Up @@ -202,7 +202,7 @@ def test_sudo_prefix_with_user():
_sudo_prefix() returns prefix plus -u flag for nonempty user
"""
eq_(
_sudo_prefix(user="foo"),
_sudo_prefix(user="foo", group=None),
"%s -u \"foo\" " % (env.sudo_prefix % env)
)

Expand All @@ -211,7 +211,27 @@ def test_sudo_prefix_without_user():
"""
_sudo_prefix() returns standard prefix when user is empty
"""
eq_(_sudo_prefix(user=None), env.sudo_prefix % env)
eq_(_sudo_prefix(user=None, group=None), env.sudo_prefix % env)


def test_sudo_prefix_with_group():
"""
_sudo_prefix() returns prefix plus -g flag for nonempty group
"""
eq_(
_sudo_prefix(user=None, group="foo"),
"%s -g \"foo\" " % (env.sudo_prefix % env)
)


def test_sudo_prefix_with_user_and_group():
"""
_sudo_prefix() returns prefix plus -u and -g for nonempty user and group
"""
eq_(
_sudo_prefix(user="foo", group="bar"),
"%s -u \"foo\" -g \"bar\" " % (env.sudo_prefix % env)
)


@with_settings(use_shell=True)
Expand Down

0 comments on commit 69f77f3

Please sign in to comment.