From a7f2129d64ca15bc06eee4b4a1ddbab08548215d Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Thu, 12 Oct 2023 17:57:49 +0900 Subject: [PATCH] Enable to share single image with multiple users. Create user in run-time to use same UDI/GID as host user. See https://qiita.com/ktamido/items/8d7b7eddbd88bd1bbf99 --- jsk_unitree_robot/cross/build_ros1.sh | 13 ++--------- .../cross/build_ros1_dependencies.sh | 14 +++-------- jsk_unitree_robot/cross/build_user.sh | 16 ++++--------- .../cross/docker/Dockerfile_ros1 | 12 ++++------ jsk_unitree_robot/cross/docker/entrypoint.sh | 23 +++++++++++++++++++ .../cross/prepare_requirements_ros1.sh | 3 ++- jsk_unitree_robot/cross/run_user.sh | 14 +++-------- 7 files changed, 41 insertions(+), 54 deletions(-) create mode 100644 jsk_unitree_robot/cross/docker/entrypoint.sh diff --git a/jsk_unitree_robot/cross/build_ros1.sh b/jsk_unitree_robot/cross/build_ros1.sh index fbd2a03d13..20e660d3e4 100755 --- a/jsk_unitree_robot/cross/build_ros1.sh +++ b/jsk_unitree_robot/cross/build_ros1.sh @@ -48,24 +48,15 @@ JSK_ROBOT_UTILS="jsk_network_tools" DIAGNOSTIC_AGGREGATOR="diagnostic_aggregator" # jsk_XXX_startup usually depends on diagnostic_aggregator PR2EUS="pr2eus" -case ${OSTYPE} in - linux*) - OPTIONS="-u $(id -u $USER)" - ;; - darwin*) - OPTIONS="" - ;; -esac - docker run -it --rm \ - ${OPTIONS} \ + -e HOST_UID=$(id -u) -e HOST_GID=$(id -g) \ -e INSTALL_ROOT=${INSTALL_ROOT} \ -e MAKEFLAGS=${MAKEFLAGS} \ -v ${HOST_INSTALL_ROOT}/ros1_dependencies:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies:ro \ -v ${HOST_INSTALL_ROOT}/ros1_dependencies_setup.bash:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies_setup.bash:ro \ -v ${HOST_INSTALL_ROOT}/ros1_inst:/opt/jsk/${INSTALL_ROOT}/ros1_inst:rw \ -v ${PWD}/${SOURCE_ROOT}:/home/user/${SOURCE_ROOT}:rw \ - ros1-unitree:${TARGET_MACHINE} \ + ${IMAGE_NAME}:${TARGET_MACHINE} \ bash -c "\ source /opt/jsk/System/ros1_dependencies_setup.bash && \ source /opt/ros/melodic/setup.bash && \ diff --git a/jsk_unitree_robot/cross/build_ros1_dependencies.sh b/jsk_unitree_robot/cross/build_ros1_dependencies.sh index 8813b24958..079d34cd14 100755 --- a/jsk_unitree_robot/cross/build_ros1_dependencies.sh +++ b/jsk_unitree_robot/cross/build_ros1_dependencies.sh @@ -1,5 +1,6 @@ #!/bin/bash +IMAGE_NAME="${IMAGE_NAME:-ros1-unitree}" TARGET_MACHINE="${TARGET_MACHINE:-arm64v8}" HOST_INSTALL_ROOT="${BASE_ROOT:-${PWD}}/"${TARGET_MACHINE}_System INSTALL_ROOT=System @@ -26,24 +27,15 @@ cp repos/ros1_dependencies.repos ${SOURCE_ROOT}/ mkdir -p ${HOST_INSTALL_ROOT}/Python cp repos/go1_requirements.txt ${SOURCE_ROOT}/go1_requirements.txt -case ${OSTYPE} in - linux*) - OPTIONS="-u $(id -u $USER)" - ;; - darwin*) - OPTIONS="" - ;; -esac - docker run -it --rm \ - ${OPTIONS} \ + -e HOST_UID=$(id -u) -e HOST_GID=$(id -g) \ -e INSTALL_ROOT=${INSTALL_ROOT} \ -e MAKEFLAGS=${MAKEFLAGS} \ -v ${PWD}/ros1_dependencies_build_scripts:/home/user/ros1_dependencies_build_scripts:ro \ -v ${PWD}/${SOURCE_ROOT}:/home/user/ros1_dependencies_sources:rw \ -v ${HOST_INSTALL_ROOT}/ros1_dependencies:/opt/jsk//${INSTALL_ROOT}/ros1_dependencies:rw \ -v ${HOST_INSTALL_ROOT}/Python:/opt/jsk/${INSTALL_ROOT}/Python:rw \ - ros1-unitree:${TARGET_MACHINE} \ + ${IMAGE_NAME}:${TARGET_MACHINE} \ bash -c "\ set -xeuf -o pipefail && \ cd /home/user/ros1_dependencies_sources && \ diff --git a/jsk_unitree_robot/cross/build_user.sh b/jsk_unitree_robot/cross/build_user.sh index 956147f133..b692debab2 100755 --- a/jsk_unitree_robot/cross/build_user.sh +++ b/jsk_unitree_robot/cross/build_user.sh @@ -1,5 +1,6 @@ #!/bin/bash +IMAGE_NAME="${IMAGE_NAME:-ros1-unitree}" TARGET_MACHINE="${TARGET_MACHINE:-arm64v8}" HOST_INSTALL_ROOT="${BASE_ROOT:-${PWD}}/"${TARGET_MACHINE}_System INSTALL_ROOT=System @@ -39,20 +40,11 @@ done # check if /proc/sys/fs/binfmt_misc/qemu-* is updated # See https://github.com/k-okada/jsk_robot/issues/61 -docker run -it --rm ros1-unitree:${TARGET_MACHINE} bash -c 'exit' || docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - -case ${OSTYPE} in - linux*) - OPTIONS="-u $(id -u $USER)" - ;; - darwin*) - OPTIONS="" - ;; -esac +docker run -it --rm -e HOST_UID=$(id -u) -e HOST_GID=$(id -g) ${IMAGE_NAME}:${TARGET_MACHINE} bash -c 'exit' || docker run --rm --privileged multiarch/qemu-user-static --reset -p yes # run on docker docker run -it --rm \ - ${OPTIONS} \ + -e HOST_UID=$(id -u) -e HOST_GID=$(id -g) \ -e INSTALL_ROOT=${INSTALL_ROOT} \ -v ${HOST_INSTALL_ROOT}/ros1_dependencies:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies:ro \ -v ${HOST_INSTALL_ROOT}/Python:/opt/jsk/${INSTALL_ROOT}/Python:ro \ @@ -61,7 +53,7 @@ docker run -it --rm \ -v ${HOST_INSTALL_ROOT}/system_setup.bash:/opt/jsk/${INSTALL_ROOT}/system_setup.bash:ro \ -v ${PWD}/${SOURCE_ROOT}:/opt/jsk/User:rw \ -v ${PWD}/rosinstall_generator_unreleased.py:/home/user/rosinstall_generator_unreleased.py:ro \ - ros1-unitree:${TARGET_MACHINE} \ + ${IMAGE_NAME}:${TARGET_MACHINE} \ bash -c "\ source /opt/jsk/System/system_setup.bash && \ env && \ diff --git a/jsk_unitree_robot/cross/docker/Dockerfile_ros1 b/jsk_unitree_robot/cross/docker/Dockerfile_ros1 index 7de759b9d3..dd2ff90fdd 100644 --- a/jsk_unitree_robot/cross/docker/Dockerfile_ros1 +++ b/jsk_unitree_robot/cross/docker/Dockerfile_ros1 @@ -31,19 +31,15 @@ RUN git clone https://github.com/k-okada/rosinstall_generator /tmp/rosinstall_ge RUN pip install /tmp/rosinstall_generator RUN apt install -y python3-vcstool # -# Setup Users +# add tool for users # -ARG UID=1000 RUN apt-get install -y sudo -RUN useradd --uid $UID -ms /bin/bash -G sudo user -RUN newgrp -RUN echo user:user | chpasswd # # Remove packages is not found on 161 # RUN dpkg -r --force-depends cython gir1.2-gstreamer-1.0 libtinyxml-dev python-attr python-autobahn python-automat python-cbor python-concurrent.futures python-constantly python-constantly python-incremental python-lz4 python-nacl python-pyasn1 python-pyasn1-modules python-qrcode python-service-identity python-snappy python-trie python-trollius python-twisted-bin python-twisted-core python-twisted python-txaio python-ubjson python-u-msgpack python-wsaccel python-zope.interface # # -# -WORKDIR /home/user -USER user +ADD entrypoint.sh / +RUN chmod +x /entrypoint.sh +ENTRYPOINT ["/entrypoint.sh"] diff --git a/jsk_unitree_robot/cross/docker/entrypoint.sh b/jsk_unitree_robot/cross/docker/entrypoint.sh new file mode 100644 index 0000000000..3eb14445d9 --- /dev/null +++ b/jsk_unitree_robot/cross/docker/entrypoint.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +function fail { + printf '\033[31m%s\033[0m\n' "$1" >&2 ## Send message to stderr. + exit "${2-1}" ## Return a code specified by $2, or 1 by default. +} +[ -z "${HOST_UID}" ] && fail "ERROR: HOST_UID is requried, add '-e HOST_UID=$(id -u)' to your docker commandline option" +[ -z "${HOST_GID}" ] && fail "ERROR: HOST_GID is requried, add '-e HOST_GID=$(id -g)' to your docker commandline option" + +# create user with same UID as the host user +# -g The numerical value of the group's ID. +groupadd -g $HOST_GID user +# -u The numerical value of the user's ID. +# -o Allow the creation of a user account with a duplicate (non-unique) UID. +# -m Create the user's home directory if it does not exist. +# -g The group name or number of the user's initial login group. +# -s The name of the user's login shell. +useradd -u $HOST_UID -o -m -g $HOST_GID -s /usr/bin user +export HOME=/home/user +chown $HOST_UID:$HOST_GID $HOME +cd $HOME + +runuser -u user -- "$@" diff --git a/jsk_unitree_robot/cross/prepare_requirements_ros1.sh b/jsk_unitree_robot/cross/prepare_requirements_ros1.sh index 110d88651c..2aae00838c 100755 --- a/jsk_unitree_robot/cross/prepare_requirements_ros1.sh +++ b/jsk_unitree_robot/cross/prepare_requirements_ros1.sh @@ -1,5 +1,6 @@ #!/bin/bash +IMAGE_NAME="${IMAGE_NAME:-ros1-unitree}" TARGET_MACHINE="${TARGET_MACHINE:-arm64v8}" HOST_INSTALL_ROOT="${BASE_ROOT:-${PWD}}/"System INSTALL_ROOT=System @@ -14,4 +15,4 @@ if [ -e /proc/sys/fs/binfmt_misc/qemu-aarch64 ] && [ ! "$(docker images -q mult docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi -docker buildx build $@ --progress plain -t ros1-unitree:${TARGET_MACHINE} --build-arg TARGET_MACHINE=${TARGET_MACHINE} --build-arg UID=$(id -u $USER) -f docker/Dockerfile_ros1 docker/ 2>&1 | tee ${TARGET_MACHINE}_prepare_requirements_ros1.log +docker buildx build $@ --progress plain -t ${IMAGE_NAME}:${TARGET_MACHINE} --build-arg TARGET_MACHINE=${TARGET_MACHINE} --build-arg UID=$(id -u $USER) -f docker/Dockerfile_ros1 docker/ 2>&1 | tee ${TARGET_MACHINE}_prepare_requirements_ros1.log diff --git a/jsk_unitree_robot/cross/run_user.sh b/jsk_unitree_robot/cross/run_user.sh index b4c80ed932..2b6acbc48e 100755 --- a/jsk_unitree_robot/cross/run_user.sh +++ b/jsk_unitree_robot/cross/run_user.sh @@ -1,5 +1,6 @@ #!/bin/bash +IMAGE_NAME="${IMAGE_NAME:-ros1-unitree}" TARGET_MACHINE="${TARGET_MACHINE:-arm64v8}" HOST_INSTALL_ROOT="${BASE_ROOT:-${PWD}}/"${TARGET_MACHINE}_System INSTALL_ROOT=System @@ -7,19 +8,10 @@ SOURCE_ROOT=${TARGET_MACHINE}_User set -xeuf -o pipefail -case ${OSTYPE} in - linux*) - OPTIONS="-u $(id -u $USER)" - ;; - darwin*) - OPTIONS="" - ;; -esac - # -v ${PWD}/${TARGET_MACHINE}_ws_system:/home/user/${TARGET_MACHINE}_ws_system:rw \ # run on docker docker run -it --rm \ - ${OPTIONS} \ + -e HOST_UID=$(id -u) -e HOST_GID=$(id -g) \ -e INSTALL_ROOT=${INSTALL_ROOT} \ -v ${HOST_INSTALL_ROOT}/ros1_dependencies:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies:ro \ -v ${HOST_INSTALL_ROOT}/Python:/opt/jsk/${INSTALL_ROOT}/Python:ro \ @@ -27,7 +19,7 @@ docker run -it --rm \ -v ${HOST_INSTALL_ROOT}/ros1_dependencies_setup.bash:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies_setup.bash:ro \ -v ${HOST_INSTALL_ROOT}/system_setup.bash:/opt/jsk/${INSTALL_ROOT}/system_setup.bash:ro \ -v ${PWD}/${SOURCE_ROOT}:/opt/jsk/User:rw \ - ros1-unitree:${TARGET_MACHINE} \ + ${IMAGE_NAME}:${TARGET_MACHINE} \ bash -c "echo 'source /opt/jsk/User/user_setup.bash; env; cd /opt/jsk/User' > ~/.bashrc; exec \"\$0\"" # https://stackoverflow.com/questions/59814742/docker-run-bash-init-file