blob: 5a86a2977f1099f5ec7ff128abd27d502445db4c [file] [log] [blame]
#!/bin/bash
# Copyright 2022 The ChromiumOS Authors.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# shellcheck disable=SC2155 # (declare and assign separately)
print_usage() {
echo "Usage: $0 path/to/chromiumos"
echo ""
echo "This command will prepare downloaded checkout and chroot for"
echo "entering by creating a user with appropriate permissions,"
echo "fixing files' ownership, mode, defining env variables."
echo "This is useful for sharing CrOS SDKs between developers when"
echo "we need to debug issues."
}
if [[ "$#" -ne 1 ]]; then
print_usage
exit 1
fi
export SOURCE_ROOT="$1"
RELATIVE_CHROOT_ROOT="${SOURCE_ROOT}/chroot"
export CHROOT_ROOT=$(realpath "${RELATIVE_CHROOT_ROOT}")
if [[ ! -d "${SOURCE_ROOT}" ]]; then
echo "Cannot access provided SOURCE_ROOT: ${SOURCE_ROOT}"
print_usage
exit 1
fi
export TARGET_USER="${USER}"
export TARGET_USER_ID="$(id -u)"
if [[ "${TARGET_USER_ID}" -eq 0 ]]; then
echo "ERROR: run this script without sudo."
exit 1
fi
export SDK_USER_ID=$(stat -c %u "${SOURCE_ROOT}")
export SDK_USER_GID=$(stat -c %g "${SOURCE_ROOT}")
export SDK_USER_GROUP=$(stat -c %G "${SOURCE_ROOT}")
if [[ "${SDK_USER_ID}" == "${TARGET_USER_ID}" ]]; then
echo "Cannot determine original sdk owner."
echo "Try deleting the checkout and re-extract the archive (with sudo)."
exit 1
fi
export LOCAL_MOUNTS_FILE="${SOURCE_ROOT}/src/scripts/.local_mounts"
export HOME_DIR_IN="/home/${TARGET_USER}"
export HOME_DIR_OUT="${CHROOT_ROOT}${HOME_DIR_IN}"
fix_permissions() {
# Files owned by root, nobody, portage, etc should stay that way.
# Files owned by original SDK owner, should change to script user.
echo "Changing owner of files with uid ${SDK_USER_ID} to ${TARGET_USER_ID}."
find -H "${SOURCE_ROOT}" -uid "${SDK_USER_ID}" -exec \
chown --no-dereference "${TARGET_USER_ID}" {} + 2>/dev/null
# If we are to do this with gid, we'd have to to enumerate unknown groups
# inside of chroot, as there are multiple. Does not seem mandatory.
}
add_user() {
echo "Adding user ${TARGET_USER}(${TARGET_USER_ID}) in chroot."
chroot "${CHROOT_ROOT}" bash -c \
"useradd -m -d ${HOME_DIR_IN} ${TARGET_USER} --uid ${TARGET_USER_ID}"
groupmod -R "${CHROOT_ROOT}" -a -U "${TARGET_USER}" portage
groupmod -R "${CHROOT_ROOT}" -a -U "${TARGET_USER}" "${SDK_USER_GROUP}"
groupmod -R "${CHROOT_ROOT}" -a -U "${TARGET_USER}" wheel
}
give_user_sudo() {
SUDOERS_FILE="${CHROOT_ROOT}/etc/sudoers"
echo "Giving ${TARGET_USER} passwordless sudo rights."
printf "\n%s ALL=(ALL) NOPASSWD: ALL\n" "${TARGET_USER}" \
| sudo tee -a "${SUDOERS_FILE}"
}
override_portage_user() {
BASHRC_FILE="${HOME_DIR_OUT}/.bashrc"
printf "\nexport PORTAGE_USERNAME=%s\n" "${TARGET_USER}" \
| sudo tee -a "${BASHRC_FILE}"
}
make_homedir_executable() {
chmod og+rx "${HOME_DIR_OUT}"
}
print_local_mounts() {
# ".local_mounts may be the reason for user issue being investigated,
# so the keep the file, but inform.
if [[ -s "${LOCAL_MOUNTS_FILE}" ]]; then
echo ".local_mounts file is detected. Missing mounts will cause warnings."
echo ".local_mounts contents:"
cat "${LOCAL_MOUNTS_FILE}"
fi
}
print_how_to_enter() {
echo
echo "To enter the prepared cros_sdk:"
echo " (outside) cd ${SOURCE_ROOT}; cros_sdk"
}
FUNCS_TO_RUN=(
fix_permissions
add_user
give_user_sudo
override_portage_user
make_homedir_executable
)
sudo -E bash -c "$(declare -f "${FUNCS_TO_RUN[@]}"); \
for f in ${FUNCS_TO_RUN[*]}; do \${f}; done"
print_local_mounts
print_how_to_enter