blob: c4ba3b0669f043fad9681f81f8b75a66b6210183 [file] [log] [blame]
# -*- coding: utf-8 -*-
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""This script installs users and groups into sysroots."""
from __future__ import print_function
import os
from chromite.lib import accounts_lib
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import sysroot_lib
from chromite.lib import user_db
ACCOUNT_DB_FILENAME = 'accounts.json'
ACTION_GET_ENTRY = 'get_entry'
ACTION_INSTALL_USER = 'install_user'
ACTION_INSTALL_GROUP = 'install_group'
USER_DB = 'passwd'
GROUP_DB = 'group'
def GetOptions(argv):
"""Returns the parsed command line arguments in |argv|."""
parser = commandline.ArgumentParser(description=__doc__)
command_parsers = parser.add_subparsers(dest='action')
get_ent_parser = command_parsers.add_parser(
ACTION_GET_ENTRY, help='Get an entry from an account database.')
get_ent_parser.add_argument(
'--nolock', action='store_true', default=False,
help='Skip locking the database before reading it.')
get_ent_parser.add_argument('sysroot', type='path',
help='Path to sysroot containing the database')
get_ent_parser.add_argument('database', choices=(USER_DB, GROUP_DB),
help='Name of database to get')
get_ent_parser.add_argument('name', type=str, help='Name of account to get')
user_parser = command_parsers.add_parser(
ACTION_INSTALL_USER, help='Install a user to a sysroot')
user_parser.add_argument('name', type=str,
help='Name of user to install')
user_parser.add_argument('--uid', type=int,
help='UID of the user')
user_parser.add_argument('--shell', type='path',
help='Shell of user')
user_parser.add_argument('--home', type='path',
help='Home directory of user')
user_parser.add_argument('--primary_group', type=str,
help='Name of primary group for user')
group_parser = command_parsers.add_parser(
ACTION_INSTALL_GROUP, help='Install a group to a sysroot')
group_parser.add_argument('name', type=str,
help='Name of group to install.')
group_parser.add_argument('--gid', type=int, help='GID of the group')
# Both group and user parsers need to understand the target sysroot.
for sub_parser in (user_parser, group_parser):
sub_parser.add_argument(
'sysroot', type='path', help='The sysroot to install the user into')
options = parser.parse_args(argv)
options.Freeze()
return options
def main(argv):
cros_build_lib.AssertInsideChroot()
options = GetOptions(argv)
if options.action == ACTION_GET_ENTRY:
db = user_db.UserDB(options.sysroot)
if options.database == USER_DB:
print(db.GetUserEntry(options.name, skip_lock=options.nolock))
else:
print(db.GetGroupEntry(options.name, skip_lock=options.nolock))
return 0
overlays = sysroot_lib.Sysroot(options.sysroot).GetStandardField(
sysroot_lib.STANDARD_FIELD_PORTDIR_OVERLAY).split()
# TODO(wiley) This process could be optimized to avoid reparsing these
# overlay databases each time.
account_db = accounts_lib.AccountDatabase()
for overlay_path in overlays:
database_path = os.path.join(overlay_path, ACCOUNT_DB_FILENAME)
if os.path.exists(database_path):
account_db.AddAccountsFromDatabase(database_path)
installed_users = user_db.UserDB(options.sysroot)
if options.action == ACTION_INSTALL_USER:
account_db.InstallUser(options.name, installed_users,
uid=options.uid, shell=options.shell,
homedir=options.home,
primary_group=options.primary_group)
homedir = account_db.users[options.name].home
homedir_path = os.path.join(options.sysroot, homedir)
if homedir != '/dev/null' and not os.path.exists(homedir_path):
osutils.SafeMakedirs(homedir_path, sudo=True)
uid = account_db.users[options.name].uid
cros_build_lib.sudo_run(
['chown', '%d:%d' % (uid, uid), homedir_path], print_cmd=False)
elif options.action == ACTION_INSTALL_GROUP:
account_db.InstallGroup(options.name, installed_users, gid=options.gid)
else:
cros_build_lib.Die('Unsupported account type: %s' % options.account_type)