blob: 7429fa3085b13d511a234da74a57450d38e4c843 [file] [log] [blame]
Christopher Wiley5ccc8292015-05-28 10:01:22 -07001# Copyright 2015 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""This script installs users and groups into sysroots."""
6
Christopher Wiley5ccc8292015-05-28 10:01:22 -07007import os
8
9from chromite.lib import accounts_lib
10from chromite.lib import commandline
11from chromite.lib import cros_build_lib
12from chromite.lib import osutils
13from chromite.lib import sysroot_lib
14from chromite.lib import user_db
15
16
17ACCOUNT_DB_FILENAME = 'accounts.json'
18
19ACTION_GET_ENTRY = 'get_entry'
20ACTION_INSTALL_USER = 'install_user'
21ACTION_INSTALL_GROUP = 'install_group'
22
23USER_DB = 'passwd'
24GROUP_DB = 'group'
25
26
27def GetOptions(argv):
28 """Returns the parsed command line arguments in |argv|."""
29 parser = commandline.ArgumentParser(description=__doc__)
30 command_parsers = parser.add_subparsers(dest='action')
31
32 get_ent_parser = command_parsers.add_parser(
33 ACTION_GET_ENTRY, help='Get an entry from an account database.')
34 get_ent_parser.add_argument(
35 '--nolock', action='store_true', default=False,
36 help='Skip locking the database before reading it.')
37 get_ent_parser.add_argument('sysroot', type='path',
38 help='Path to sysroot containing the database')
39 get_ent_parser.add_argument('database', choices=(USER_DB, GROUP_DB),
40 help='Name of database to get')
41 get_ent_parser.add_argument('name', type=str, help='Name of account to get')
42
43 user_parser = command_parsers.add_parser(
44 ACTION_INSTALL_USER, help='Install a user to a sysroot')
45 user_parser.add_argument('name', type=str,
46 help='Name of user to install')
47 user_parser.add_argument('--uid', type=int,
48 help='UID of the user')
49 user_parser.add_argument('--shell', type='path',
50 help='Shell of user')
51 user_parser.add_argument('--home', type='path',
52 help='Home directory of user')
53 user_parser.add_argument('--primary_group', type=str,
54 help='Name of primary group for user')
55
56 group_parser = command_parsers.add_parser(
57 ACTION_INSTALL_GROUP, help='Install a group to a sysroot')
58 group_parser.add_argument('name', type=str,
59 help='Name of group to install.')
60 group_parser.add_argument('--gid', type=int, help='GID of the group')
61
62 # Both group and user parsers need to understand the target sysroot.
63 for sub_parser in (user_parser, group_parser):
64 sub_parser.add_argument(
65 'sysroot', type='path', help='The sysroot to install the user into')
66
67 options = parser.parse_args(argv)
68 options.Freeze()
69 return options
70
71
72def main(argv):
73 cros_build_lib.AssertInsideChroot()
74 options = GetOptions(argv)
75
76 if options.action == ACTION_GET_ENTRY:
77 db = user_db.UserDB(options.sysroot)
78 if options.database == USER_DB:
79 print(db.GetUserEntry(options.name, skip_lock=options.nolock))
80 else:
81 print(db.GetGroupEntry(options.name, skip_lock=options.nolock))
82 return 0
83
84 overlays = sysroot_lib.Sysroot(options.sysroot).GetStandardField(
85 sysroot_lib.STANDARD_FIELD_PORTDIR_OVERLAY).split()
86
87 # TODO(wiley) This process could be optimized to avoid reparsing these
88 # overlay databases each time.
89 account_db = accounts_lib.AccountDatabase()
90 for overlay_path in overlays:
91 database_path = os.path.join(overlay_path, ACCOUNT_DB_FILENAME)
92 if os.path.exists(database_path):
93 account_db.AddAccountsFromDatabase(database_path)
94
95 installed_users = user_db.UserDB(options.sysroot)
96
97 if options.action == ACTION_INSTALL_USER:
98 account_db.InstallUser(options.name, installed_users,
99 uid=options.uid, shell=options.shell,
100 homedir=options.home,
101 primary_group=options.primary_group)
102
103 homedir = account_db.users[options.name].home
104 homedir_path = os.path.join(options.sysroot, homedir)
105
106 if homedir != '/dev/null' and not os.path.exists(homedir_path):
107 osutils.SafeMakedirs(homedir_path, sudo=True)
108 uid = account_db.users[options.name].uid
Mike Frysinger45602c72019-09-22 02:15:11 -0400109 cros_build_lib.sudo_run(
Christopher Wiley5ccc8292015-05-28 10:01:22 -0700110 ['chown', '%d:%d' % (uid, uid), homedir_path], print_cmd=False)
111
112 elif options.action == ACTION_INSTALL_GROUP:
113 account_db.InstallGroup(options.name, installed_users, gid=options.gid)
114 else:
115 cros_build_lib.Die('Unsupported account type: %s' % options.account_type)