From 8a0ec7cef35237cf4630752a7c62a5aa37fed354 Mon Sep 17 00:00:00 2001 From: Jason Thomas Date: Thu, 15 Jan 2026 17:49:53 -0700 Subject: [PATCH 1/5] Use '[[' instead of '[' for conditional tests in bash scripts The '[[' construct is safer and more feature-rich, preventing word splitting and pathname expansion issues. Scripts that run in Docker containers with /bin/sh (Alpine/busybox) remain unchanged to maintain POSIX compliance. Co-Authored-By: Claude Opus 4.5 --- hooks/install.sh | 2 +- openc3-cosmos-init/init.sh | 4 +- openc3-ruby/anycable_install.sh | 4 +- openc3-tsdb/docker-entrypoint.sh | 12 ++-- openc3.sh | 88 ++++++++++++------------- playwright/playwright.sh | 20 +++--- scripts/linux/benchmark_s3_migration.sh | 16 ++--- scripts/linux/openc3_build_ubi.sh | 14 ++-- scripts/linux/openc3_migrate_s3.sh | 30 ++++----- scripts/linux/openc3_setup.sh | 10 +-- scripts/linux/openc3_test.sh | 12 ++-- scripts/linux/openc3_upgrade.sh | 14 ++-- scripts/linux/openc3_util.sh | 32 ++++----- scripts/release/build_multi_arch.sh | 38 +++++------ 14 files changed, 148 insertions(+), 148 deletions(-) diff --git a/hooks/install.sh b/hooks/install.sh index d677153291..fee1338a75 100755 --- a/hooks/install.sh +++ b/hooks/install.sh @@ -7,7 +7,7 @@ GIT_DIR="$(git rev-parse --git-dir)" echo "Installing git hooks..." # Install pre-commit hook -if [ -f "$SCRIPT_DIR/pre-commit" ]; then +if [[ -f "$SCRIPT_DIR/pre-commit" ]]; then cp "$SCRIPT_DIR/pre-commit" "$GIT_DIR/hooks/pre-commit" chmod +x "$GIT_DIR/hooks/pre-commit" echo "✓ Installed pre-commit hook" diff --git a/openc3-cosmos-init/init.sh b/openc3-cosmos-init/init.sh index 5900d04219..d198a12995 100755 --- a/openc3-cosmos-init/init.sh +++ b/openc3-cosmos-init/init.sh @@ -39,7 +39,7 @@ if [ ! -z "${OPENC3_ISTIO_ENABLED}" ]; then echo "Sidecar available. Running the command..." fi -if [ "${OPENC3_CLOUD}" == "local" ]; then +if [ "${OPENC3_CLOUD}" = "local" ]; then RC=1 while [ $RC -gt 0 ]; do # Check if buckets endpoint is responding (accept any HTTP response, even 403) @@ -95,7 +95,7 @@ if [ -z "${OPENC3_NO_MIGRATE}" ]; then ruby /openc3/bin/openc3cli runmigrations || exit 1 fi -if [ "${OPENC3_CLOUD}" == "local" ]; then +if [ "${OPENC3_CLOUD}" = "local" ]; then ruby /openc3/bin/openc3cli initbuckets || exit 1 fi diff --git a/openc3-ruby/anycable_install.sh b/openc3-ruby/anycable_install.sh index 2f637bac08..9994278810 100755 --- a/openc3-ruby/anycable_install.sh +++ b/openc3-ruby/anycable_install.sh @@ -1,11 +1,11 @@ #!/bin/sh ARCH=`uname -m` -if [ "$ARCH" == "aarch64" ]; then +if [ "$ARCH" = "aarch64" ]; then chmod 755 /usr/bin/anycable-go-linux-arm64 ln -s /usr/bin/anycable-go-linux-arm64 /usr/bin/anycable-go else chmod 755 /usr/bin/anycable-go-linux-amd64 ln -s /usr/bin/anycable-go-linux-amd64 /usr/bin/anycable-go fi -chmod 755 /usr/bin/anycable-go \ No newline at end of file +chmod 755 /usr/bin/anycable-go diff --git a/openc3-tsdb/docker-entrypoint.sh b/openc3-tsdb/docker-entrypoint.sh index 72653f860d..1995bf0dbd 100644 --- a/openc3-tsdb/docker-entrypoint.sh +++ b/openc3-tsdb/docker-entrypoint.sh @@ -31,26 +31,26 @@ read -ra LOCALDIRS < <( echo -n "( "; printf -- "-ipath ${QUESTDB_DATA_DIR}%s* - # Temporary only # Most of the users will have the data mounted under /root/.questdb as default # we will run as root for them until they change the mount to /var/lib/questdb or something else -if [ "$IGNORE_DATA_ROOT_MOUNT_CHECK" = "false" ] && mount | grep "/root/.questdb" -q; then +if [[ "$IGNORE_DATA_ROOT_MOUNT_CHECK" == "false" ]] && mount | grep "/root/.questdb" -q; then echo "Found /root/.questdb mount, overwriting QUESTDB_DATA_DIR" QUESTDB_DATA_DIR="/root/.questdb" fi # Check if on-demand JVM arguments are provided through environment variable -if [ -n "$JVM_PREPEND" ]; then +if [[ -n "$JVM_PREPEND" ]]; then echo "Found on-demand JVM arguments: $JVM_PREPEND, prepending to JVM args" JAVA_COMMAND="$JAVA_COMMAND $JVM_PREPEND" fi # Check if arguments are provided in the configuration file -if [ $# -eq 0 ]; then +if [[ $# -eq 0 ]]; then echo "No arguments found in the configuration, start with default arguments" set -- $JAVA_COMMAND -ea -Dnoebug -XX:+UseParallelGC -XX:ErrorFile=${QUESTDB_DATA_DIR}/db/hs_err_pid+%p.log -Dout=${QUESTDB_DATA_DIR}/conf/log.conf -m io.questdb/io.questdb.ServerMain -d ${QUESTDB_DATA_DIR} -f else - if [ "${1:0:1}" = '-' ]; then + if [[ "${1:0:1}" == '-' ]]; then echo "Found config arguments $@" set -- $JAVA_COMMAND "$@" - elif [ "$1" = "/app/bin/java" ]; then + elif [[ "$1" == "/app/bin/java" ]]; then echo "Java binary argument found in command, ignoring on-demand JVM arguments, start with fully-customized arguments" set -- "$@" fi @@ -69,4 +69,4 @@ fi # fi echo "Running as $(id -un 2>/dev/null) user" -exec "$@" \ No newline at end of file +exec "$@" diff --git a/openc3.sh b/openc3.sh index 9d28759de1..448ee6fae8 100755 --- a/openc3.sh +++ b/openc3.sh @@ -27,12 +27,12 @@ find_script() { export DOCKER_COMPOSE_COMMAND="docker compose" ${DOCKER_COMPOSE_COMMAND} version &> /dev/null -if [ "$?" -ne 0 ]; then +if [[ "$?" -ne 0 ]]; then export DOCKER_COMPOSE_COMMAND="docker-compose" fi docker info | grep -e "rootless$" -e "rootless: true" -if [ "$?" -ne 0 ]; then +if [[ "$?" -ne 0 ]]; then export OPENC3_ROOTFUL=1 export OPENC3_USER_ID=`id -u` export OPENC3_GROUP_ID=`id -g` @@ -44,23 +44,23 @@ fi # Detect if this is a development (build) environment or runtime environment # by checking for compose-build.yaml -if [ -f "$(dirname -- "$0")/compose-build.yaml" ]; then +if [[ -f "$(dirname -- "$0")/compose-build.yaml" ]]; then export OPENC3_DEVEL=1 else export OPENC3_DEVEL=0 fi # Detect if this is enterprise by checking for enterprise-specific services -if [ -f "$(dirname -- "$0")/compose-build.yaml" ] && grep -q "openc3-enterprise-gem" "$(dirname -- "$0")/compose-build.yaml" 2>/dev/null; then +if [[ -f "$(dirname -- "$0")/compose-build.yaml" ]] && grep -q "openc3-enterprise-gem" "$(dirname -- "$0")/compose-build.yaml" 2>/dev/null; then export OPENC3_ENTERPRISE=1 -elif [ -f "$(dirname -- "$0")/compose.yaml" ] && grep -q "openc3-metrics" "$(dirname -- "$0")/compose.yaml" 2>/dev/null; then +elif [[ -f "$(dirname -- "$0")/compose.yaml" ]] && grep -q "openc3-metrics" "$(dirname -- "$0")/compose.yaml" 2>/dev/null; then export OPENC3_ENTERPRISE=1 else export OPENC3_ENTERPRISE=0 fi # Set display name based on enterprise flag -if [ "$OPENC3_ENTERPRISE" -eq 1 ]; then +if [[ "$OPENC3_ENTERPRISE" -eq 1 ]]; then export COSMOS_NAME="COSMOS Enterprise" else export COSMOS_NAME="COSMOS Core" @@ -69,7 +69,7 @@ fi set -e usage() { - if [ "$OPENC3_DEVEL" -eq 1 ] && [ "$OPENC3_ENTERPRISE" -eq 1 ]; then + if [[ "$OPENC3_DEVEL" -eq 1 ]] && [[ "$OPENC3_ENTERPRISE" -eq 1 ]]; then cat >&2 << EOF OpenC3 $COSMOS_NAME - Command and Control System (Enterprise Development Installation) Usage: $1 COMMAND [OPTIONS] @@ -83,7 +83,7 @@ DESCRIPTION: COMMON COMMANDS: EOF - elif [ "$OPENC3_DEVEL" -eq 1 ]; then + elif [[ "$OPENC3_DEVEL" -eq 1 ]]; then cat >&2 << EOF OpenC3 $COSMOS_NAME - Command and Control System (Development Installation) Usage: $1 COMMAND [OPTIONS] @@ -97,7 +97,7 @@ DESCRIPTION: COMMON COMMANDS: EOF - elif [ "$OPENC3_ENTERPRISE" -eq 1 ]; then + elif [[ "$OPENC3_ENTERPRISE" -eq 1 ]]; then cat >&2 << EOF OpenC3 $COSMOS_NAME - Command and Control System (Enterprise Runtime-Only Installation) Usage: $1 COMMAND [OPTIONS] @@ -126,7 +126,7 @@ DESCRIPTION: COMMON COMMANDS: EOF fi - if [ "$OPENC3_DEVEL" -eq 1 ]; then + if [[ "$OPENC3_DEVEL" -eq 1 ]]; then cat >&2 << EOF start Build and run $COSMOS_NAME (equivalent to: build + run) This is the typical command to get $COSMOS_NAME running. @@ -154,7 +154,7 @@ EOF Same as 'cli' but with root privileges EOF - if [ "$OPENC3_DEVEL" -eq 1 ]; then + if [[ "$OPENC3_DEVEL" -eq 1 ]]; then cat >&2 << EOF DEVELOPMENT COMMANDS: build Build all $COSMOS_NAME Docker containers from source @@ -173,7 +173,7 @@ EOF Use '$1 util' to see available utilities. EOF - if [ "$OPENC3_DEVEL" -eq 0 ]; then + if [[ "$OPENC3_DEVEL" -eq 0 ]]; then cat >&2 << EOF upgrade Upgrade $COSMOS_NAME to latest version Downloads and installs latest release. @@ -189,7 +189,7 @@ CLEANUP: force - Skip confirmation prompt EOF - if [ "$OPENC3_DEVEL" -eq 1 ]; then + if [[ "$OPENC3_DEVEL" -eq 1 ]]; then cat >&2 << EOF REDHAT: start-ubi Build and run with Red Hat UBI images @@ -217,24 +217,24 @@ EOF exit 1 } -if [ "$#" -eq 0 ]; then +if [[ "$#" -eq 0 ]]; then usage $0 fi # Check for help flag -if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then +if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then usage $0 fi check_root() { - if [ "$(id -u)" -eq 0 ]; then + if [[ "$(id -u)" -eq 0 ]]; then echo "WARNING: $COSMOS_NAME should not be run as the root user, as permissions for Local Mode will be affected. Do not use sudo when running $COSMOS_NAME. See more: https://docs.openc3.com/docs/guides/local-mode" fi } case $1 in cli ) - if [ "$2" == "--wrapper-help" ] || [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--wrapper-help" ]] || [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 cli [COMMAND] [OPTIONS]" echo "" echo "Run $COSMOS_NAME CLI commands inside a Docker container as the default user." @@ -278,7 +278,7 @@ case $1 in # Run the command "ruby /openc3/bin/openc3cli" with all parameters starting at 2 since the first is 'openc3' # Shift off the first argument (script name) to get CLI args shift - if [ "$OPENC3_ENTERPRISE" -eq 1 ]; then + if [[ "$OPENC3_ENTERPRISE" -eq 1 ]]; then ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" run -it --rm -v `pwd`:/openc3/local:z -w /openc3/local -e OPENC3_API_USER=$OPENC3_API_USER -e OPENC3_API_PASSWORD=$OPENC3_API_PASSWORD --no-deps openc3-cosmos-cmd-tlm-api ruby /openc3/bin/openc3cli "$@" else ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" run -it --rm -v `pwd`:/openc3/local:z -w /openc3/local -e OPENC3_API_PASSWORD=$OPENC3_API_PASSWORD --no-deps openc3-cosmos-cmd-tlm-api ruby /openc3/bin/openc3cli "$@" @@ -286,7 +286,7 @@ case $1 in set +a ;; cliroot ) - if [ "$2" == "--wrapper-help" ] || [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--wrapper-help" ]] || [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 cliroot [COMMAND] [OPTIONS]" echo "" echo "Run $COSMOS_NAME CLI commands inside a Docker container as root user." @@ -329,7 +329,7 @@ case $1 in # (enterprise or non-enterprise) based on environment variables. # Shift off the first argument (script name) to get CLI args shift - if [ "$OPENC3_ENTERPRISE" -eq 1 ]; then + if [[ "$OPENC3_ENTERPRISE" -eq 1 ]]; then ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" run -it --rm --user=root -v `pwd`:/openc3/local:z -w /openc3/local -e OPENC3_API_USER=$OPENC3_API_USER -e OPENC3_API_PASSWORD=$OPENC3_API_PASSWORD --no-deps openc3-cosmos-cmd-tlm-api ruby /openc3/bin/openc3cli "$@" else ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" run -it --rm --user=root -v `pwd`:/openc3/local:z -w /openc3/local -e OPENC3_API_PASSWORD=$OPENC3_API_PASSWORD --no-deps openc3-cosmos-cmd-tlm-api ruby /openc3/bin/openc3cli "$@" @@ -337,8 +337,8 @@ case $1 in set +a ;; start ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then - if [ "$OPENC3_DEVEL" -eq 1 ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then + if [[ "$OPENC3_DEVEL" -eq 1 ]]; then echo "Usage: $0 start" echo "" echo "Build and run $COSMOS_NAME containers." @@ -361,7 +361,7 @@ case $1 in fi exit 0 fi - if [ "$OPENC3_DEVEL" -eq 1 ]; then + if [[ "$OPENC3_DEVEL" -eq 1 ]]; then "$0" build "$0" run else @@ -369,8 +369,8 @@ case $1 in fi ;; start-ubi ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then - if [ "$OPENC3_DEVEL" -eq 1 ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then + if [[ "$OPENC3_DEVEL" -eq 1 ]]; then echo "Usage: $0 start-ubi" echo "" echo "Build and run $COSMOS_NAME UBI containers." @@ -393,7 +393,7 @@ case $1 in fi exit 0 fi - if [ "$OPENC3_DEVEL" -eq 1 ]; then + if [[ "$OPENC3_DEVEL" -eq 1 ]]; then "$0" build-ubi "$0" run-ubi else @@ -401,12 +401,12 @@ case $1 in fi ;; stop ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 stop" echo "" echo "Stop all $COSMOS_NAME containers gracefully." echo "" - if [ "$OPENC3_ENTERPRISE" -eq 1 ]; then + if [[ "$OPENC3_ENTERPRISE" -eq 1 ]]; then echo "This command:" echo " 1. Stops operator, script-runner-api, cmd-tlm-api, and metrics containers" echo " 2. Waits 5 seconds" @@ -425,14 +425,14 @@ case $1 in ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" stop openc3-operator ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" stop openc3-cosmos-script-runner-api ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" stop openc3-cosmos-cmd-tlm-api - if [ "$OPENC3_ENTERPRISE" -eq 1 ]; then + if [[ "$OPENC3_ENTERPRISE" -eq 1 ]]; then ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" stop openc3-metrics fi sleep 5 ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" down -t 30 ;; cleanup ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 cleanup [local] [force]" echo "" echo "Remove all $COSMOS_NAME docker volumes and data." @@ -454,7 +454,7 @@ case $1 in exit 0 fi # They can specify 'cleanup force' or 'cleanup local force' - if [ "$2" == "force" ] || [ "$3" == "force" ] + if [[ "$2" == "force" ]] || [[ "$3" == "force" ]] then ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" down -t 30 -v else @@ -466,7 +466,7 @@ case $1 in esac done fi - if [ "$2" == "local" ] + if [[ "$2" == "local" ]] then cd "$(dirname -- "$0")/plugins/DEFAULT" ls | grep -xv "README.md" | xargs rm -r @@ -474,17 +474,17 @@ case $1 in fi ;; build ) - if [ "$OPENC3_DEVEL" -eq 0 ]; then + if [[ "$OPENC3_DEVEL" -eq 0 ]]; then echo "Error: 'build' command is only available in development environments" echo "This appears to be a runtime-only installation." exit 1 fi - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 build" echo "" echo "Build all $COSMOS_NAME docker containers." echo "" - if [ "$OPENC3_ENTERPRISE" -eq 1 ]; then + if [[ "$OPENC3_ENTERPRISE" -eq 1 ]]; then echo "This command:" echo " 1. Runs setup to download certificates" echo " 2. Builds openc3-enterprise-gem image" @@ -508,7 +508,7 @@ case $1 in # Handle restrictive umasks - Built files need to be world readable umask 0022 chmod -R +r "$(dirname -- "$0")" - if [ "$OPENC3_ENTERPRISE" -eq 1 ]; then + if [[ "$OPENC3_ENTERPRISE" -eq 1 ]]; then ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" -f "$(dirname -- "$0")/compose-build.yaml" build openc3-enterprise-gem else ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" -f "$(dirname -- "$0")/compose-build.yaml" build openc3-ruby @@ -518,12 +518,12 @@ case $1 in ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" -f "$(dirname -- "$0")/compose-build.yaml" build ;; build-ubi ) - if [ "$OPENC3_DEVEL" -eq 0 ]; then + if [[ "$OPENC3_DEVEL" -eq 0 ]]; then echo "Error: 'build-ubi' command is only available in development environments" echo "This appears to be a runtime-only installation." exit 1 fi - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 build-ubi [IMAGE_NAME...]" echo "" echo "Build $COSMOS_NAME UBI (Universal Base Image) containers." @@ -578,7 +578,7 @@ case $1 in set +a ;; run ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 run" echo "" echo "Run all $COSMOS_NAME containers in detached mode." @@ -608,7 +608,7 @@ case $1 in ${DOCKER_COMPOSE_COMMAND} -f "$(dirname -- "$0")/compose.yaml" up -d ;; run-ubi ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 run-ubi" echo "" echo "Run all $COSMOS_NAME UBI (Universal Base Image) containers in detached mode." @@ -643,7 +643,7 @@ case $1 in ;; test ) # Check for help at any position - if [ "$2" == "--help" ] || [ "$2" == "-h" ] || [ "$#" -eq 1 ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]] || [[ "$#" -eq 1 ]]; then echo "Usage: $0 test COMMAND [OPTIONS]" echo "" echo "Test $COSMOS_NAME. This builds $COSMOS_NAME and runs the specified test suite." @@ -665,7 +665,7 @@ case $1 in fi # If subcommand has --help or -h, skip setup/build and pass through directly for arg in "$@"; do - if [ "$arg" == "--help" ] || [ "$arg" == "-h" ]; then + if [[ "$arg" == "--help" ]] || [[ "$arg" == "-h" ]]; then "$(find_script openc3_test.sh)" "${@:2}" exit 0 fi @@ -677,7 +677,7 @@ case $1 in "$(find_script openc3_test.sh)" "${@:2}" ;; upgrade ) - if [ "$OPENC3_DEVEL" -eq 1 ]; then + if [[ "$OPENC3_DEVEL" -eq 1 ]]; then echo "Error: 'upgrade' command is only available in runtime environments" echo "This appears to be a development installation." exit 1 @@ -685,7 +685,7 @@ case $1 in "$(find_script openc3_upgrade.sh)" "${@:2}" ;; util ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ] || [ "$#" -eq 1 ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]] || [[ "$#" -eq 1 ]]; then echo "Usage: $0 util COMMAND [OPTIONS]" echo "" echo "Various $COSMOS_NAME utility commands." diff --git a/playwright/playwright.sh b/playwright/playwright.sh index 79a8a4fffa..5a3f79646c 100755 --- a/playwright/playwright.sh +++ b/playwright/playwright.sh @@ -11,18 +11,18 @@ usage() { exit 1 } -if [ "$#" -eq 0 ]; then +if [[ "$#" -eq 0 ]]; then usage $0 fi # Check for help flag -if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then +if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then usage $0 fi case $1 in install-playwright ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 install-playwright" echo "" echo "Install Playwright and its dependencies." @@ -40,8 +40,8 @@ case $1 in fi # Attempt to clean up downloaded browser binaries # https://playwright.dev/docs/ci#directories-to-cache - [ -d $HOME/.cache/ms-playwright ] && rm -rf $HOME/.cache/ms-playwright # linux - [ -d $HOME/Library/Caches/ms-playwright ] && rm -rf $HOME/Library/Caches/ms-playwright # mac + [[ -d $HOME/.cache/ms-playwright ]] && rm -rf $HOME/.cache/ms-playwright # linux + [[ -d $HOME/Library/Caches/ms-playwright ]] && rm -rf $HOME/Library/Caches/ms-playwright # mac rm -rf node_modules @@ -51,7 +51,7 @@ case $1 in ;; build-plugin ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 build-plugin" echo "" echo "Build the test plugin used in Playwright tests." @@ -77,7 +77,7 @@ case $1 in ;; reset-storage-state ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 reset-storage-state" echo "" echo "Clear out cached Playwright storage state." @@ -93,7 +93,7 @@ case $1 in ;; run-chromium ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 run-chromium [PLAYWRIGHT_OPTIONS]" echo "" echo "Run Playwright tests using Chrome against a local OpenC3 instance." @@ -117,7 +117,7 @@ case $1 in ;; run-enterprise ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 run-enterprise" echo "" echo "Run enterprise Playwright tests." @@ -133,7 +133,7 @@ case $1 in ;; run-aws ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 run-aws" echo "" echo "Run Playwright tests against AWS-hosted OpenC3." diff --git a/scripts/linux/benchmark_s3_migration.sh b/scripts/linux/benchmark_s3_migration.sh index 691a00553d..d88b1bc6de 100755 --- a/scripts/linux/benchmark_s3_migration.sh +++ b/scripts/linux/benchmark_s3_migration.sh @@ -31,20 +31,20 @@ BENCHMARK_BUCKET="benchmark-test" # Auto-detect Docker network and MINIO container detect_docker_environment() { MINIO_CONTAINER=$(docker ps --format '{{.Names}}' | grep -i minio | head -1) - if [ -z "$MINIO_CONTAINER" ]; then + if [[ -z "$MINIO_CONTAINER" ]]; then echo "${RED}Error: Could not find running MINIO container${NC}" echo "Make sure COSMOS is running: ./openc3.sh run" exit 1 fi DOCKER_NETWORK=$(docker inspect --format '{{range $net, $config := .NetworkSettings.Networks}}{{$net}}{{"\n"}}{{end}}' "$MINIO_CONTAINER" | grep -v '^$' | head -1) - if [ -z "$DOCKER_NETWORK" ]; then + if [[ -z "$DOCKER_NETWORK" ]]; then echo "${RED}Error: Could not determine network for MINIO container${NC}" exit 1 fi MINIO_SERVICE=$(docker inspect --format '{{index .Config.Labels "com.docker.compose.service"}}' "$MINIO_CONTAINER" 2>/dev/null) - if [ -z "$MINIO_SERVICE" ]; then + if [[ -z "$MINIO_SERVICE" ]]; then MINIO_SERVICE="$MINIO_CONTAINER" fi } @@ -140,7 +140,7 @@ calc_rate() { local duration=$2 # Handle empty or zero duration - if [ -z "$duration" ] || [ "$duration" = "0" ]; then + if [[ -z "$duration" ]] || [[ "$duration" == "0" ]]; then echo "N/A" return fi @@ -152,7 +152,7 @@ calc_rate() { fi local rate=$(echo "scale=2; $size_mb / $duration" | bc 2>/dev/null) - if [ -z "$rate" ]; then + if [[ -z "$rate" ]]; then echo "N/A" else echo "$rate" @@ -164,7 +164,7 @@ format_duration() { local seconds=$1 # Handle empty or invalid input - if [ -z "$seconds" ] || ! echo "$seconds" | grep -qE '^[0-9]+\.?[0-9]*$'; then + if [[ -z "$seconds" ]] || ! echo "$seconds" | grep -qE '^[0-9]+\.?[0-9]*$'; then echo "N/A" return fi @@ -267,7 +267,7 @@ print_summary() { echo "" # Estimate times for larger datasets based on measured rate - if [ ${#BENCHMARK_RESULTS[@]} -gt 0 ]; then + if [[ ${#BENCHMARK_RESULTS[@]} -gt 0 ]]; then # Use the largest test's rate for estimation local last_index=$((${#BENCHMARK_RESULTS[@]} - 1)) local last_result="${BENCHMARK_RESULTS[$last_index]}" @@ -375,7 +375,7 @@ case "${1:-help}" in print_summary ;; custom) - if [ -z "$2" ]; then + if [[ -z "$2" ]]; then echo "${RED}Error: custom requires SIZE_MB argument${NC}" echo "Usage: $0 custom SIZE_MB" exit 1 diff --git a/scripts/linux/openc3_build_ubi.sh b/scripts/linux/openc3_build_ubi.sh index 18cb1023e7..3e3a93f794 100755 --- a/scripts/linux/openc3_build_ubi.sh +++ b/scripts/linux/openc3_build_ubi.sh @@ -16,7 +16,7 @@ AVAILABLE_IMAGES=( ) # Check for help flag -if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then +if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then echo "Usage: openc3_build_ubi.sh [IMAGE_NAME...]" echo "" echo "Builds OpenC3 UBI (Universal Base Image) containers for enterprise deployments." @@ -61,7 +61,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" # Parse command line arguments to determine which images to build IMAGES_TO_BUILD=() -if [ $# -eq 0 ]; then +if [[ $# -eq 0 ]]; then # No arguments provided, build all images IMAGES_TO_BUILD=("${AVAILABLE_IMAGES[@]}") echo "No images specified, building all images..." @@ -99,7 +99,7 @@ fi # Detect host architecture and set platform flag # On ARM Macs, some x86 images use x86-64-v3 which can't be emulated -if [ "$(uname -m)" = "arm64" ]; then +if [[ "$(uname -m)" == "arm64" ]]; then echo "Detected ARM architecture - building native images" PLATFORM_FLAG="" else @@ -109,7 +109,7 @@ fi # Function to check and perform registry login check_registry_login() { - if [ -z "$OPENC3_UBI_REGISTRY" ]; then + if [[ -z "$OPENC3_UBI_REGISTRY" ]]; then echo "Warning: OPENC3_UBI_REGISTRY not set, skipping registry login check" return 0 fi @@ -117,7 +117,7 @@ check_registry_login() { echo "Logging into registry: $OPENC3_UBI_REGISTRY" # Attempt login with credentials if provided, otherwise prompt - if [ -n "$OPENC3_UBI_USERNAME" ] && [ -n "$OPENC3_UBI_PASSWORD" ]; then + if [[ -n "$OPENC3_UBI_USERNAME" ]] && [[ -n "$OPENC3_UBI_PASSWORD" ]]; then echo "Using provided credentials for login..." if echo "$OPENC3_UBI_PASSWORD" | docker login "$OPENC3_UBI_REGISTRY" --username "$OPENC3_UBI_USERNAME" --password-stdin; then echo "Successfully authenticated with registry: $OPENC3_UBI_REGISTRY" @@ -155,7 +155,7 @@ format_duration() { local total_seconds=$1 local minutes=$((total_seconds / 60)) local seconds=$((total_seconds % 60)) - if [ $minutes -gt 0 ]; then + if [[ $minutes -gt 0 ]]; then echo "${minutes}m ${seconds}s" else echo "${seconds}s" @@ -416,7 +416,7 @@ echo " BUILD SUMMARY REPORT" echo "========================================" echo "" -if [ ${#BUILT_IMAGES[@]} -eq 0 ]; then +if [[ ${#BUILT_IMAGES[@]} -eq 0 ]]; then echo "No images were built." else echo "Images built: ${#BUILT_IMAGES[@]}" diff --git a/scripts/linux/openc3_migrate_s3.sh b/scripts/linux/openc3_migrate_s3.sh index 1cac14a83e..52ea5dd55d 100755 --- a/scripts/linux/openc3_migrate_s3.sh +++ b/scripts/linux/openc3_migrate_s3.sh @@ -37,7 +37,7 @@ OLD_VOLUME="${OLD_VOLUME:-openc3-buckets-v}" NEW_VOLUME="${NEW_VOLUME:-openc3-buckets-v}" # User IDs - must match openc3.sh behavior # openc3.sh sets these to current user (id -u/id -g) for non-rootless Docker -if [ -z "$OPENC3_USER_ID" ]; then +if [[ -z "$OPENC3_USER_ID" ]]; then if docker info 2>/dev/null | grep -qE "rootless$|rootless: true"; then # Rootless - use 0 OPENC3_USER_ID=0 @@ -165,16 +165,16 @@ get_container_network() { # Ensure migration network exists ensure_network() { - if [ -n "$DOCKER_NETWORK" ]; then + if [[ -n "$DOCKER_NETWORK" ]]; then return 0 fi # Try to find an existing COSMOS network local cosmos_container cosmos_container=$(find_container "openc3-buckets|openc3-minio") - if [ -n "$cosmos_container" ]; then + if [[ -n "$cosmos_container" ]]; then DOCKER_NETWORK=$(get_container_network "$cosmos_container") - if [ -n "$DOCKER_NETWORK" ]; then + if [[ -n "$DOCKER_NETWORK" ]]; then log_info "Using existing Docker network: $DOCKER_NETWORK" return 0 fi @@ -224,7 +224,7 @@ detect_environment() { # Detect MINIO source (COSMOS 6 running or temp container) local live_minio live_minio=$(find_container "openc3-minio") - if [ -n "$live_minio" ] && [ "$live_minio" != "$MINIO_MIGRATION_CONTAINER" ]; then + if [[ -n "$live_minio" ]] && [[ "$live_minio" != "$MINIO_MIGRATION_CONTAINER" ]]; then MINIO_SOURCE="$live_minio" USING_TEMP_MINIO=false log_info "Found live MINIO (COSMOS 6): $MINIO_SOURCE" @@ -242,11 +242,11 @@ detect_environment() { # Detect versitygw destination (COSMOS 7 running or temp container) local live_versity live_versity=$(find_container "openc3-buckets") - if [ -n "$live_versity" ] && [ "$live_versity" != "$VERSITY_MIGRATION_CONTAINER" ]; then + if [[ -n "$live_versity" ]] && [[ "$live_versity" != "$VERSITY_MIGRATION_CONTAINER" ]]; then VERSITY_DEST="$live_versity" USING_TEMP_VERSITY=false log_info "Found live versitygw (COSMOS 7): $VERSITY_DEST" - if [ -z "$DOCKER_NETWORK" ]; then + if [[ -z "$DOCKER_NETWORK" ]]; then DOCKER_NETWORK=$(get_container_network "$VERSITY_DEST") fi elif container_running "$VERSITY_MIGRATION_CONTAINER"; then @@ -384,12 +384,12 @@ cmd_start() { detect_environment # Start temp MINIO if no live MINIO - if [ -z "$MINIO_SOURCE" ]; then + if [[ -z "$MINIO_SOURCE" ]]; then start_temp_minio fi # Start temp versitygw if no live versitygw - if [ -z "$VERSITY_DEST" ]; then + if [[ -z "$VERSITY_DEST" ]]; then start_temp_versity fi @@ -406,12 +406,12 @@ cmd_migrate() { detect_environment # Ensure source is available - if [ -z "$MINIO_SOURCE" ]; then + if [[ -z "$MINIO_SOURCE" ]]; then start_temp_minio fi # Ensure destination is available - if [ -z "$VERSITY_DEST" ]; then + if [[ -z "$VERSITY_DEST" ]]; then start_temp_versity fi @@ -430,7 +430,7 @@ cmd_migrate() { local buckets buckets=$(run_mc ls minio/ 2>/dev/null | awk '{print $NF}' | tr -d '/' | grep -v '^$' || true) - if [ -z "$buckets" ]; then + if [[ -z "$buckets" ]]; then log_warn "No buckets found in MINIO - nothing to migrate" return 0 fi @@ -492,16 +492,16 @@ cmd_status() { echo "" echo "Containers:" echo " MINIO source: ${MINIO_SOURCE:-none}" - if [ -n "$MINIO_SOURCE" ]; then + if [[ -n "$MINIO_SOURCE" ]]; then echo -e " ${GREEN}running${NC}" fi echo " versitygw destination: ${VERSITY_DEST:-none}" - if [ -n "$VERSITY_DEST" ]; then + if [[ -n "$VERSITY_DEST" ]]; then echo -e " ${GREEN}running${NC}" fi # If both are running, compare bucket sizes - if [ -n "$MINIO_SOURCE" ] && [ -n "$VERSITY_DEST" ]; then + if [[ -n "$MINIO_SOURCE" ]] && [[ -n "$VERSITY_DEST" ]]; then echo "" echo "Bucket sizes (source -> destination):" echo "" diff --git a/scripts/linux/openc3_setup.sh b/scripts/linux/openc3_setup.sh index fb10981e12..d67ba8e55c 100755 --- a/scripts/linux/openc3_setup.sh +++ b/scripts/linux/openc3_setup.sh @@ -1,7 +1,7 @@ #!/bin/bash # Check for help flag -if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then +if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then echo "Usage: openc3_setup.sh" echo "" echo "Sets up OpenC3 dependencies and downloads necessary certificates." @@ -39,14 +39,14 @@ then fi fi -if [ ! -f ./cacert.pem ]; then - if [ ! -z "$SSL_CERT_FILE" ]; then +if [[ ! -f ./cacert.pem ]]; then + if [[ -n "$SSL_CERT_FILE" ]]; then cp $SSL_CERT_FILE ./cacert.pem echo Using $SSL_CERT_FILE as cacert.pem else echo "Downloading cert from curl" curl -q -L https://curl.se/ca/cacert.pem --output ./cacert.pem - if [ $? -ne 0 ]; then + if [[ $? -ne 0 ]]; then echo "ERROR: Problem downloading cacert.pem file from https://curl.se/ca/cacert.pem" 1>&2 echo "openc3_setup FAILED" 1>&2 exit 1 @@ -65,7 +65,7 @@ cp ./cacert.pem openc3-buckets/cacert.pem cp ./cacert.pem openc3-tsdb/cacert.pem docker --version -if [ "$?" -ne 0 ]; then +if [[ "$?" -ne 0 ]]; then echo "ERROR: docker is not installed, please install and try again." 1>&2 echo "${0} FAILED" 1>&2 exit 1 diff --git a/scripts/linux/openc3_test.sh b/scripts/linux/openc3_test.sh index 7097b22c51..34a6d2c635 100755 --- a/scripts/linux/openc3_test.sh +++ b/scripts/linux/openc3_test.sh @@ -4,7 +4,7 @@ set +e export DOCKER_COMPOSE_COMMAND="docker compose" ${DOCKER_COMPOSE_COMMAND} version -if [ "$?" -ne 0 ]; then +if [[ "$?" -ne 0 ]]; then export DOCKER_COMPOSE_COMMAND="docker-compose" fi @@ -17,18 +17,18 @@ usage() { exit 1 } -if [ "$#" -eq 0 ]; then +if [[ "$#" -eq 0 ]]; then usage $0 fi # Check for help flag -if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then +if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then usage $0 fi case $1 in rspec ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 rspec" echo "" echo "Run RSpec tests against Ruby code in the openc3 directory." @@ -43,7 +43,7 @@ case $1 in ;; playwright ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 playwright [COMMAND]" echo "" echo "Run Playwright end-to-end tests." @@ -95,7 +95,7 @@ case $1 in ;; hash ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 hash" echo "" echo "Run comprehensive Playwright tests with coverage." diff --git a/scripts/linux/openc3_upgrade.sh b/scripts/linux/openc3_upgrade.sh index 09311c4c32..b3c0b371d8 100755 --- a/scripts/linux/openc3_upgrade.sh +++ b/scripts/linux/openc3_upgrade.sh @@ -10,7 +10,7 @@ fi # Determine if this is Core or Enterprise installation REPO_ROOT="$(git rev-parse --show-toplevel)" -if [ -d "$REPO_ROOT/openc3-enterprise-traefik" ]; then +if [[ -d "$REPO_ROOT/openc3-enterprise-traefik" ]]; then IS_ENTERPRISE=true else IS_ENTERPRISE=false @@ -20,7 +20,7 @@ usage() { echo "Usage: openc3.sh upgrade --preview" >&2 echo "e.g. openc3.sh upgrade v6.4.1" >&2 echo "The '--preview' flag will show the diff without applying changes." >&2 - if [ "$IS_ENTERPRISE" = false ]; then + if [[ "$IS_ENTERPRISE" == false ]]; then echo "" >&2 echo "You can also upgrade to Enterprise versions of OpenC3 if you have access" >&2 echo "e.g. openc3.sh upgrade enterprise-v6.4.1" >&2 @@ -30,19 +30,19 @@ usage() { exit 1 } -if [ "$#" -eq 0 ]; then +if [[ "$#" -eq 0 ]]; then usage $0 fi # Check for help flag -if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then +if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then usage $0 fi tag="$1" # Setup the 'cosmos' remote based on IS_ENTERPRISE or if upgrading to enterprise -if [ "$IS_ENTERPRISE" = true ] || echo "$1" | grep -qi "enterprise"; then +if [[ "$IS_ENTERPRISE" == true ]] || echo "$1" | grep -qi "enterprise"; then COSMOS_URL="https://github.com/OpenC3/cosmos-enterprise-project.git" if git remote -v | grep -q '^cosmos[[:space:]]'; then echo "Setting 'cosmos' remote to the enterprise repository." @@ -53,7 +53,7 @@ if [ "$IS_ENTERPRISE" = true ] || echo "$1" | grep -qi "enterprise"; then fi # Warn if upgrading from core to enterprise (but not if just previewing) - if [ "$IS_ENTERPRISE" = false ] && echo "$1" | grep -qi "enterprise" && [ "$2" != "--preview" ]; then + if [[ "$IS_ENTERPRISE" == false ]] && echo "$1" | grep -qi "enterprise" && [[ "$2" != "--preview" ]]; then echo "" >&2 echo "WARNING: You are upgrading from OpenC3 Core to OpenC3 Enterprise." >&2 echo "This is a ONE-WAY operation and CANNOT be undone." >&2 @@ -100,7 +100,7 @@ fi hash="$(git ls-remote cosmos refs/tags/$tag | awk '{print $1}')" # If the --preview flag is set, show the diff without applying changes -if [ "$2" == "--preview" ]; then +if [[ "$2" == "--preview" ]]; then git diff -R $hash exit 0 fi diff --git a/scripts/linux/openc3_util.sh b/scripts/linux/openc3_util.sh index 7cad9b4c2a..7f73e48719 100755 --- a/scripts/linux/openc3_util.sh +++ b/scripts/linux/openc3_util.sh @@ -30,7 +30,7 @@ usage() { } saveTar() { - if [ "$#" -lt 3 ]; then + if [[ "$#" -lt 3 ]]; then echo "Usage: save " >&2 echo "e.g. save docker.io openc3inc 5.1.0" >&2 fi @@ -71,7 +71,7 @@ saveTar() { } loadTar() { - if [ -z "$1" ]; then + if [[ -z "$1" ]]; then tag="latest" else tag=$1 @@ -96,7 +96,7 @@ loadTar() { } tag() { - if [ "$#" -lt 4 ]; then + if [[ "$#" -lt 4 ]]; then echo "Usage: tag " >&2 echo "e.g. tag docker.io localhost:12345 openc3 latest" >&2 echo "Note: NAMESPACE2 and TAG2 default to NAMESPACE1 and TAG1 if not given" >&2 @@ -136,7 +136,7 @@ tag() { } push() { - if [ "$#" -lt 3 ]; then + if [[ "$#" -lt 3 ]]; then echo "Usage: push " >&2 echo "e.g. push localhost:12345 openc3 latest" >&2 exit 1 @@ -173,18 +173,18 @@ cleanFiles() { find . -type f -name "Gemfile.lock" | xargs -I {} rm -i {} } -if [ "$#" -eq 0 ]; then +if [[ "$#" -eq 0 ]]; then usage $0 fi # Check for help flag -if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then +if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then usage $0 fi case $1 in encode ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 encode STRING" echo "" echo "Encode a string to base64." @@ -202,7 +202,7 @@ case $1 in echo -n $2 | base64 ;; hash ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 hash STRING" echo "" echo "Hash a string using SHA-256." @@ -220,7 +220,7 @@ case $1 in echo -n $2 | shasum -a 256 | sed 's/-//' ;; save ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 save REPO NAMESPACE TAG [SUFFIX]" echo "" echo "Pull and save all OpenC3 docker images to tar files in tmp/ directory." @@ -241,7 +241,7 @@ case $1 in saveTar "${@:2}" ;; load ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 load [TAG] [SUFFIX]" echo "" echo "Load OpenC3 docker images from tar files in tmp/ directory." @@ -260,7 +260,7 @@ case $1 in loadTar "${@:2}" ;; tag ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 tag REPO1 REPO2 NAMESPACE1 TAG1 [NAMESPACE2] [TAG2] [SUFFIX]" echo "" echo "Tag OpenC3 images from one repository to another." @@ -284,7 +284,7 @@ case $1 in tag "${@:2}" ;; push ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 push REPO NAMESPACE TAG [SUFFIX]" echo "" echo "Push all OpenC3 images to a docker repository." @@ -305,7 +305,7 @@ case $1 in push "${@:2}" ;; clean ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 clean" echo "" echo "Clean up development files from the project." @@ -323,7 +323,7 @@ case $1 in cleanFiles ;; hostsetup ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 hostsetup REPO NAMESPACE TAG" echo "" echo "Configure Docker host for Redis optimal performance." @@ -344,7 +344,7 @@ case $1 in echo " -h, --help Show this help message" exit 0 fi - if [ "$#" -ne 4 ]; then + if [[ "$#" -ne 4 ]]; then echo "Usage: hostsetup " >&2 echo "e.g. hostsetup docker.io openc3inc latest" >&2 exit 1 @@ -357,7 +357,7 @@ case $1 in docker run --rm --privileged --pid=host --entrypoint='' --user root $repo/$namespace/openc3-operator:$tag nsenter -t 1 -m -u -n -i -- sh -c "sysctl -w vm.max_map_count=262144" ;; hostenter ) - if [ "$2" == "--help" ] || [ "$2" == "-h" ]; then + if [[ "$2" == "--help" ]] || [[ "$2" == "-h" ]]; then echo "Usage: $0 hostenter" echo "" echo "Enter a shell on the Docker VM host." diff --git a/scripts/release/build_multi_arch.sh b/scripts/release/build_multi_arch.sh index ed423387d9..76b0fba71e 100755 --- a/scripts/release/build_multi_arch.sh +++ b/scripts/release/build_multi_arch.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # TODO: Can this script be replaced by https://github.com/docker/build-push-action @@ -26,7 +26,7 @@ eval $(sed -e '/^#/d' -e 's/^/export /' -e 's/$/;/' .env) ; # OPENC3_ENTERPRISE_REGISTRY=localhost:5000 # Uncomment for local builds # check if the first parameter is 'ubi' -if [ "${1:-default}" = "ubi" ]; then +if [[ "${1:-default}" == "ubi" ]]; then OPENC3_PLATFORMS=linux/amd64 DOCKERFILE='Dockerfile-ubi' SUFFIX='-ubi' @@ -41,7 +41,7 @@ fi # Setup cacert.pem echo "Downloading cert from curl" curl -q -L https://curl.se/ca/cacert.pem --output ./cacert.pem -if [ $? -ne 0 ]; then +if [[ $? -ne 0 ]]; then echo "ERROR: Problem downloading cacert.pem file from https://curl.se/ca/cacert.pem" 1>&2 echo "openc3_setup FAILED" 1>&2 exit 1 @@ -72,7 +72,7 @@ docker buildx build \ --push -t ${OPENC3_REGISTRY}/${OPENC3_NAMESPACE}/openc3-ruby${SUFFIX}:${OPENC3_RELEASE_VERSION} \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-ruby${SUFFIX}:${OPENC3_RELEASE_VERSION} . -if [ $OPENC3_UPDATE_LATEST = true ] +if [[ $OPENC3_UPDATE_LATEST == true ]] then docker buildx build \ --file ${DOCKERFILE} \ @@ -103,7 +103,7 @@ docker buildx build \ --push -t ${OPENC3_REGISTRY}/${OPENC3_NAMESPACE}/openc3-base${SUFFIX}:${OPENC3_RELEASE_VERSION} \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-base${SUFFIX}:${OPENC3_RELEASE_VERSION} . -if [ $OPENC3_UPDATE_LATEST = true ] +if [[ $OPENC3_UPDATE_LATEST == true ]] then docker buildx build \ --file ${DOCKERFILE} \ @@ -129,7 +129,7 @@ docker buildx build \ --push -t ${OPENC3_REGISTRY}/${OPENC3_NAMESPACE}/openc3-node${SUFFIX}:${OPENC3_RELEASE_VERSION} \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-node${SUFFIX}:${OPENC3_RELEASE_VERSION} . -if [ $OPENC3_UPDATE_LATEST = true ] +if [[ $OPENC3_UPDATE_LATEST == true ]] then docker buildx build \ --file ${DOCKERFILE} \ @@ -145,7 +145,7 @@ fi # Note: Missing OPENC3_REGISTRY build-arg intentionally to default to docker.io cd ../openc3-redis -if [ "${1:-default}" = "ubi" ]; then +if [[ "${1:-default}" == "ubi" ]]; then # UBI build uses Dockerfile-ubi which builds Valkey from source docker buildx build \ --file Dockerfile-ubi \ @@ -157,7 +157,7 @@ if [ "${1:-default}" = "ubi" ]; then --push -t ${OPENC3_REGISTRY}/${OPENC3_NAMESPACE}/openc3-redis${SUFFIX}:${OPENC3_RELEASE_VERSION} \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-redis${SUFFIX}:${OPENC3_RELEASE_VERSION} . - if [ $OPENC3_UPDATE_LATEST = true ] + if [[ $OPENC3_UPDATE_LATEST == true ]] then docker buildx build \ --file Dockerfile-ubi \ @@ -180,7 +180,7 @@ else --push -t ${OPENC3_REGISTRY}/${OPENC3_NAMESPACE}/openc3-redis${SUFFIX}:${OPENC3_RELEASE_VERSION} \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-redis${SUFFIX}:${OPENC3_RELEASE_VERSION} . - if [ $OPENC3_UPDATE_LATEST = true ] + if [[ $OPENC3_UPDATE_LATEST == true ]] then docker buildx build \ --platform ${OPENC3_PLATFORMS} \ @@ -193,7 +193,7 @@ else fi fi -if [ "${1:-default}" = "ubi" ]; then +if [[ "${1:-default}" == "ubi" ]]; then OPENC3_TSDB_VERSION_EXT="-rhel" else OPENC3_TSDB_VERSION_EXT="" @@ -206,7 +206,7 @@ docker buildx build \ --push -t ${OPENC3_REGISTRY}/${OPENC3_NAMESPACE}/openc3-tsdb${SUFFIX}:${OPENC3_RELEASE_VERSION} \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-tsdb${SUFFIX}:${OPENC3_RELEASE_VERSION} . -if [ $OPENC3_UPDATE_LATEST = true ] +if [[ $OPENC3_UPDATE_LATEST == true ]] then docker buildx build \ --platform ${OPENC3_PLATFORMS} \ @@ -229,7 +229,7 @@ docker buildx build \ --push -t ${OPENC3_REGISTRY}/${OPENC3_NAMESPACE}/openc3-buckets${SUFFIX}:${OPENC3_RELEASE_VERSION} \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-buckets${SUFFIX}:${OPENC3_RELEASE_VERSION} . -if [ $OPENC3_UPDATE_LATEST = true ] +if [[ $OPENC3_UPDATE_LATEST == true ]] then docker buildx build \ --file ${DOCKERFILE} \ @@ -256,7 +256,7 @@ docker buildx build \ --push -t ${OPENC3_REGISTRY}/${OPENC3_NAMESPACE}/openc3-cosmos-cmd-tlm-api${SUFFIX}:${OPENC3_RELEASE_VERSION} \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-cosmos-cmd-tlm-api${SUFFIX}:${OPENC3_RELEASE_VERSION} . -if [ $OPENC3_UPDATE_LATEST = true ] +if [[ $OPENC3_UPDATE_LATEST == true ]] then docker buildx build \ --file ${DOCKERFILE} \ @@ -282,7 +282,7 @@ docker buildx build \ --push -t ${OPENC3_REGISTRY}/${OPENC3_NAMESPACE}/openc3-cosmos-script-runner-api${SUFFIX}:${OPENC3_RELEASE_VERSION} \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-cosmos-script-runner-api${SUFFIX}:${OPENC3_RELEASE_VERSION} . -if [ $OPENC3_UPDATE_LATEST = true ] +if [[ $OPENC3_UPDATE_LATEST == true ]] then docker buildx build \ --file ${DOCKERFILE} \ @@ -307,7 +307,7 @@ docker buildx build \ --push -t ${OPENC3_REGISTRY}/${OPENC3_NAMESPACE}/openc3-operator${SUFFIX}:${OPENC3_RELEASE_VERSION} \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-operator${SUFFIX}:${OPENC3_RELEASE_VERSION} . -if [ $OPENC3_UPDATE_LATEST = true ] +if [[ $OPENC3_UPDATE_LATEST == true ]] then docker buildx build \ --platform ${OPENC3_PLATFORMS} \ @@ -321,7 +321,7 @@ docker buildx build \ fi # Note: Missing OPENC3_REGISTRY build-arg intentionally to default to docker.io -if [ "${1:-default}" = "ubi" ]; then +if [[ "${1:-default}" == "ubi" ]]; then OPENC3_DEPENDENCY_REGISTRY=${OPENC3_UBI_REGISTRY}/ironbank/opensource/traefik OPENC3_TRAEFIK_RELEASE=v3.6.5 else @@ -336,7 +336,7 @@ docker buildx build \ --push -t ${OPENC3_REGISTRY}/${OPENC3_NAMESPACE}/openc3-traefik${SUFFIX}:${OPENC3_RELEASE_VERSION} \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-traefik${SUFFIX}:${OPENC3_RELEASE_VERSION} . -if [ $OPENC3_UPDATE_LATEST = true ] +if [[ $OPENC3_UPDATE_LATEST == true ]] then docker buildx build \ --platform ${OPENC3_PLATFORMS} \ @@ -347,7 +347,7 @@ docker buildx build \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-traefik${SUFFIX}:latest . fi -if [ "${1:-default}" = "ubi" ]; then +if [[ "${1:-default}" == "ubi" ]]; then OPENC3_DEPENDENCY_REGISTRY=${OPENC3_UBI_REGISTRY}/ironbank/opensource fi cd ../openc3-cosmos-init @@ -365,7 +365,7 @@ docker buildx build \ --push -t ${OPENC3_REGISTRY}/${OPENC3_NAMESPACE}/openc3-cosmos-init${SUFFIX}:${OPENC3_RELEASE_VERSION} \ --push -t ${OPENC3_ENTERPRISE_REGISTRY}/${OPENC3_ENTERPRISE_NAMESPACE}/openc3-cosmos-init${SUFFIX}:${OPENC3_RELEASE_VERSION} . -if [ $OPENC3_UPDATE_LATEST = true ] +if [[ $OPENC3_UPDATE_LATEST == true ]] then docker buildx build \ --platform ${OPENC3_PLATFORMS} \ From 2101fc5c2e935a7aa9e3e0242b57340391fb407a Mon Sep 17 00:00:00 2001 From: Jason Thomas Date: Thu, 15 Jan 2026 18:03:14 -0700 Subject: [PATCH 2/5] Fix static code analysis issues - logger.py: Rename DEBUG/INFO/WARN/ERROR/FATAL to DEBUG_VALUE/INFO_VALUE/ WARN_VALUE/ERROR_VALUE/FATAL_VALUE to avoid clash with method names. Keep old names as backwards compatibility aliases. - packet_item.py: Rename STATE_COLORS to VALID_STATE_COLORS to avoid clash with state_colors instance attribute. - packet_config.py: Rename COMMAND/TELEMETRY to COMMAND_STRING/ TELEMETRY_STRING to avoid clash with commands/telemetry attributes. - Openc3Screen.vue: Add "falls through" comments for intentional switch case fallthrough in SUBSETTING and GLOBAL_SUBSETTING cases. Co-Authored-By: Claude Opus 4.5 --- .../src/components/Openc3Screen.vue | 4 +- openc3/python/openc3/packets/packet_config.py | 36 ++++++++-------- openc3/python/openc3/packets/packet_item.py | 4 +- .../openc3/packets/parsers/state_parser.py | 6 +-- .../tools/table_manager/table_item_parser.py | 4 +- openc3/python/openc3/utilities/logger.py | 43 +++++++++++++------ 6 files changed, 57 insertions(+), 40 deletions(-) diff --git a/openc3-cosmos-init/plugins/packages/openc3-vue-common/src/components/Openc3Screen.vue b/openc3-cosmos-init/plugins/packages/openc3-vue-common/src/components/Openc3Screen.vue index 1be41e2b21..dc6208339a 100644 --- a/openc3-cosmos-init/plugins/packages/openc3-vue-common/src/components/Openc3Screen.vue +++ b/openc3-cosmos-init/plugins/packages/openc3-vue-common/src/components/Openc3Screen.vue @@ -13,7 +13,7 @@ # GNU Affero General Public License for more details. # Modified by OpenC3, Inc. -# All changes Copyright 2025, OpenC3, Inc. +# All changes Copyright 2026, OpenC3, Inc. # All Rights Reserved # # This file may also be used under the terms of a commercial license @@ -587,6 +587,7 @@ export default { if (parameters[1] === 'RAW') { parameters[1] = 'RAW__' + parameters[2].toLowerCase() } + // falls through case 'SETTING': this.configParser.verify_num_parameters( 2, @@ -628,6 +629,7 @@ export default { if (parameters[2] === 'RAW') { parameters[2] = 'RAW__' + parameters[3].toLowerCase() } + // falls through case 'GLOBAL_SETTING': this.configParser.verify_num_parameters( 2, diff --git a/openc3/python/openc3/packets/packet_config.py b/openc3/python/openc3/packets/packet_config.py index 1225032b37..97e5de28ea 100644 --- a/openc3/python/openc3/packets/packet_config.py +++ b/openc3/python/openc3/packets/packet_config.py @@ -1,4 +1,4 @@ -# Copyright 2025 OpenC3, Inc. +# Copyright 2026 OpenC3, Inc. # All Rights Reserved. # # This program is free software; you can modify and/or redistribute it @@ -45,8 +45,8 @@ class PacketConfig: - COMMAND = "Command" - TELEMETRY = "Telemetry" + COMMAND_STRING = "Command" + TELEMETRY_STRING = "Telemetry" # Note: DERIVED is not a valid converted type. Also TIME is currently only a converted type CONVERTED_DATA_TYPES = ["INT", "UINT", "FLOAT", "STRING", "BLOCK", "BOOL", "OBJECT", "ARRAY", "ANY", "TIME"] @@ -152,7 +152,7 @@ def process_file(self, filename, process_target_name): self.current_packet = PacketParser.parse_command( parser, process_target_name, self.commands, self.warnings ) - self.current_cmd_or_tlm = PacketConfig.COMMAND + self.current_cmd_or_tlm = PacketConfig.COMMAND_STRING case "TELEMETRY": self.finish_packet() @@ -163,7 +163,7 @@ def process_file(self, filename, process_target_name): self.latest_data, self.warnings, ) - self.current_cmd_or_tlm = PacketConfig.TELEMETRY + self.current_cmd_or_tlm = PacketConfig.TELEMETRY_STRING # Select an existing packet for editing case "SELECT_COMMAND" | "SELECT_TELEMETRY": @@ -177,11 +177,11 @@ def process_file(self, filename, process_target_name): self.current_packet = None if "COMMAND" in keyword: - self.current_cmd_or_tlm = PacketConfig.COMMAND + self.current_cmd_or_tlm = PacketConfig.COMMAND_STRING if self.commands.get(target_name): self.current_packet = self.commands[target_name][packet_name] else: - self.current_cmd_or_tlm = PacketConfig.TELEMETRY + self.current_cmd_or_tlm = PacketConfig.TELEMETRY_STRING if self.telemetry.get(target_name): self.current_packet = self.telemetry[target_name][packet_name] @@ -401,7 +401,7 @@ def finish_packet(self): warnings = self.current_packet.check_bit_offsets() if len(warnings) > 0: self.warnings += warnings - if self.current_cmd_or_tlm == PacketConfig.COMMAND: + if self.current_cmd_or_tlm == PacketConfig.COMMAND_STRING: PacketParser.check_item_data_types(self.current_packet) self.commands[self.current_packet.target_name][self.current_packet.packet_name] = self.current_packet if not self.current_packet.virtual: @@ -556,9 +556,9 @@ def process_current_packet(self, parser, keyword, params): match keyword: # Select or delete an item in the current packet case "SELECT_PARAMETER" | "SELECT_ITEM" | "DELETE_PARAMETER" | "DELETE_ITEM": - if (self.current_cmd_or_tlm == PacketConfig.COMMAND) and (keyword.split("_")[1] == "ITEM"): + if (self.current_cmd_or_tlm == PacketConfig.COMMAND_STRING) and (keyword.split("_")[1] == "ITEM"): raise parser.error(f"{keyword} only applies to telemetry packets") - if (self.current_cmd_or_tlm == PacketConfig.TELEMETRY) and (keyword.split("_")[1] == "PARAMETER"): + if (self.current_cmd_or_tlm == PacketConfig.TELEMETRY_STRING) and (keyword.split("_")[1] == "PARAMETER"): raise parser.error(f"{keyword} only applies to command packets") usage = f"{keyword} <{keyword.split('_')[1]} NAME>" @@ -738,14 +738,14 @@ def process_current_packet(self, parser, keyword, params): case "RESPONSE": usage = f"{keyword} " parser.verify_num_parameters(2, 2, usage) - if self.current_cmd_or_tlm == PacketConfig.TELEMETRY: + if self.current_cmd_or_tlm == PacketConfig.TELEMETRY_STRING: raise parser.error(f"{keyword} only applies to command packets") self.current_packet.response = [params[0].upper(), params[1].upper()] case "ERROR_RESPONSE": usage = f"{keyword} " parser.verify_num_parameters(2, 2, usage) - if self.current_cmd_or_tlm == PacketConfig.TELEMETRY: + if self.current_cmd_or_tlm == PacketConfig.TELEMETRY_STRING: raise parser.error(f"{keyword} only applies to command packets") self.current_packet.error_response = [ params[0].upper(), @@ -755,14 +755,14 @@ def process_current_packet(self, parser, keyword, params): case "SCREEN": usage = f"{keyword} " parser.verify_num_parameters(2, 2, usage) - if self.current_cmd_or_tlm == PacketConfig.TELEMETRY: + if self.current_cmd_or_tlm == PacketConfig.TELEMETRY_STRING: raise parser.error(f"{keyword} only applies to command packets") self.current_packet.screen = [params[0].upper(), params[1].upper()] case "RELATED_ITEM": usage = f"{keyword} " parser.verify_num_parameters(3, 3, usage) - if self.current_cmd_or_tlm == PacketConfig.TELEMETRY: + if self.current_cmd_or_tlm == PacketConfig.TELEMETRY_STRING: raise parser.error(f"{keyword} only applies to command packets") if not self.current_packet.related_items: self.current_packet.related_items = [] @@ -913,14 +913,14 @@ def process_current_item(self, parser, keyword, params): case "REQUIRED": usage = "REQUIRED" parser.verify_num_parameters(0, 0, usage) - if self.current_cmd_or_tlm == PacketConfig.COMMAND: + if self.current_cmd_or_tlm == PacketConfig.COMMAND_STRING: self.current_item.required = True else: raise parser.error(f"{keyword} only applies to command parameters") # Update the minimum value for the current command parameter case "MINIMUM_VALUE": - if self.current_cmd_or_tlm == PacketConfig.TELEMETRY: + if self.current_cmd_or_tlm == PacketConfig.TELEMETRY_STRING: raise parser.error(f"{keyword} only applies to command parameters") usage = "MINIMUM_VALUE " @@ -934,7 +934,7 @@ def process_current_item(self, parser, keyword, params): # Update the maximum value for the current command parameter case "MAXIMUM_VALUE": - if self.current_cmd_or_tlm == PacketConfig.TELEMETRY: + if self.current_cmd_or_tlm == PacketConfig.TELEMETRY_STRING: raise parser.error(f"{keyword} only applies to command parameters") usage = "MAXIMUM_VALUE " @@ -1000,7 +1000,7 @@ def finish_item(self): if not self.current_packet: raise RuntimeError("Cannot finish item without a current packet") self.current_packet.set_item(self.current_item) - if self.current_cmd_or_tlm == PacketConfig.TELEMETRY: + if self.current_cmd_or_tlm == PacketConfig.TELEMETRY_STRING: target_latest_data = self.latest_data[self.current_packet.target_name] if not target_latest_data.get(self.current_item.name): target_latest_data[self.current_item.name] = [] diff --git a/openc3/python/openc3/packets/packet_item.py b/openc3/python/openc3/packets/packet_item.py index 193d965f21..cee332e870 100644 --- a/openc3/python/openc3/packets/packet_item.py +++ b/openc3/python/openc3/packets/packet_item.py @@ -1,4 +1,4 @@ -# Copyright 2024 OpenC3, Inc. +# Copyright 2026 OpenC3, Inc. # All Rights Reserved. # # This program is free software; you can modify and/or redistribute it @@ -24,7 +24,7 @@ class PacketItem(StructureItem): # The allowable state colors - STATE_COLORS = ["GREEN", "YELLOW", "RED"] + VALID_STATE_COLORS = ["GREEN", "YELLOW", "RED"] def __init__( self, diff --git a/openc3/python/openc3/packets/parsers/state_parser.py b/openc3/python/openc3/packets/parsers/state_parser.py index ffed7c0006..c1d66bf093 100644 --- a/openc3/python/openc3/packets/parsers/state_parser.py +++ b/openc3/python/openc3/packets/parsers/state_parser.py @@ -1,4 +1,4 @@ -# Copyright 2023 OpenC3, Inc. +# Copyright 2026 OpenC3, Inc. # All Rights Reserved. # # This program is free software; you can modify and/or redistribute it @@ -125,9 +125,9 @@ def _get_hazardous_or_disable_messages(self, item): def _get_state_colors(self, item): color = self.parser.parameters[2].upper() - if color not in PacketItem.STATE_COLORS: + if color not in PacketItem.VALID_STATE_COLORS: raise self.parser.error( - f"Invalid state color {color}. Must be one of {' '.join(PacketItem.STATE_COLORS)}.", + f"Invalid state color {color}. Must be one of {' '.join(PacketItem.VALID_STATE_COLORS)}.", self.usage, ) diff --git a/openc3/python/openc3/tools/table_manager/table_item_parser.py b/openc3/python/openc3/tools/table_manager/table_item_parser.py index b7cab457dd..847767a419 100644 --- a/openc3/python/openc3/tools/table_manager/table_item_parser.py +++ b/openc3/python/openc3/tools/table_manager/table_item_parser.py @@ -1,4 +1,4 @@ -# Copyright 2025 OpenC3, Inc. +# Copyright 2026 OpenC3, Inc. # All Rights Reserved. # # This program is free software; you can modify and/or redistribute it @@ -39,7 +39,7 @@ def parse(cls, parser, table_config, table, warnings): The created TableItem """ parser = cls(parser, table_config, warnings) - parser.verify_parameters(PacketConfig.COMMAND) + parser.verify_parameters(PacketConfig.COMMAND_STRING) return parser.create_table_item(table) def create_table_item(self, table): diff --git a/openc3/python/openc3/utilities/logger.py b/openc3/python/openc3/utilities/logger.py index 06fae9ca59..b111104395 100644 --- a/openc3/python/openc3/utilities/logger.py +++ b/openc3/python/openc3/utilities/logger.py @@ -1,4 +1,4 @@ -# Copyright 2025 OpenC3, Inc. +# Copyright 2026 OpenC3, Inc. # All Rights Reserved. # # This program is free software; you can modify and/or redistribute it @@ -29,6 +29,12 @@ "my_instance", "scope", "__dict__", + "DEBUG_VALUE", + "INFO_VALUE", + "WARN_VALUE", + "ERROR_VALUE", + "FATAL_VALUE", + # Backwards compatibility aliases "DEBUG", "INFO", "WARN", @@ -90,11 +96,20 @@ class Logger(metaclass=LoggerMeta): my_instance = None scope = OPENC3_SCOPE - DEBUG = 0 - INFO = 1 - WARN = 2 - ERROR = 3 - FATAL = 4 + # These were renamed from simply DEBUG, INFO, etc. to avoid confusion with the log levels themselves. + # The old names are still supported as aliases for backwards compatibility. + DEBUG_VALUE = 0 + INFO_VALUE = 1 + WARN_VALUE = 2 + ERROR_VALUE = 3 + FATAL_VALUE = 4 + + # Backwards compatibility aliases for numeric levels + DEBUG = DEBUG_VALUE + INFO = INFO_VALUE + WARN = WARN_VALUE + ERROR = ERROR_VALUE + FATAL = FATAL_VALUE DEBUG_LEVEL = "DEBUG" INFO_LEVEL = "INFO" @@ -108,7 +123,7 @@ class Logger(metaclass=LoggerMeta): EPHEMERAL = "ephemeral" # @param level [Integer] The initial logging level - def __init__(self, level=INFO): + def __init__(self, level=INFO_VALUE): self.stdout = True self.level = level self.detail_string = None @@ -121,7 +136,7 @@ def __init__(self, level=INFO): # Get the singleton instance @classmethod - def instance(cls, level=INFO): + def instance(cls, level=INFO_VALUE): if cls.my_instance: return cls.my_instance @@ -135,7 +150,7 @@ def instance(cls, level=INFO): # to the log message def debug(self, message=None, scope=None, user=None, type=LOG, url=None, other=None): scope = scope or self.scope - if self.level <= self.DEBUG: + if self.level <= self.DEBUG_VALUE: self.log_message( self.DEBUG_LEVEL, message, @@ -149,7 +164,7 @@ def debug(self, message=None, scope=None, user=None, type=LOG, url=None, other=N # (see #debug) def info(self, message=None, scope=None, user=None, type=LOG, url=None, other=None): scope = scope or self.scope - if self.level <= self.INFO: + if self.level <= self.INFO_VALUE: self.log_message( self.INFO_LEVEL, message, @@ -163,7 +178,7 @@ def info(self, message=None, scope=None, user=None, type=LOG, url=None, other=No # (see #debug) def warn(self, message=None, scope=None, user=None, type=LOG, url=None, other=None): scope = scope or self.scope - if self.level <= self.WARN: + if self.level <= self.WARN_VALUE: self.log_message( self.WARN_LEVEL, message, @@ -177,7 +192,7 @@ def warn(self, message=None, scope=None, user=None, type=LOG, url=None, other=No # (see #debug) def error(self, message=None, scope=None, user=None, type=LOG, url=None, other=None): scope = scope or self.scope - if self.level <= self.ERROR: + if self.level <= self.ERROR_VALUE: self.log_message( self.ERROR_LEVEL, message, @@ -191,7 +206,7 @@ def error(self, message=None, scope=None, user=None, type=LOG, url=None, other=N # (see #debug) def fatal(self, message=None, scope=None, user=None, type=LOG, url=None, other=None): scope = scope or self.scope - if self.level <= self.FATAL: + if self.level <= self.FATAL_VALUE: self.log_message( self.FATAL_LEVEL, message, @@ -232,7 +247,7 @@ def log_message(self, log_level: str, message: str | None, scope, user, type, ur with self.instance_mutex: data = self.build_log_data(log_level, message, user, type, url, other) if self.stdout: - if (log_level in ['WARN', 'ERROR', 'FATAL']) and OPENC3_LOG_STDERR: + if (log_level in ["WARN", "ERROR", "FATAL"]) and OPENC3_LOG_STDERR: io = sys.stderr else: io = sys.stdout From 8f98c243ee6c9c3420ad7a703d11ebaaec122ac6 Mon Sep 17 00:00:00 2001 From: Jason Thomas Date: Thu, 15 Jan 2026 18:11:26 -0700 Subject: [PATCH 3/5] Add NOSONAR comments for intentional Thread.current usage Thread-local storage is used intentionally for: - Pipeline context tracking in Redis operations - Topic offset tracking per-thread for stream reading These are well-established Ruby patterns with proper cleanup. Co-Authored-By: Claude Opus 4.5 --- openc3/lib/openc3/microservices/microservice.rb | 4 ++-- openc3/lib/openc3/utilities/store_autoload.rb | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openc3/lib/openc3/microservices/microservice.rb b/openc3/lib/openc3/microservices/microservice.rb index 4a9f0072b7..8c03fe03d2 100644 --- a/openc3/lib/openc3/microservices/microservice.rb +++ b/openc3/lib/openc3/microservices/microservice.rb @@ -241,8 +241,8 @@ def shutdown(state = 'STOPPED') def setup_microservice_topic @topics.append(@microservice_topic) - Thread.current[:topic_offsets] ||= {} - topic_offsets = Thread.current[:topic_offsets] + Thread.current[:topic_offsets] ||= {} # NOSONAR - Thread-local used for topic offset tracking + topic_offsets = Thread.current[:topic_offsets] # NOSONAR topic_offsets[@microservice_topic] = "0-0" # Always get all available end diff --git a/openc3/lib/openc3/utilities/store_autoload.rb b/openc3/lib/openc3/utilities/store_autoload.rb index 8b78007bbd..e61bb854f2 100644 --- a/openc3/lib/openc3/utilities/store_autoload.rb +++ b/openc3/lib/openc3/utilities/store_autoload.rb @@ -14,7 +14,7 @@ # GNU Affero General Public License for more details. # Modified by OpenC3, Inc. -# All changes Copyright 2022, OpenC3, Inc. +# All changes Copyright 2026, OpenC3, Inc. # All Rights Reserved # # This file may also be used under the terms of a commercial license @@ -42,11 +42,11 @@ def pipelined else with(NO_OPTIONS) do |redis| redis.pipelined do |pipeline| - Thread.current[:pipeline] = pipeline + Thread.current[:pipeline] = pipeline # NOSONAR - Thread-local used for pipeline context tracking begin yield ensure - Thread.current[:pipeline] = nil + Thread.current[:pipeline] = nil # NOSONAR end end end @@ -54,7 +54,7 @@ def pipelined end def with(options = NO_OPTIONS, &block) - pipeline = Thread.current[:pipeline] + pipeline = Thread.current[:pipeline] # NOSONAR if pipeline yield pipeline else @@ -152,8 +152,8 @@ def update_topic_offsets(topics) topics.each do |topic| # Normally we will just be grabbing the topic offset # this allows xread to get everything past this point - Thread.current[:topic_offsets] ||= {} - topic_offsets = Thread.current[:topic_offsets] + Thread.current[:topic_offsets] ||= {} # NOSONAR - Thread-local used for topic offset tracking + topic_offsets = Thread.current[:topic_offsets] # NOSONAR last_id = topic_offsets[topic] if last_id offsets << last_id @@ -170,8 +170,8 @@ def update_topic_offsets(topics) unless $openc3_redis_cluster def read_topics(topics, offsets = nil, timeout_ms = 1000, count = nil) return {} if topics.empty? - Thread.current[:topic_offsets] ||= {} - topic_offsets = Thread.current[:topic_offsets] + Thread.current[:topic_offsets] ||= {} # NOSONAR - Thread-local used for topic offset tracking + topic_offsets = Thread.current[:topic_offsets] # NOSONAR begin # Logger.debug "read_topics: #{topics}, #{offsets} pool:#{@redis_pool}" @redis_pool.with do |redis| From 7a632be0f00f1fbb8f458e3577911f1478f5fca7 Mon Sep 17 00:00:00 2001 From: Jason Thomas Date: Thu, 15 Jan 2026 18:32:25 -0700 Subject: [PATCH 4/5] Fix python tests --- .../packages/openc3-vue-common/src/tools/base/Login.vue | 6 +++--- openc3/python/openc3/tools/table_manager/table_config.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openc3-cosmos-init/plugins/packages/openc3-vue-common/src/tools/base/Login.vue b/openc3-cosmos-init/plugins/packages/openc3-vue-common/src/tools/base/Login.vue index 140fc3d63d..f68b7860d0 100644 --- a/openc3-cosmos-init/plugins/packages/openc3-vue-common/src/tools/base/Login.vue +++ b/openc3-cosmos-init/plugins/packages/openc3-vue-common/src/tools/base/Login.vue @@ -13,7 +13,7 @@ # GNU Affero General Public License for more details. # Modified by OpenC3, Inc. -# All changes Copyright 2024, OpenC3, Inc. +# All changes Copyright 2026, OpenC3, Inc. # All Rights Reserved # # This file may also be used under the terms of a commercial license @@ -64,10 +64,10 @@ Login @@ -150,7 +150,7 @@ export default { login: function (response) { localStorage.openc3Token = response.data const redirect = new URLSearchParams(window.location.search).get( - 'redirect' + 'redirect', ) if (redirect?.startsWith('/tools/')) { // Valid relative redirect URL diff --git a/openc3/python/openc3/tools/table_manager/table_config.py b/openc3/python/openc3/tools/table_manager/table_config.py index 74a27e1bf7..aff080d7c3 100644 --- a/openc3/python/openc3/tools/table_manager/table_config.py +++ b/openc3/python/openc3/tools/table_manager/table_config.py @@ -1,4 +1,4 @@ -# Copyright 2025 OpenC3, Inc. +# Copyright 2026 OpenC3, Inc. # All Rights Reserved. # # This program is free software; you can modify and/or redistribute it @@ -161,7 +161,7 @@ def _process_file(self, filename): self.finish_packet() self.current_packet = TableParser.parse_table(parser, self.commands, self.warnings) self.definitions[self.current_packet.packet_name] = self.last_config - self.current_cmd_or_tlm = self.COMMAND + self.current_cmd_or_tlm = PacketConfig.COMMAND_STRING self.default_index = 0 # Select an existing table for editing From ff8231c54aaf521e28f30c346e8f6c27cccc6545 Mon Sep 17 00:00:00 2001 From: Jason Thomas Date: Thu, 15 Jan 2026 20:43:09 -0700 Subject: [PATCH 5/5] Address minor sonarqube security issues & add copywright headers --- .github/codeql-config.yml | 16 ++++++++++ .github/dependabot.yml | 16 ++++++++++ .github/workflows/api_tests.yml | 21 ++++++++----- .github/workflows/build_ubi.yml | 26 ++++++++++++---- .github/workflows/clamav.yml | 19 +++++++++--- .github/workflows/cli.yml | 19 +++++++++--- .github/workflows/codeql.yaml | 16 ++++++++++ .github/workflows/eslint.yml | 18 ++++++++++- .github/workflows/generate-docs.yml | 16 ++++++++++ .../workflows/playwright-firefox-nightly.yml | 16 ++++++++++ .github/workflows/playwright.yml | 19 +++++++++--- .github/workflows/post_release_clamav.yml | 19 +++++++++--- .github/workflows/post_release_trivy.yml | 19 +++++++++--- .github/workflows/python_unit_tests.yml | 21 ++++++++----- .github/workflows/release.yml | 30 ++++++++++++++----- .github/workflows/ruby_unit_tests.yml | 21 ++++++++----- .github/workflows/spelling.yml | 16 ++++++++++ .github/workflows/tool.yml | 19 +++++++++--- .github/workflows/trivy.yml | 19 +++++++++--- openc3/python/openc3/io/udp_sockets.py | 6 ++-- 20 files changed, 308 insertions(+), 64 deletions(-) diff --git a/.github/codeql-config.yml b/.github/codeql-config.yml index 9bb15f1fb2..43ee53f287 100644 --- a/.github/codeql-config.yml +++ b/.github/codeql-config.yml @@ -1,3 +1,19 @@ +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. + name: COSMOS CodeQL paths-ignore: # The templates include ERB and therefore aren't scanable diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a2e25c476f..0a216a8d7c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,3 +1,19 @@ +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. + version: 2 updates: # Maintain dependencies for GitHub Actions diff --git a/.github/workflows/api_tests.yml b/.github/workflows/api_tests.yml index 069123158f..3cb450bff7 100644 --- a/.github/workflows/api_tests.yml +++ b/.github/workflows/api_tests.yml @@ -1,11 +1,18 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. -# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake -# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. -# Reference environment variables: https://docs.github.com/en/actions/reference/environment-variables +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. name: API Tests diff --git a/.github/workflows/build_ubi.yml b/.github/workflows/build_ubi.yml index 3e48516a04..3974d26b20 100644 --- a/.github/workflows/build_ubi.yml +++ b/.github/workflows/build_ubi.yml @@ -1,7 +1,18 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. name: Build UBI @@ -28,7 +39,12 @@ jobs: - name: login to ironbank # This `shell` line is required to get around a known issue: https://github.com/actions/runner/issues/241#issuecomment-745902718 shell: 'script -q -e -c "bash {0}"' - run: echo ${{ secrets.IRONBANK_REGISTRY_CLI }} | docker login registry1.dso.mil -u jmthomas --password-stdin + env: + # Create ENV variable for the IronBank registry CLI token, which is stored as a secret in GitHub + # This is done to avoid expanding secrets directly in a run block + # where they may be exposed in process lists, shell history, or files. + IRONBANK_REGISTRY_CLI: ${{ secrets.IRONBANK_REGISTRY_CLI }} + run: echo "$IRONBANK_REGISTRY_CLI" | docker login registry1.dso.mil -u jmthomas --password-stdin - name: openc3.sh build-ubi # This `shell` line is required to get around a known issue: https://github.com/actions/runner/issues/241#issuecomment-745902718 shell: 'script -q -e -c "bash {0}"' diff --git a/.github/workflows/clamav.yml b/.github/workflows/clamav.yml index 7a7b28010f..d32ad393f2 100644 --- a/.github/workflows/clamav.yml +++ b/.github/workflows/clamav.yml @@ -1,7 +1,18 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. name: ClamAV Scan diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml index 8a1edf07c5..596e41979d 100644 --- a/.github/workflows/cli.yml +++ b/.github/workflows/cli.yml @@ -1,7 +1,18 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. name: CLI Tests diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 64a806a51c..ee9ff70a49 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -1,3 +1,19 @@ +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. + # Generated by Github via https://github.com/OpenC3/cosmos/actions/new?category=security name: CodeQL diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml index f0393b5f43..95d792d3c9 100644 --- a/.github/workflows/eslint.yml +++ b/.github/workflows/eslint.yml @@ -1,9 +1,25 @@ +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. + name: eslint on: pull_request: branches-ignore: - - 'dependabot/**' + - "dependabot/**" types: - opened - reopened diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml index fe70604aa4..817eb535f8 100644 --- a/.github/workflows/generate-docs.yml +++ b/.github/workflows/generate-docs.yml @@ -1,3 +1,19 @@ +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. + name: Auto Build Docs on: diff --git a/.github/workflows/playwright-firefox-nightly.yml b/.github/workflows/playwright-firefox-nightly.yml index 0594144630..05fa82fee9 100644 --- a/.github/workflows/playwright-firefox-nightly.yml +++ b/.github/workflows/playwright-firefox-nightly.yml @@ -1,3 +1,19 @@ +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. + name: Playwright Firefox Nightly Tests on: diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index ea44288b0b..34924f1a4b 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -1,7 +1,18 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. name: Playwright Tests diff --git a/.github/workflows/post_release_clamav.yml b/.github/workflows/post_release_clamav.yml index 7dccdbb37e..52b6d460d2 100644 --- a/.github/workflows/post_release_clamav.yml +++ b/.github/workflows/post_release_clamav.yml @@ -1,7 +1,18 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. name: Post Release ClamAV Scan diff --git a/.github/workflows/post_release_trivy.yml b/.github/workflows/post_release_trivy.yml index bd5928316d..a294f71ea4 100644 --- a/.github/workflows/post_release_trivy.yml +++ b/.github/workflows/post_release_trivy.yml @@ -1,7 +1,18 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. name: Post Release Trivy Scan diff --git a/.github/workflows/python_unit_tests.yml b/.github/workflows/python_unit_tests.yml index 837e1eb5e8..ab27d3350b 100644 --- a/.github/workflows/python_unit_tests.yml +++ b/.github/workflows/python_unit_tests.yml @@ -1,11 +1,18 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. -# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake -# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. -# Reference environment variables: https://docs.github.com/en/actions/reference/environment-variables +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. name: Python Unit Tests diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 466fa90a46..fa18b35a23 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,18 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. name: COSMOS Core Release @@ -23,9 +34,9 @@ on: default: true permissions: - id-token: write # Required for OIDC + id-token: write # Required for OIDC contents: read - packages: write # Required for pushing to ghcr.io + packages: write # Required for pushing to ghcr.io jobs: release: @@ -58,7 +69,12 @@ jobs: - name: login to ironbank # This `shell` line is required to get around a known issue: https://github.com/actions/runner/issues/241#issuecomment-745902718 shell: 'script -q -e -c "bash {0}"' - run: echo ${{ secrets.IRONBANK_REGISTRY_CLI }} | docker login registry1.dso.mil -u jmthomas --password-stdin + env: + # Create ENV variable for the IronBank registry CLI token, which is stored as a secret in GitHub + # This is done to avoid expanding secrets directly in a run block + # where they may be exposed in process lists, shell history, or files. + IRONBANK_REGISTRY_CLI: ${{ secrets.IRONBANK_REGISTRY_CLI }} + run: echo "$IRONBANK_REGISTRY_CLI" | docker login registry1.dso.mil -u jmthomas --password-stdin - name: Login to DockerHub uses: docker/login-action@v3 with: diff --git a/.github/workflows/ruby_unit_tests.yml b/.github/workflows/ruby_unit_tests.yml index 6f7d56aa2d..9418f70e07 100644 --- a/.github/workflows/ruby_unit_tests.yml +++ b/.github/workflows/ruby_unit_tests.yml @@ -1,11 +1,18 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. -# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake -# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. -# Reference environment variables: https://docs.github.com/en/actions/reference/environment-variables +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. name: Ruby Unit Tests diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml index 9dce3d41ae..dc8775e674 100644 --- a/.github/workflows/spelling.yml +++ b/.github/workflows/spelling.yml @@ -1,3 +1,19 @@ +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. + name: Check Spelling # Only run on a push to main to avoid running for all the dependabot PRs diff --git a/.github/workflows/tool.yml b/.github/workflows/tool.yml index d2227cf334..c15ff4ad36 100644 --- a/.github/workflows/tool.yml +++ b/.github/workflows/tool.yml @@ -1,7 +1,18 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. name: Frontend Generator Tests diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index f594c259c9..93ba36e1dc 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -1,7 +1,18 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is free software; you can modify and/or redistribute it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation; version 3 with +# attribution addendums as found in the LICENSE.txt +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. name: Trivy Scan diff --git a/openc3/python/openc3/io/udp_sockets.py b/openc3/python/openc3/io/udp_sockets.py index 3e09075b00..3b0c48209c 100644 --- a/openc3/python/openc3/io/udp_sockets.py +++ b/openc3/python/openc3/io/udp_sockets.py @@ -1,4 +1,4 @@ -# Copyright 2023 OpenC3, Inc. +# Copyright 2026 OpenC3, Inc. # All Rights Reserved. # # This program is free software; you can modify and/or redistribute it @@ -127,7 +127,9 @@ def multicast(cls, host, port): if host is None or port is None: return False host_ip = socket.gethostbyname(host) - return ipaddress.ip_address(host_ip) in ipaddress.ip_network("224.0.0.0/4") + # "224.0.0.0/4 is the CIDR notation for the range of IPv4 multicast addresses, + # which includes all addresses from 224.0.0.0 to 239.255.255.255. + return ipaddress.ip_address(host_ip) in ipaddress.ip_network("224.0.0.0/4") # NOSONAR # Creates a UDPSocket and implements a non-blocking write.