blob: 3769b0eb28b02be8300f5475b1bd4834a5531df3 [file] [log] [blame]
# 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.')
'--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):
'sysroot', type='path', help='The sysroot to install the user into')
options = parser.parse_args(argv)
return options
def main(argv):
options = GetOptions(argv)
if options.action == ACTION_GET_ENTRY:
db = user_db.UserDB(options.sysroot)
if options.database == USER_DB:
print(db.GetUserEntry(, skip_lock=options.nolock))
print(db.GetGroupEntry(, skip_lock=options.nolock))
return 0
overlays = sysroot_lib.Sysroot(options.sysroot).GetStandardField(
# 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):
installed_users = user_db.UserDB(options.sysroot)
if options.action == ACTION_INSTALL_USER:
account_db.InstallUser(, installed_users,
homedir = account_db.users[].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[].uid
['chown', '%d:%d' % (uid, uid), homedir_path], print_cmd=False)
elif options.action == ACTION_INSTALL_GROUP:
account_db.InstallGroup(, installed_users, gid=options.gid)
cros_build_lib.Die('Unsupported account type: %s' % options.account_type)