From 44c10cd57c587a167ced7a992ab17f271a195aa0 Mon Sep 17 00:00:00 2001 From: Chmouel Boudjnah Date: Wed, 1 Oct 2014 10:14:56 +0200 Subject: [PATCH] Allow use another usename than current user Useful for boot2docker Change-Id: I1e345a8d8ed05d723f419764401ba564ee900c01 --- dox/cmd.py | 5 +++++ dox/runner.py | 15 +++++++++++++-- dox/tests/test_runner.py | 41 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 dox/tests/test_runner.py diff --git a/dox/cmd.py b/dox/cmd.py index 10c021f..1201f3f 100644 --- a/dox/cmd.py +++ b/dox/cmd.py @@ -16,6 +16,7 @@ import argparse import functools import logging +import os import sys import dox.commands @@ -65,6 +66,10 @@ def parse_args(): parser.add_argument('-n', '--noop', dest='noop', default=False, action='store_true', help="Don't actually execute commands") + parser.add_argument('--user-map', default=os.environ.get("DOX_USER_MAP"), + help='User to run the container to ' + 'format is user:uid:gid, with boot2docker use ' + 'docker:1000:10 (default to your current user)') return parser.parse_args() diff --git a/dox/runner.py b/dox/runner.py index 8da526b..4cbdf0b 100644 --- a/dox/runner.py +++ b/dox/runner.py @@ -36,6 +36,15 @@ class Runner(object): self.project = os.path.basename(os.path.abspath('.')) self.base_image_name = 'dox_%s_base' % self.project self.test_image_name = 'dox_%s_test' % self.project + self.user_map = self._get_user_mapping() + + def _get_user_mapping(self): + """Get user mapping from command line or current user.""" + if self.args.user_map: + username, uid, gid = self.args.user_map.split(':') + else: + username, uid, gid = (os.getlogin(), os.getuid(), os.getgid()) + return {'username': username, 'uid': int(uid), 'gid': int(gid)} def is_docker_installed(self): try: @@ -128,7 +137,9 @@ class Runner(object): tempd = tempfile.mkdtemp() dockerfile.append( "RUN useradd -M -U -d /src -u %(uid)s %(user)s" % dict( - uid=os.getuid(), gid=os.getgid(), user=os.getlogin())) + uid=self.user_map['uid'], + gid=self.user_map['gid'], + user=self.user_map['username'])) for add_file in commands.get_add_files(): shutil.copy(add_file, os.path.join(tempd, add_file)) dockerfile.append("ADD %s /dox/" % add_file) @@ -146,7 +157,7 @@ class Runner(object): def run_commands(self, command): self._docker_run( '--privileged=true', - '--rm', '--user=%s' % os.getlogin(), + '--rm', '--user=%s' % self.user_map['username'], '-v', "%s:/src" % os.path.abspath('.'), '-w', '/src', self.test_image_name, *command) diff --git a/dox/tests/test_runner.py b/dox/tests/test_runner.py new file mode 100644 index 0000000..6425af8 --- /dev/null +++ b/dox/tests/test_runner.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Author: Chmouel Boudjnah +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import argparse + +import mock + +import dox.runner as doxrunner +from dox.tests import base + + +class TestRunner(base.TestCase): + + def setUp(self): + super(TestRunner, self).setUp() + + def test_user_mapping(self): + dr = doxrunner.Runner(argparse.Namespace(user_map='foo:100:10')) + self.assertEqual('foo', dr.user_map['username']) + self.assertEqual(100, dr.user_map['uid']) + self.assertEqual(10, dr.user_map['gid']) + + @mock.patch('os.getuid', return_value=12345) + @mock.patch('os.getgid', return_value=67890) + @mock.patch('os.getlogin', return_value='toto') + def test_user_mapping_default(self, os_uid, os_gid, os_username): + dr = doxrunner.Runner(argparse.Namespace(user_map=None)) + self.assertEqual('toto', dr.user_map['username']) + self.assertEqual(12345, dr.user_map['uid']) + self.assertEqual(67890, dr.user_map['gid'])