make_chroot: Add workspace support.
In certain circumstances the workspace folder has user/group ownership
that doesn't carry properly into the chroot. This CL makes sure that if
a workspace is specified, the chroot user is added to the group that
owns the workspace.
It also changes the chroot primary group to match the primary group
outside the chroot; previously it was hardcoded to eng/5000.
BUG=brillo:861
TEST=mkdir workspace
sudo chgrp google workspace
cd workspace
touch workspace-config.json
brillo sdk --update <version>
brillo chroot
"google" group now exists in the chroot and contains the user.
CQ-DEPEND=CL:269530
Change-Id: I9b47c133b4b86412af55143375c774b96416d495
Reviewed-on: https://chromium-review.googlesource.com/269521
Reviewed-by: David Pursell <dpursell@chromium.org>
Commit-Queue: David Pursell <dpursell@chromium.org>
Trybot-Ready: David Pursell <dpursell@chromium.org>
Tested-by: David Pursell <dpursell@chromium.org>
diff --git a/sdk_lib/make_chroot.sh b/sdk_lib/make_chroot.sh
index 2817d6c..7d763db 100755
--- a/sdk_lib/make_chroot.sh
+++ b/sdk_lib/make_chroot.sh
@@ -43,6 +43,8 @@
"Use the stage3 with the given date."
DEFINE_string stage3_path "" \
"Use the stage3 located on this path."
+DEFINE_string workspace_root "" \
+ "The root of your workspace."
DEFINE_string cache_dir "" "Directory to store caches within."
# Parse command line flags.
@@ -52,7 +54,7 @@
check_flags_only_and_allow_null_arg "$@" && set --
CROS_LOG_PREFIX=cros_sdk:make_chroot
-SUDO_HOME=$(eval echo ~${SUDO_USER})
+SUDO_HOME=$(eval echo ~"${SUDO_USER}")
# Set the right umask for chroot creation.
umask 022
@@ -68,8 +70,19 @@
. "${SCRIPT_ROOT}"/sdk_lib/make_conf_util.sh
+PRIMARY_GROUP=$(id -g -n "${SUDO_USER}")
+PRIMARY_GROUP_ID=$(id -g "${SUDO_USER}")
+
FULLNAME="ChromeOS Developer"
-DEFGROUPS="eng,adm,cdrom,floppy,audio,video,portage"
+DEFGROUPS="${PRIMARY_GROUP},adm,cdrom,floppy,audio,video,portage"
+
+# If a workspace was specified we want to make sure the user is in its group.
+if [[ -n "${FLAGS_workspace_root}" ]]; then
+ WORKSPACE_GROUP=$(stat -c "%G" "${FLAGS_workspace_root}")
+ WORKSPACE_GROUP_ID=$(getent group "${WORKSPACE_GROUP}" | cut -d: -f3)
+ # Duplicates in DEFGROUPS are fine, the useradd call handles them properly.
+ DEFGROUPS+=",${WORKSPACE_GROUP}"
+fi
USEPKG=""
if [[ $FLAGS_usepkg -eq $FLAGS_TRUE ]]; then
@@ -109,7 +122,7 @@
# found inside of the chroot since the environment outside of the chroot
# might be insufficient (like distros with merged /bin /sbin and /usr).
bare_chroot() {
- PATH=/bin:/sbin:/usr/bin:/usr/sbin:${PATH} \
+ PATH="/bin:/sbin:/usr/bin:/usr/sbin:${PATH}" \
chroot "${FLAGS_chroot}" "$@"
}
@@ -140,15 +153,26 @@
ln -sf /usr/share/zoneinfo/PST8PDT "${FLAGS_chroot}/etc/localtime"
fi
info "Adding user/group..."
+ # Add the necessary groups to the chroot.
+ # Duplicate GIDs are allowed here in order to ensure that the required
+ # groups are the same inside and outside the chroot.
+ # TODO(dpursell): Handle when PRIMARY_GROUP exists in the chroot already
+ # with a different GID; groupadd will not create the new GID in that case.
+ bare_chroot groupadd -f -o -g "${PRIMARY_GROUP_ID}" "${PRIMARY_GROUP}"
+ if [[ -n "${WORKSPACE_GROUP}" ]]; then
+ # groupadd -f is fine (has no effect) if this group+ID already exists.
+ # TODO(dpursell): Handle when WORKSPACE_GROUP exists in the chroot already
+ # with a different GID; groupadd will not create the new GID in that case.
+ bare_chroot groupadd -f -o -g "${WORKSPACE_GROUP_ID}" "${WORKSPACE_GROUP}"
+ fi
# Add ourselves as a user inside the chroot.
- bare_chroot groupadd -g 5000 eng
# We need the UID to match the host user's. This can conflict with
# a particular chroot UID. At the same time, the added user has to
# be a primary user for the given UID for sudo to work, which is
# determined by the order in /etc/passwd. Let's put ourselves on top
# of the file.
- bare_chroot useradd -o -G ${DEFGROUPS} -g eng -u ${SUDO_UID} -s \
- /bin/bash -m -c "${FULLNAME}" ${SUDO_USER}
+ bare_chroot useradd -o -G "${DEFGROUPS}" -g "${PRIMARY_GROUP}" \
+ -u "${SUDO_UID}" -s /bin/bash -m -c "${FULLNAME}" "${SUDO_USER}"
# Because passwd generally isn't sorted and the entry ended up at the
# bottom, it is safe to just take it and move it to top instead.
sed -e '1{h;d};$!{H;d};$G' -i "${FLAGS_chroot}/etc/passwd"
@@ -242,9 +266,9 @@
# We rely on 'env-update' getting called below.
target="${FLAGS_chroot}/etc/env.d/99chromiumos"
cat <<EOF > "${target}"
-PATH=${CHROOT_TRUNK_DIR}/chromite/bin:${DEPOT_TOOLS_DIR}
+PATH="${CHROOT_TRUNK_DIR}/chromite/bin:${DEPOT_TOOLS_DIR}"
CROS_WORKON_SRCROOT="${CHROOT_TRUNK_DIR}"
-PORTAGE_USERNAME=${SUDO_USER}
+PORTAGE_USERNAME="${SUDO_USER}"
EOF
# TODO(zbehan): Configure stuff that is usually configured in postinst's,
@@ -286,19 +310,19 @@
# Automatically change to scripts directory.
echo 'cd ${CHROOT_CWD:-~/trunk/src/scripts}' \
- | user_append "$FLAGS_chroot/home/${SUDO_USER}/.bash_profile"
+ | user_append "${FLAGS_chroot}/home/${SUDO_USER}/.bash_profile"
# Enable bash completion for build scripts.
echo ". ~/trunk/src/scripts/bash_completion" \
- | user_append "$FLAGS_chroot/home/${SUDO_USER}/.bashrc"
+ | user_append "${FLAGS_chroot}/home/${SUDO_USER}/.bashrc"
if [[ "${SUDO_USER}" = "chrome-bot" && -d "${SUDO_HOME}/.ssh" ]]; then
# Copy ssh keys, so chroot'd chrome-bot can scp files from chrome-web.
user_cp -rp "${SUDO_HOME}/.ssh" "$FLAGS_chroot/home/${SUDO_USER}/"
fi
- if [[ -f ${SUDO_HOME}/.cros_chroot_init ]]; then
- sudo -u ${SUDO_USER} -- /bin/bash "${SUDO_HOME}/.cros_chroot_init" \
+ if [[ -f "${SUDO_HOME}/.cros_chroot_init" ]]; then
+ sudo -u "${SUDO_USER}" -- /bin/bash "${SUDO_HOME}/.cros_chroot_init" \
"${FLAGS_chroot}"
fi
}
@@ -325,7 +349,7 @@
# Pass proxy variables into the environment.
for type in http ftp all; do
- value=$(env | grep ${type}_proxy || true)
+ value=$(env | grep "${type}_proxy" || true)
if [ -n "${value}" ]; then
CHROOT_PASSTHRU+=("$value")
fi
@@ -335,13 +359,13 @@
mkdir -p "$FLAGS_chroot"
echo
-if [[ -f ${CHROOT_STATE} ]]; then
+if [[ -f "${CHROOT_STATE}" ]]; then
info "stage3 already set up. Skipping..."
-elif [[ -z ${FLAGS_stage3_path} ]]; then
+elif [[ -z "${FLAGS_stage3_path}" ]]; then
die_notrace "Please use --stage3_path when bootstrapping"
else
info "Unpacking stage3..."
- case ${FLAGS_stage3_path} in
+ case "${FLAGS_stage3_path}" in
*.tbz2|*.tar.bz2) DECOMPRESS=$(type -p pbzip2 || echo bzip2) ;;
*.tar.xz) DECOMPRESS="xz" ;;
*) die "Unknown tarball compression: ${FLAGS_stage3_path}" ;;
@@ -353,7 +377,7 @@
# Ensure that we properly detect when we are inside the chroot.
# We'll force this to the latest version at the end as needed.
-if [[ ! -e ${CHROOT_VERSION} ]]; then
+if [[ ! -e "${CHROOT_VERSION}" ]]; then
echo "0" > "${CHROOT_VERSION}"
fi
@@ -402,7 +426,7 @@
early_enter_chroot emerge -uNv --quiet portage
# Clear out openrc if it's installed as we don't want it.
-if [[ -e ${FLAGS_chroot}/usr/share/openrc ]]; then
+if [[ -e "${FLAGS_chroot}/usr/share/openrc" ]]; then
info "Uninstalling openrc"
early_enter_chroot env CLEAN_DELAY=0 emerge -qC sys-apps/openrc
# Now update baselayout to get our functions.sh. The unmerge
@@ -430,11 +454,11 @@
done
info "Updating host toolchain"
-if [[ ! -e ${FLAGS_chroot}/usr/bin/crossdev ]]; then
+if [[ ! -e "${FLAGS_chroot}/usr/bin/crossdev" ]]; then
early_enter_chroot $EMERGE_CMD -uNv crossdev
fi
TOOLCHAIN_ARGS=( --deleteold )
-if [[ ${FLAGS_usepkg} -eq ${FLAGS_FALSE} ]]; then
+if [[ "${FLAGS_usepkg}" == "${FLAGS_FALSE}" ]]; then
TOOLCHAIN_ARGS+=( --nousepkg )
fi
# Note: early_enter_chroot executes as root.
@@ -456,13 +480,13 @@
# Skip toolchain update because it already happened above, and the chroot is
# not ready to emerge all cross toolchains.
UPDATE_ARGS=( --skip_toolchain_update )
-if [[ ${FLAGS_usepkg} -eq ${FLAGS_TRUE} ]]; then
+if [[ "${FLAGS_usepkg}" == "${FLAGS_TRUE}" ]]; then
UPDATE_ARGS+=( --usepkg )
else
UPDATE_ARGS+=( --nousepkg )
fi
if [[ "${FLAGS_jobs}" -ne -1 ]]; then
- UPDATE_ARGS+=( --jobs=${FLAGS_jobs} )
+ UPDATE_ARGS+=( --jobs="${FLAGS_jobs}" )
fi
enter_chroot "${CHROOT_TRUNK_DIR}/src/scripts/update_chroot" "${UPDATE_ARGS[@]}"