Skip to content

Commit

Permalink
Merge pull request #4: Additional sudo changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
xolox committed Oct 19, 2014
2 parents 766c230 + 6909e59 commit 2f3858e
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 39 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
deb_pkg_tools.egg-info
59 changes: 44 additions & 15 deletions README.rst
Expand Up @@ -20,6 +20,8 @@ variables. If you find something that doesn't work to your liking and you can't
work around it, feel free to ask for an additional configuration option; I try
to keep an open mind about the possible use cases of my projects.

.. contents::

Status
------

Expand Down Expand Up @@ -102,25 +104,52 @@ have an ``-l`` parameter and the ``root`` user and group may not exist, but
despite these things it can still be useful to test package builds on Mac OS
X. The following environment variables can be used to adjust such factors:

==================== ======== ================================================
Variable Default Description
==================== ======== ================================================
``DPT_HARD_LINKS`` ``true`` Allow the usage of hard links to speed up file
copies between directories on the same file
system.
``DPT_ROOT_USER`` ``root`` During package builds the ownership of all
directories and files is reset to this user.
``DPT_ROOT_GROUP`` ``root`` During package builds the ownership of all
directories and files is reset to this group.
``DPT_SUDO`` ``true`` Enable the usage of ``sudo`` during operations
that normally require elevated privileges.
``DPT_RESET_SETGID`` ``true`` Reset sticky bit on directories inside package
templates before building.
==================== ======== ================================================
============================== ============= ================================
Variable Default Description
============================== ============= ================================
``DPT_CHOWN_FILES`` ``true`` Normalize ownership of files
during packaging.
``DPT_ROOT_USER`` ``root`` During package builds the
ownership of all directories and
files is reset to this user.
``DPT_ROOT_GROUP`` ``root`` During package builds the
ownership of all directories and
files is reset to this group.
``DPT_RESET_SETGID`` ``true`` Reset sticky bit on directories
inside package templates before
building.
``DPT_ALLOW_FAKEROOT_OR_SUDO`` ``true`` Run commands using either
fakeroot or sudo (depending on
which is available).
``DPT_SUDO`` ``true`` Enable the usage of ``sudo``
during operations that normally
require elevated privileges.
``DPT_HARD_LINKS`` ``true`` Allow the usage of hard links to
speed up file copies between
directories on the same file
system.
``DPT_FORCE_ENTROPY`` ``false`` Force the system to generate
entropy based on disk I/O.
``SHELL`` ``/bin/bash`` Shell to use for the
``deb-pkg-tools --with-repo``
command.
============================== ============= ================================

Environment variables for boolean options support the strings ``yes``,
``true``, ``1``, ``no``, ``false`` and ``0`` (case is ignored).

Disabling sudo usage
~~~~~~~~~~~~~~~~~~~~

To disable any use of ``sudo`` you can use the following:

.. code-block:: bash
export DPT_ALLOW_FAKEROOT_OR_SUDO=false
export DPT_CHOWN_FILES=false
export DPT_RESET_SETGID=false
export DPT_SUDO=false
Contact
-------

Expand Down
4 changes: 2 additions & 2 deletions deb_pkg_tools/__init__.py
@@ -1,11 +1,11 @@
# Debian packaging tools.
#
# Author: Peter Odding <peter@peterodding.com>
# Last Change: September 17, 2014
# Last Change: October 19, 2014
# URL: https://github.com/xolox/python-deb-pkg-tools

# Semi-standard module versioning.
__version__ = '1.28'
__version__ = '1.29'

debian_package_dependencies = (
'apt', # apt-get
Expand Down
2 changes: 1 addition & 1 deletion deb_pkg_tools/gpg.py
Expand Up @@ -226,7 +226,7 @@ class EntropyGenerator(object):
"""

def __init__(self):
self.enabled = coerce_boolean(os.environ.get('DPT_FORCE_ENTROPY', 'no'))
self.enabled = coerce_boolean(os.environ.get('DPT_FORCE_ENTROPY', 'false'))
if self.enabled:
self.process = multiprocessing.Process(target=generate_entropy)

Expand Down
39 changes: 26 additions & 13 deletions deb_pkg_tools/package.py
@@ -1,7 +1,7 @@
# Debian packaging tools: Package manipulation.
#
# Author: Peter Odding <peter@peterodding.com>
# Last Change: August 31, 2014
# Last Change: October 19, 2014
# URL: https://github.com/xolox/python-deb-pkg-tools

"""
Expand Down Expand Up @@ -60,6 +60,13 @@
'.hgtags', # Mercurial ignore files (http://lintian.debian.org/tags/package-contains-vcs-control-file.html)
'.s??') # Vim anonymous swap files

# Enable power users to customize how packages are built in order to enable
# limited use of deb-pkg-tools in non-Debian environments like Mac OS X.
ALLOW_CHOWN = coerce_boolean(os.environ.get('DPT_CHOWN_FILES', 'true'))
ALLOW_FAKEROOT_OR_SUDO = coerce_boolean(os.environ.get('DPT_ALLOW_FAKEROOT_OR_SUDO', 'true'))
ALLOW_HARD_LINKS = coerce_boolean(os.environ.get('DPT_HARD_LINKS', 'true'))
ALLOW_RESET_SETGID = coerce_boolean(os.environ.get('DPT_RESET_SETGID', 'true'))

def parse_filename(filename):
"""
Parse the filename of a Debian binary package archive into three fields:
Expand Down Expand Up @@ -501,13 +508,15 @@ def build_package(directory, repository=None, check_package=True, copy_files=Tru
# install the package. As you can imagine, the results are
# disastrous...
os.chmod(build_directory, 0o755)
# Make sure all files included in the package are owned by `root'
# (the only account guaranteed to exist on all systems).
root_user = os.environ.get('DPT_ROOT_USER', 'root')
root_group = os.environ.get('DPT_ROOT_GROUP', 'root')
user_spec = '%s:%s' % (root_user, root_group)
logger.debug("Resetting file ownership (to %s) ..", user_spec)
execute('chown', '-R', user_spec, build_directory, fakeroot=True, logger=logger)
if ALLOW_CHOWN:
# Make sure all files included in the package are owned by `root'
# (the only account guaranteed to exist on all systems).
root_user = os.environ.get('DPT_ROOT_USER', 'root')
root_group = os.environ.get('DPT_ROOT_GROUP', 'root')
user_spec = '%s:%s' % (root_user, root_group)
logger.debug("Resetting file ownership (to %s) ..", user_spec)
execute('chown', '-R', user_spec, build_directory,
fakeroot=ALLOW_FAKEROOT_OR_SUDO, logger=logger)
# Reset the file modes of pre/post installation/removal scripts.
for script_name in ('preinst', 'postinst', 'prerm', 'postrm'):
script_path = os.path.join(build_directory, 'DEBIAN', script_name)
Expand All @@ -519,17 +528,20 @@ def build_package(directory, repository=None, check_package=True, copy_files=Tru
# world) so we'll go ahead and remove some potentially harmful
# permission bits (harmful enough that Lintian complains about them).
logger.debug("Resetting file modes (go-w) ..")
execute('chmod', '-R', 'go-w', build_directory, fakeroot=True, logger=logger)
execute('chmod', '-R', 'go-w', build_directory,
fakeroot=ALLOW_FAKEROOT_OR_SUDO, logger=logger)
# Remove the setgid bit from all directories in the package. Rationale:
# In my situation package templates are stored in a directory where a
# team of people have push access (I imagine that this is a common
# setup). To facilitate shared push access a shared primary UNIX group
# is used with the sticky bit on directories. However dpkg-deb *really*
# doesn't like this, failing with the error "dpkg-deb: control
# directory has bad permissions 2755 (must be >=0755 and <=0775)".
if coerce_boolean(os.environ.get('DPT_RESET_SETGID', 'true')):
if ALLOW_RESET_SETGID:
logger.debug("Removing sticky bit from directories (g-s) ..")
execute('find -type d -print0 | xargs -0 chmod g-s', directory=build_directory, fakeroot=True, logger=logger)
execute('find -type d -print0 | xargs -0 chmod g-s',
directory=build_directory,
fakeroot=ALLOW_FAKEROOT_OR_SUDO, logger=logger)
# Make sure files in /etc/sudoers.d have the correct permissions.
sudoers_directory = os.path.join(build_directory, 'etc', 'sudoers.d')
if os.path.isdir(sudoers_directory):
Expand All @@ -539,7 +551,8 @@ def build_package(directory, repository=None, check_package=True, copy_files=Tru
os.chmod(pathname, 0o440)
# Build the package using `dpkg-deb'.
logger.info("Building package in %s ..", format_path(build_directory))
execute('dpkg-deb', '--build', build_directory, package_file, fakeroot=True, logger=logger)
execute('dpkg-deb', '--build', build_directory, package_file,
fakeroot=ALLOW_FAKEROOT_OR_SUDO, logger=logger)
# Check the package for possible issues using Lintian?
if check_package:
if not os.access('/usr/bin/lintian', os.X_OK):
Expand Down Expand Up @@ -594,7 +607,7 @@ def copy_package_files(from_directory, to_directory, hard_links=True):
command = ['cp', '-a']
if not os.path.isdir(to_directory):
os.makedirs(to_directory)
if hard_links and coerce_boolean(os.environ.get('DPT_HARD_LINKS', 'true')):
if hard_links and ALLOW_HARD_LINKS:
# Check whether we can use hard links to speed up the copy. In the past
# this used the following simple and obvious check:
#
Expand Down
16 changes: 8 additions & 8 deletions deb_pkg_tools/repo.py
@@ -1,7 +1,7 @@
# Debian packaging tools: Trivial repository management.
#
# Author: Peter Odding <peter@peterodding.com>
# Last Change: August 4, 2014
# Last Change: October 19, 2014
# URL: https://github.com/xolox/python-deb-pkg-tools

"""
Expand Down Expand Up @@ -60,7 +60,7 @@

# Enable power users to disable the use of `sudo' (because it
# may not be available in non-Debian build environments).
SUDO_ENABLED = coerce_boolean(os.environ.get('DPT_SUDO', 'true'))
ALLOW_SUDO = coerce_boolean(os.environ.get('DPT_SUDO', 'true'))

# Initialize a logger.
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -286,7 +286,7 @@ def activate_repository(directory, gpg_key=None):
logger.debug("Activating repository: %s", format_path(directory))
# Generate the `sources.list' file.
sources_directory = '/etc/apt/sources.list.d'
execute('mkdir', '-p', sources_directory, sudo=SUDO_ENABLED, logger=logger)
execute('mkdir', '-p', sources_directory, sudo=ALLOW_SUDO, logger=logger)
sources_file = os.path.join(sources_directory, '%s.list' % sha1(directory))
logger.debug("Generating file: %s", sources_file)
sources_entry = ['deb']
Expand All @@ -297,17 +297,17 @@ def activate_repository(directory, gpg_key=None):
command = "echo {text} > {file}"
execute(command.format(text=pipes.quote(' '.join(sources_entry)),
file=pipes.quote(sources_file)),
sudo=SUDO_ENABLED, logger=logger)
sudo=ALLOW_SUDO, logger=logger)
# Make apt-get accept the repository signing key?
gpg_key = gpg_key or select_gpg_key(directory)
if gpg_key:
logger.info("Installing GPG key for automatic signing ..")
initialize_gnupg()
command = '{gpg} --armor --export | apt-key add -'
execute(command.format(gpg=gpg_key.gpg_command), sudo=SUDO_ENABLED, logger=logger)
execute(command.format(gpg=gpg_key.gpg_command), sudo=ALLOW_SUDO, logger=logger)
# Update the package list (make sure it works).
logger.debug("Updating package list ..")
execute("apt-get update", sudo=SUDO_ENABLED, logger=logger)
execute("apt-get update", sudo=ALLOW_SUDO, logger=logger)

def deactivate_repository(directory):
"""
Expand All @@ -329,10 +329,10 @@ def deactivate_repository(directory):
# Remove the `sources.list' file.
sources_file = os.path.join('/etc/apt/sources.list.d', '%s.list' % sha1(directory))
logger.debug("Removing file: %s", sources_file)
execute('rm', '-f', sources_file, sudo=SUDO_ENABLED, logger=logger)
execute('rm', '-f', sources_file, sudo=ALLOW_SUDO, logger=logger)
# Update the package list (cleanup).
logger.debug("Updating package list ..")
execute("apt-get update", sudo=SUDO_ENABLED, logger=logger)
execute("apt-get update", sudo=ALLOW_SUDO, logger=logger)

def with_repository(directory, *command, **kw):
"""
Expand Down

0 comments on commit 2f3858e

Please sign in to comment.