diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 1423d55cb..2e982ab7b 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -16,6 +16,8 @@ API changes Bug fixes --------- +- Prevent building the image as root if --user-id and --user-name are not specified + in :pr:`676` by :user:`Xarthisius`. Version 0.9.0 diff --git a/repo2docker/app.py b/repo2docker/app.py index 7fcd170e6..d951094e6 100644 --- a/repo2docker/app.py +++ b/repo2docker/app.py @@ -8,6 +8,7 @@ python -m repo2docker https://github.com/you/your-repo """ import argparse +import errno import json import sys import logging @@ -650,6 +651,19 @@ def build(self): extra=dict(phase='building')) if not self.dry_run: + if self.user_id == 0: + self.log.error( + 'Root as the primary user in the image is not permitted.\n' + ) + self.log.info( + "The uid and the username of the user invoking repo2docker " + "is used to create a mirror account in the image by default. " + "To override that behavior pass --user-id and " + " --user-name to repo2docker.\n" + "Please see repo2docker --help for more details.\n" + ) + sys.exit(errno.EPERM) + build_args = { 'NB_USER': self.user_name, 'NB_UID': str(self.user_id), diff --git a/tests/unit/test_app.py b/tests/unit/test_app.py index ecc786094..4f43d88ae 100644 --- a/tests/unit/test_app.py +++ b/tests/unit/test_app.py @@ -1,3 +1,5 @@ +import errno +import pytest from tempfile import TemporaryDirectory from unittest.mock import patch @@ -101,4 +103,26 @@ def test_run_kwargs(repo_with_content): containers.run.assert_called_once() args, kwargs = containers.run.call_args assert 'somekey' in kwargs - assert kwargs['somekey'] == "somevalue" \ No newline at end of file + assert kwargs['somekey'] == "somevalue" + + +def test_root_not_allowed(): + with TemporaryDirectory() as src, patch('os.geteuid') as geteuid: + geteuid.return_value = 0 + argv = [src] + app = make_r2d(argv) + with pytest.raises(SystemExit) as exc: + app.build() + assert exc.code == errno.EPERM + + app = Repo2Docker( + repo=src, + user_id=1000, + user_name='jovyan', + run=False, + ) + app.initialize() + with patch.object(docker.APIClient, 'build') as builds: + builds.return_value = [] + app.build() + builds.assert_called_once()