Permalink
Browse files

Merge remote-tracking branch 'akaihola/master'

Conflicts:
	docs/api/core/operations.rst
	docs/changelog.rst
  • Loading branch information...
2 parents 8c6ddcf + 294b869 commit 69f77f3599bec17d95349331c0a32d1a02300842 @bitprophet bitprophet committed Sep 14, 2012
Showing with 52 additions and 19 deletions.
  1. +1 −1 docs/api/core/operations.rst
  2. +2 −0 docs/changelog.rst
  3. +26 −15 fabric/operations.py
  4. +1 −1 tests/server.py
  5. +22 −2 tests/test_operations.py
@@ -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)
View
@@ -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
View
@@ -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
@@ -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.
"""
@@ -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'
@@ -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
@@ -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)
View
@@ -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
@@ -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)
)
@@ -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)

0 comments on commit 69f77f3

Please sign in to comment.