Bug 1295380 - Teach run-task to chown paths; r=dustin
It is common for tasks to chown paths before permissions are dropped
from root:root. This commonly occurs when Docker volumes/caches are
involved since they are default owned by root:root and not writable
by any other user.
Since this will likely be a common request, add the functionality to
run-task.
MozReview-Commit-ID: AHmSfY5Ce0S
--- a/testing/docker/recipes/run-task
+++ b/testing/docker/recipes/run-task
@@ -151,16 +151,23 @@ def main(args):
task_args = args[i + 1:]
except ValueError:
our_args = args
task_args = []
parser = argparse.ArgumentParser()
parser.add_argument('--user', default='worker', help='user to run as')
parser.add_argument('--group', default='worker', help='group to run as')
+ # We allow paths to be chowned by the --user:--group before permissions are
+ # dropped. This is often necessary for caches/volumes, since they default
+ # to root:root ownership.
+ parser.add_argument('--chown', action='append',
+ help='Directory to chown to --user:--group')
+ parser.add_argument('--chown-recursive', action='append',
+ help='Directory to recursively chown to --user:--group')
parser.add_argument('--vcs-checkout',
help='Directory where Gecko checkout should be created')
args = parser.parse_args(our_args)
try:
user = pwd.getpwnam(args.user)
except KeyError:
@@ -175,16 +182,33 @@ def main(args):
return 1
uid = user.pw_uid
gid = group.gr_gid
# Find all groups to which this user is a member.
gids = [g.gr_gid for g in grp.getgrall() if args.group in g.gr_mem]
+ # Change ownership of requested paths.
+ # FUTURE: parse argument values for user/group if we don't want to
+ # use --user/--group.
+ for path in args.chown or []:
+ print_line(b'chown', b'changing ownership of %s to %s:%s\n' % (
+ path, user.pw_name, group.gr_name))
+ os.chown(path, uid, gid)
+
+ for path in args.chown_recursive or []:
+ print_line(b'chown', b'recursively changing ownership of %s to %s:%s\n' %
+ (path, user.pw_name, group.gr_name))
+ for root, dirs, files in os.walk(path):
+ for d in dirs:
+ os.chown(os.path.join(root, d), uid, gid)
+ for f in files:
+ os.chown(os.path.join(root, f), uid, gid)
+
checkout = args.vcs_checkout
if checkout:
# Ensure the directory for the source checkout exists.
try:
os.makedirs(os.path.dirname(checkout))
except OSError as e:
if e.errno != errno.EEXIST:
raise