diff --git a/common.sh b/common.sh index 6c59ea07b0..e704c787d9 100644 --- a/common.sh +++ b/common.sh @@ -421,6 +421,16 @@ setup_board_warning() { echo } +is_nfs() { + [ "$(stat -f -L -c %T "$1")" = "nfs" ] +} + +warn_if_nfs() { + if is_nfs "$1"; then + warn "$1 is on NFS. This is unsupported." + fi +} + # Enter a chroot and restart the current script if needed restart_in_chroot_if_needed() { # NB: Pass in ARGV: restart_in_chroot_if_needed "$@" @@ -546,6 +556,13 @@ user_clobber() { install -m644 -o ${SUDO_UID} -g ${SUDO_GID} /dev/stdin "$@" } +# Copies the specified file owned by the user to the specified location. +# If the copy fails as root (e.g. due to root_squash and NFS), retry the copy +# with the user's account before failing. +user_cp() { + cp -p "$@" 2>/dev/null || sudo -u ${SUDO_USER} -- cp -p "$@" +} + # Appends stdin to the given file name as the sudo user. # # $1 - The output file name. diff --git a/sdk_lib/enter_chroot.sh b/sdk_lib/enter_chroot.sh index 8e44686854..f200335565 100755 --- a/sdk_lib/enter_chroot.sh +++ b/sdk_lib/enter_chroot.sh @@ -139,7 +139,7 @@ copy_ssh_config() { local filter local option - if [ ! -f "${sshc}" ]; then + if ! user_cp "${sshc}" "${chroot_ssh_dir}/config.orig" 2>/dev/null; then return # Nothing to copy. fi @@ -152,7 +152,7 @@ copy_ssh_config() { fi done - sed "/^.*\(${filter}\).*$/d" "${sshc}" | \ + sed "/^.*\(${filter}\).*$/d" "${chroot_ssh_dir}/config.orig" | \ user_clobber "${chroot_ssh_dir}/config" } @@ -285,9 +285,15 @@ setup_env() { if [ -n "${SSH_AUTH_SOCK}" -a -d "${SUDO_HOME}/.ssh" ]; then TARGET_DIR="${FLAGS_chroot}/home/${SUDO_USER}/.ssh" user_mkdir "${TARGET_DIR}" - # Ignore errors as some people won't have these files to copy. - cp -p "${SUDO_HOME}"/.ssh/{known_hosts,*.pub} "${TARGET_DIR}/" \ - 2>/dev/null || : + ( + # Only copy ~/.ssh/{known_hosts,*.pub} if they exist. Since we set + # nullglob, this needs to happen within a subshell. + shopt -s nullglob + files=("${SUDO_HOME}"/.ssh/{known_hosts,*.pub}) + if [[ ${#files[@]} -gt 0 ]]; then + user_cp "${files[@]}" "${TARGET_DIR}/" + fi + ) copy_ssh_config "${TARGET_DIR}" chown -R ${SUDO_UID}:${SUDO_GID} "${TARGET_DIR}" diff --git a/sdk_lib/make_chroot.sh b/sdk_lib/make_chroot.sh index 7ca219b749..258619c94f 100755 --- a/sdk_lib/make_chroot.sh +++ b/sdk_lib/make_chroot.sh @@ -301,7 +301,7 @@ EOF # Copy .gitconfig into chroot so repo and git can be used from inside. # This is required for repo to work since it validates the email address. echo "Copying ~/.gitconfig into chroot" - cp -p "${SUDO_HOME}/.gitconfig" "$FLAGS_chroot/home/${SUDO_USER}/" + user_cp "${SUDO_HOME}/.gitconfig" "$FLAGS_chroot/home/${SUDO_USER}/" fi # If the user didn't set up their username in their gitconfig, look @@ -513,3 +513,5 @@ delete the chroot cleanly, use: $ cros_sdk --delete $CHROOT_EXAMPLE_OPT EOF + +warn_if_nfs "${SUDO_HOME}"