From dd540366b5b0437c675db9613dd9f53203620c9f Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 21 Nov 2024 16:54:08 -0500 Subject: [PATCH] docker_* helpers: pass usb host controllers to docker only if usb devices are connected, unify, bugfixes Signed-off-by: Thierry Laurion --- docker_latest.sh | 47 ++++++++++++++---------- docker_local_dev.sh | 87 +++++++++++++++++++++++++-------------------- docker_repro.sh | 50 +++++++++++++++----------- 3 files changed, 105 insertions(+), 79 deletions(-) diff --git a/docker_latest.sh b/docker_latest.sh index e831b058..f073e5a7 100755 --- a/docker_latest.sh +++ b/docker_latest.sh @@ -2,26 +2,27 @@ # Inform the user that the latest published Docker image is being used echo "Using the latest Docker image: tlaurion/heads-dev-env:latest" +DOCKER_IMAGE="tlaurion/heads-dev-env:latest" # Function to display usage information usage() { - echo "Usage: $0 [OPTIONS] -- [COMMAND]" - echo "Options:" - echo " CPUS=N Set the number of CPUs" - echo " V=1 Enable verbose mode" - echo "Command:" - echo " The command to run inside the Docker container, e.g., make BOARD=BOARD_NAME" + echo "Usage: $0 [OPTIONS] -- [COMMAND]" + echo "Options:" + echo " CPUS=N Set the number of CPUs" + echo " V=1 Enable verbose mode" + echo "Command:" + echo " The command to run inside the Docker container, e.g., make BOARD=BOARD_NAME" } # Function to kill GPG toolstack related processes using USB devices kill_usb_processes() { - echo "Killing any GPG toolstack related processes on host currently using USB devices..." - sudo lsof /dev/bus/usb/00*/0* 2>/dev/null | awk 'NR>1 {print $2}' | xargs -r ps -p | grep -E 'scdaemon|pcscd' | awk '{print $1}' | xargs -r sudo kill -9 - if [ $? -ne 0 ]; then - echo "Failed to kill GPG toolstack related processes using USB devices. Please run the following command manually:" - echo "sudo lsof /dev/bus/usb/00*/0* | awk 'NR>1 {print \$2}' | xargs -r ps -p | grep -E 'scdaemon|pcscd' | awk '{print \$1}' | xargs -r sudo kill -9" - exit 1 - fi + # check if scdaemon or pcscd processes are using USB devices + if [ -d /dev/bus/usb ]; then + if sudo lsof /dev/bus/usb/00*/0* 2>/dev/null | awk 'NR>1 {print $2}' | xargs -r ps -p | grep -E 'scdaemon|pcscd' >/dev/null; then + echo "Killing GPG toolstack related processes using USB devices..." + sudo lsof /dev/bus/usb/00*/0* 2>/dev/null | awk 'NR>1 {print $2}' | xargs -r ps -p | grep -E 'scdaemon|pcscd' | awk '{print $1}' | xargs -r sudo kill -9 + fi + fi } # Handle Ctrl-C (SIGINT) to exit gracefully @@ -29,10 +30,10 @@ trap "echo 'Script interrupted. Exiting...'; exit 1" SIGINT # Check if --help or -h is provided for arg in "$@"; do - if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then - usage - exit 0 - fi + if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then + usage + exit 0 + fi done # Kill processes using USB devices @@ -42,8 +43,16 @@ kill_usb_processes echo "----" echo "Usage reminder: The minimal command is 'make BOARD=XYZ', where additional options, including 'V=1' or 'CPUS=N' are optional." echo "For more advanced QEMU testing options, refer to targets/qemu.md and boards/qemu-*/*.config." +echo +echo "Type exit within docker image to get back to host if launched interactively!" echo "----" -echo "Entering the Docker container. Type 'exit' to return to the host shell." +echo # Execute the docker run command with the provided parameters -docker run --device=/dev/bus/usb:/dev/bus/usb -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) tlaurion/heads-dev-env:latest -- "$@" +if [ -d "/dev/bus/usb" ]; then + echo "--->Launching container with access to host's USB buses (some USB devices were connected to host)..." + docker run --device=/dev/bus/usb:/dev/bus/usb -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) $DOCKER_IMAGE -- "$@" +else + echo "--->Launching container without access to host's USB buses (no USB devices was connected to host)..." + docker run -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) $DOCKER_IMAGE -- "$@" +fi diff --git a/docker_local_dev.sh b/docker_local_dev.sh index dd543d15..43b8022b 100755 --- a/docker_local_dev.sh +++ b/docker_local_dev.sh @@ -1,49 +1,51 @@ #!/bin/bash +#locally build docker name is linuxboot/heads:dev-env +DOCKER_IMAGE="linuxboot/heads:dev-env" + # Check if Nix is installed -if ! command -v nix &> /dev/null; then - echo "Nix is not installed or not in the PATH. Please install Nix before running this script." - echo "Refer to the README.md at the root of the repository for installation instructions." - exit 1 +if ! command -v nix &>/dev/null; then + echo "Nix is not installed or not in the PATH. Please install Nix before running this script." + echo "Refer to the README.md at the root of the repository for installation instructions." + exit 1 fi # Check if Docker is installed -if ! command -v docker &> /dev/null; then - echo "Docker is not installed or not in the PATH. Please install Docker before running this script." - echo "Refer to the README.md at the root of the repository for installation instructions." - exit 1 +if ! command -v docker &>/dev/null; then + echo "Docker is not installed or not in the PATH. Please install Docker before running this script." + echo "Refer to the README.md at the root of the repository for installation instructions." + exit 1 fi # Inform the user about the Docker image being used -echo "** This ./docker_local_dev.sh script is for developers usage only. **" +echo "!!! This ./docker_local_dev.sh script is for developers usage only. !!!" echo "" -echo "Using the last locally produced Docker image: linuxboot/heads:dev-env" -echo "Warning: Using anything other than the published Docker image might lead to non-reproducible builds." +echo "Using the last locally built Docker image when flake.nix/flake.lock was modified and repo was dirty: linuxboot/heads:dev-env" +echo "!!! Warning: Using anything other than the published Docker image might lead to non-reproducible builds. !!!" echo "" echo "For using the latest published Docker image, refer to ./docker_latest.sh." echo "For producing reproducible builds as CircleCI, refer to ./docker_repro.sh." echo "" -echo "---" # Function to display usage information usage() { - echo "Usage: $0 [OPTIONS] -- [COMMAND]" - echo "Options:" - echo " CPUS=N Set the number of CPUs" - echo " V=1 Enable verbose mode" - echo "Command:" - echo " The command to run inside the Docker container, e.g., make BOARD=BOARD_NAME" + echo "Usage: $0 [OPTIONS] -- [COMMAND]" + echo "Options:" + echo " CPUS=N Set the number of CPUs" + echo " V=1 Enable verbose mode" + echo "Command:" + echo " The command to run inside the Docker container, e.g., make BOARD=BOARD_NAME" } # Function to kill GPG toolstack related processes using USB devices kill_usb_processes() { - echo "Killing any GPG toolstack related processes on host currently using USB devices..." - sudo lsof /dev/bus/usb/00*/0* 2>/dev/null | awk 'NR>1 {print $2}' | xargs -r ps -p | grep -E 'scdaemon|pcscd' | awk '{print $1}' | xargs -r sudo kill -9 - if [ $? -ne 0 ]; then - echo "Failed to kill GPG toolstack related processes using USB devices. Please run the following command manually:" - echo "sudo lsof /dev/bus/usb/00*/0* | awk 'NR>1 {print \$2}' | xargs -r ps -p | grep -E 'scdaemon|pcscd' | awk '{print \$1}' | xargs -r sudo kill -9" - exit 1 - fi + # check if scdaemon or pcscd processes are using USB devices + if [ -d /dev/bus/usb ]; then + if sudo lsof /dev/bus/usb/00*/0* 2>/dev/null | awk 'NR>1 {print $2}' | xargs -r ps -p | grep -E 'scdaemon|pcscd' >/dev/null; then + echo "Killing GPG toolstack related processes using USB devices..." + sudo lsof /dev/bus/usb/00*/0* 2>/dev/null | awk 'NR>1 {print $2}' | xargs -r ps -p | grep -E 'scdaemon|pcscd' | awk '{print $1}' | xargs -r sudo kill -9 + fi + fi } # Handle Ctrl-C (SIGINT) to exit gracefully @@ -51,23 +53,22 @@ trap "echo 'Script interrupted. Exiting...'; exit 1" SIGINT # Check if --help or -h is provided for arg in "$@"; do - if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then - usage - exit 0 - fi + if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then + usage + exit 0 + fi done # Check if the git repository is dirty and if flake.nix or flake.lock are part of the uncommitted changes if [ -n "$(git status --porcelain | grep -E 'flake\.nix|flake\.lock')" ]; then - echo "Warning: Uncommitted changes detected in flake.nix or flake.lock. The Docker image will be rebuilt." - echo "If this was not intended, please commit your changes and rerun the script." - echo "Building the Docker image from flake.nix..." - nix --print-build-logs --verbose develop --ignore-environment --command true - nix --print-build-logs --verbose build .#dockerImage && docker load < result + echo "**Warning: Uncommitted changes detected in flake.nix or flake.lock. The Docker image will be rebuilt!**" + echo "If this was not intended, please CTRL-C now, commit your changes and rerun the script." + echo "Building the Docker image from flake.nix..." + nix --print-build-logs --verbose develop --ignore-environment --command true + nix --print-build-logs --verbose build .#dockerImage && docker load Launching container with access to host's USB buses (some USB devices were connected to host)..." + docker run --device=/dev/bus/usb:/dev/bus/usb -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) $DOCKER_IMAGE -- "$@" +else + echo "--->Launching container without access to host's USB buses (no USB devices was connected to host)..." + docker run -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) $DOCKER_IMAGE -- "$@" +fi diff --git a/docker_repro.sh b/docker_repro.sh index 173bef62..0dbeb2f6 100755 --- a/docker_repro.sh +++ b/docker_repro.sh @@ -5,8 +5,8 @@ DOCKER_IMAGE=$(grep -oP '^\s*-?\s*image:\s*\K(tlaurion/heads-dev-env:[^\s]+)' .c # Check if the Docker image was found if [ -z "$DOCKER_IMAGE" ]; then - echo "Error: Docker image not found in .circleci/config.yml" - exit 1 + echo "Error: Docker image not found in .circleci/config.yml" + exit 1 fi # Inform the user about the versioned CircleCI Docker image being used @@ -14,23 +14,23 @@ echo "Using CircleCI Docker image: $DOCKER_IMAGE" # Function to display usage information usage() { - echo "Usage: $0 [OPTIONS] -- [COMMAND]" - echo "Options:" - echo " CPUS=N Set the number of CPUs" - echo " V=1 Enable verbose mode" - echo "Command:" - echo " The command to run inside the Docker container, e.g., make BOARD=BOARD_NAME" + echo "Usage: $0 [OPTIONS] -- [COMMAND]" + echo "Options:" + echo " CPUS=N Set the number of CPUs" + echo " V=1 Enable verbose mode" + echo "Command:" + echo " The command to run inside the Docker container, e.g., make BOARD=BOARD_NAME" } # Function to kill GPG toolstack related processes using USB devices kill_usb_processes() { - echo "Killing any GPG toolstack related processes on host currently using USB devices..." - sudo lsof /dev/bus/usb/00*/0* 2>/dev/null | awk 'NR>1 {print $2}' | xargs -r ps -p | grep -E 'scdaemon|pcscd' | awk '{print $1}' | xargs -r sudo kill -9 - if [ $? -ne 0 ]; then - echo "Failed to kill GPG toolstack related processes using USB devices. Please run the following command manually:" - echo "sudo lsof /dev/bus/usb/00*/0* | awk 'NR>1 {print \$2}' | xargs -r ps -p | grep -E 'scdaemon|pcscd' | awk '{print \$1}' | xargs -r sudo kill -9" - exit 1 - fi + # check if scdaemon or pcscd processes are using USB devices + if [ -d /dev/bus/usb ]; then + if sudo lsof /dev/bus/usb/00*/0* 2>/dev/null | awk 'NR>1 {print $2}' | xargs -r ps -p | grep -E 'scdaemon|pcscd' >/dev/null; then + echo "Killing GPG toolstack related processes using USB devices..." + sudo lsof /dev/bus/usb/00*/0* 2>/dev/null | awk 'NR>1 {print $2}' | xargs -r ps -p | grep -E 'scdaemon|pcscd' | awk '{print $1}' | xargs -r sudo kill -9 + fi + fi } # Handle Ctrl-C (SIGINT) to exit gracefully @@ -38,10 +38,10 @@ trap "echo 'Script interrupted. Exiting...'; exit 1" SIGINT # Check if --help or -h is provided for arg in "$@"; do - if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then - usage - exit 0 - fi + if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then + usage + exit 0 + fi done # Kill processes using USB devices @@ -51,8 +51,16 @@ kill_usb_processes echo "----" echo "Usage reminder: The minimal command is 'make BOARD=XYZ', where additional options, including 'V=1' or 'CPUS=N' are optional." echo "For more advanced QEMU testing options, refer to targets/qemu.md and boards/qemu-*/*.config." +echo +echo "Type exit within docker image to get back to host if launched interactively!" echo "----" -echo "Entering the Docker container. Type 'exit' to return to the host shell." +echo # Execute the docker run command with the provided parameters -docker run --device=/dev/bus/usb:/dev/bus/usb -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) $DOCKER_IMAGE -- "$@" +if [ -d "/dev/bus/usb" ]; then + echo "--->Launching container with access to host's USB buses (some USB devices were connected to host)..." + docker run --device=/dev/bus/usb:/dev/bus/usb -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) $DOCKER_IMAGE -- "$@" +else + echo "--->Launching container without access to host's USB buses (no USB devices was connected to host)..." + docker run -e DISPLAY=$DISPLAY --network host --rm -ti -v $(pwd):$(pwd) -w $(pwd) $DOCKER_IMAGE -- "$@" +fi