From 80f64b6bdb8382deca1581f0633543ce2b1b4f03 Mon Sep 17 00:00:00 2001 From: RoseSecurity Date: Fri, 12 Dec 2025 15:27:38 -0500 Subject: [PATCH 1/2] chore: typo fixes --- README.md | 2 +- README.yaml | 2 +- os/debian/Dockerfile.debian | 2 +- rootfs/etc/codefresh/require_vars | 4 ++-- rootfs/etc/profile.d/_40-preferences.sh | 2 +- rootfs/etc/profile.d/fzf.sh | 2 +- rootfs/etc/profile.d/prompt.sh | 2 +- "rootfs/etc/profile.d/\316\251_overrides.sh" | 2 +- rootfs/usr/local/bin/codefresh-pipeline | 4 ++-- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 69205d600..10a8c84ca 100644 --- a/README.md +++ b/README.md @@ -232,7 +232,7 @@ You can also add extra commands by installing "packages". - Cloud Posse also provides a large set of packages for installing common DevOps commands and utilities via [cloudposse/packages](https://github.com/cloudposse/packages). - Google Cloud provides a set of packages for working with GCP -- OpenTofu provides a packge for installing it, too. +- OpenTofu provides a package for installing it, too. Those package repositories are pre-installed in Geodesic, so all you need to do is add the packages you want via diff --git a/README.yaml b/README.yaml index fccd128b5..bdf448ce0 100644 --- a/README.yaml +++ b/README.yaml @@ -230,7 +230,7 @@ usage: |- - Cloud Posse also provides a large set of packages for installing common DevOps commands and utilities via [cloudposse/packages](https://github.com/cloudposse/packages). - Google Cloud provides a set of packages for working with GCP - - OpenTofu provides a packge for installing it, too. + - OpenTofu provides a package for installing it, too. Those package repositories are pre-installed in Geodesic, so all you need to do is add the packages you want via diff --git a/os/debian/Dockerfile.debian b/os/debian/Dockerfile.debian index 3c1eb3b2b..e029b561b 100644 --- a/os/debian/Dockerfile.debian +++ b/os/debian/Dockerfile.debian @@ -283,7 +283,7 @@ RUN if [[ -x /usr/local/bin/aws ]]; then mv /usr/local/bin/aws /usr/local/bin/aw # Install AWS CLI 2 # Get AWS CLI V2 version from https://github.com/aws/aws-cli/blob/v2/CHANGELOG.rst if you want # but it is updated several times a week, so we choose to just get the latest. -# It is available in a Debain package `awscli`, but that can be very out of date. +# It is available in a Debian package `awscli`, but that can be very out of date. # ARG AWS_CLI_VERSION=2.15.48 RUN AWSTMPDIR=$(mktemp -d -t aws-inst-XXXXXXXXXX) && \ if [ "$TARGETARCH" = "amd64" ]; then \ diff --git a/rootfs/etc/codefresh/require_vars b/rootfs/etc/codefresh/require_vars index 395820a36..9e8b9ef8c 100755 --- a/rootfs/etc/codefresh/require_vars +++ b/rootfs/etc/codefresh/require_vars @@ -26,7 +26,7 @@ function require_cfvar() { echo "$separator" red Build variable \"$var\" has not been set >&2 - # Look for docmentation of VARNAME on the rest of the args + # Look for documentation of VARNAME on the rest of the args # First, look for trailing characters on $1 and collect them local rem1=$(expr match "$1" '[^}]*}}[[:blank:]]*\(.*\)') @@ -50,7 +50,7 @@ function require_cfvar() { # EOF # Checks each variable with require_cfvar. # Variables must be at the start of the line, one per line, but do not need to be quoted. -# The final EOF must be at the begining of the line. +# The final EOF must be at the beginning of the line. function require_cfvars() { local var local status=0 diff --git a/rootfs/etc/profile.d/_40-preferences.sh b/rootfs/etc/profile.d/_40-preferences.sh index 9bd732356..3e8be24ad 100755 --- a/rootfs/etc/profile.d/_40-preferences.sh +++ b/rootfs/etc/profile.d/_40-preferences.sh @@ -17,7 +17,7 @@ fi # # Determine the base directory for all customizations. # We do some extra processing because GEODESIC_CONFIG_HOME needs to be set as a path in the Geodesic file system, -# but the user may have set it as a path on the host computer system. We try to accomodate that by +# but the user may have set it as a path on the host computer system. We try to accommodate that by # searching a few other places for the directory if $GEODESIC_CONFIG_HOME does point to a valid directory export GEODESIC_CONFIG_HOME _GEODESIC_CONFIG_HOME_DEFAULT="/root/.config/geodesic" diff --git a/rootfs/etc/profile.d/fzf.sh b/rootfs/etc/profile.d/fzf.sh index 82cf6f8a4..53500d777 100755 --- a/rootfs/etc/profile.d/fzf.sh +++ b/rootfs/etc/profile.d/fzf.sh @@ -34,7 +34,7 @@ function _set_fzf_default_opts() { local cyan="37" local green="2" local olive="3" - local keep="-1" # Keep the exsiting terminal setting for this field + local keep="-1" # Keep the existing terminal setting for this field local fzf_default_opts case "$1" in diff --git a/rootfs/etc/profile.d/prompt.sh b/rootfs/etc/profile.d/prompt.sh index 7e8c3284b..2b091423b 100755 --- a/rootfs/etc/profile.d/prompt.sh +++ b/rootfs/etc/profile.d/prompt.sh @@ -119,7 +119,7 @@ function geodesic_prompt() { case $SHLVL in 1) level_prompt='.' ;; 2) level_prompt=':' ;; - 3) level_prompt='⋮' ;; # vertical elipsis \u22ee from Mathematical Symbols + 3) level_prompt='⋮' ;; # vertical ellipsis \u22ee from Mathematical Symbols *) level_prompt="$SHLVL" ;; esac level_prompt=$(bold "${level_prompt}") diff --git "a/rootfs/etc/profile.d/\316\251_overrides.sh" "b/rootfs/etc/profile.d/\316\251_overrides.sh" index 980b1d8e1..396dd0a31 100644 --- "a/rootfs/etc/profile.d/\316\251_overrides.sh" +++ "b/rootfs/etc/profile.d/\316\251_overrides.sh" @@ -3,7 +3,7 @@ # other files that this function needs to be able to see. # This file should be the last file in profile.d to execute. # This loads user's overrides, which take actions based on any setup that has already occurred. -# This must come after all setup has happened so that the final configuration is availble for inspection, +# This must come after all setup has happened so that the final configuration is available for inspection, # and there must not be any configuration after this to ensure that anything set here remains set as the user intended. ## Load user's custom overrides diff --git a/rootfs/usr/local/bin/codefresh-pipeline b/rootfs/usr/local/bin/codefresh-pipeline index 1c8167923..16ceb862c 100755 --- a/rootfs/usr/local/bin/codefresh-pipeline +++ b/rootfs/usr/local/bin/codefresh-pipeline @@ -91,11 +91,11 @@ function convert_to_yaml() { else local subdirs="$3" local pipeline=$(jq -rc '.metadata.name' <"$1") - # You could get project from jq .metadata.project, but we care more about the name embeded in the pipeline name + # You could get project from jq .metadata.project, but we care more about the name embedded in the pipeline name local project=$(dirname $pipeline) if [[ -z "$pipeline" ]] || [[ -z "$project" ]]; then red "* Unable to find project and pipeline name from file $1" - reutrn 5 + return 5 fi local target="${pipeline##*/}.pip" From 5020c07fbc2c924990a4c9f4ba72cc0c76434756 Mon Sep 17 00:00:00 2001 From: RoseSecurity Date: Mon, 15 Dec 2025 07:57:16 -0500 Subject: [PATCH 2/2] refactor(shell): quote variables and use arrays safely Improve shell script robustness by consistently quoting variable expansions and using array-safe patterns. Replace unquoted variables with quoted ones, use mapfile for array assignments from command output, and update command invocations to prevent word splitting and globbing issues. These changes enhance script reliability and maintainability. --- rootfs/etc/init.d/atlantis.sh | 25 ++++++++++++------------- rootfs/etc/profile.d/aws.sh | 11 ++++++----- rootfs/templates/wrapper-body.sh | 22 ++++++++++++---------- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/rootfs/etc/init.d/atlantis.sh b/rootfs/etc/init.d/atlantis.sh index 10fbfcd36..fe44f7ece 100755 --- a/rootfs/etc/init.d/atlantis.sh +++ b/rootfs/etc/init.d/atlantis.sh @@ -2,8 +2,7 @@ # Start the atlantis server if [ "${ATLANTIS_ENABLED}" == "true" ]; then - which atlantis >/dev/null - if [ $? -ne 0 ]; then + if ! which atlantis >/dev/null; then echo "Atlantis is not installed" exit 1 fi @@ -42,7 +41,7 @@ if [ "${ATLANTIS_ENABLED}" == "true" ]; then export ATLANTIS_CHAMBER_SERVICE=${ATLANTIS_CHAMBER_SERVICE:-atlantis} # Export environment from chamber to shell - source <(chamber exec ${ATLANTIS_CHAMBER_SERVICE} -- sh -c "export -p") + source <(chamber exec "${ATLANTIS_CHAMBER_SERVICE}" -- sh -c "export -p") if [ -n "${ATLANTIS_IAM_ROLE_ARN}" ]; then # Map the Atlantis IAM Role ARN to the env we use everywhere in our root modules @@ -55,11 +54,11 @@ if [ "${ATLANTIS_ENABLED}" == "true" ]; then export ATLANTIS_HOME=${ATLANTIS_HOME:-/home/atlantis} # create atlantis user & group - (getent group ${ATLANTIS_GROUP} || addgroup ${ATLANTIS_GROUP}) >/dev/null - (getent passwd ${ATLANTIS_USER} || adduser -h ${ATLANTIS_HOME} -S -G ${ATLANTIS_GROUP} ${ATLANTIS_USER}) >/dev/null + (getent group "${ATLANTIS_GROUP}" || addgroup "${ATLANTIS_GROUP}") >/dev/null + (getent passwd "${ATLANTIS_USER}" || adduser -h "${ATLANTIS_HOME}" -S -G "${ATLANTIS_GROUP}" "${ATLANTIS_USER}") >/dev/null # Provision terraform cache directory - install --directory ${TF_PLUGIN_CACHE_DIR} --owner ${ATLANTIS_USER} --group ${ATLANTIS_GROUP} + install --directory "${TF_PLUGIN_CACHE_DIR}" --owner "${ATLANTIS_USER}" --group "${ATLANTIS_GROUP}" # Allow atlantis to use /dev/shm if [ -d /dev/shm ]; then @@ -69,14 +68,14 @@ if [ "${ATLANTIS_ENABLED}" == "true" ]; then # Add SSH key to agent, if one is configured so we can pull from private git repos if [ -n "${ATLANTIS_SSH_PRIVATE_KEY}" ]; then - source <(gosu ${ATLANTIS_USER} ssh-agent -s) - ssh-add - <<<${ATLANTIS_SSH_PRIVATE_KEY} + source <(gosu "${ATLANTIS_USER}" ssh-agent -s) + ssh-add - <<<"${ATLANTIS_SSH_PRIVATE_KEY}" # Sanitize environment unset ATLANTIS_SSH_PRIVATE_KEY fi if [ -n "${ATLANTIS_ALLOW_PRIVILEGED_PORTS}" ]; then - setcap "cap_net_bind_service=+ep" $(which atlantis) + setcap "cap_net_bind_service=+ep" "$(which atlantis)" fi # Do not export these as Terraform environment variables @@ -92,18 +91,18 @@ if [ "${ATLANTIS_ENABLED}" == "true" ]; then # https://gist.github.com/Kovrinic/ea5e7123ab5c97d451804ea222ecd78a # The URL "git@github.com:" is used by `git` (e.g. `git clone`) - gosu ${ATLANTIS_USER} git config --global url."https://github.com/".insteadOf "git@github.com:" + gosu "${ATLANTIS_USER}" git config --global url."https://github.com/".insteadOf "git@github.com:" # The URL "ssh://git@github.com/" is used by Terraform (e.g. `terraform init --from-module=...`) # NOTE: we use `--add` to append the second URL to the config file - gosu ${ATLANTIS_USER} git config --global url."https://github.com/".insteadOf "ssh://git@github.com/" --add + gosu "${ATLANTIS_USER}" git config --global url."https://github.com/".insteadOf "ssh://git@github.com/" --add # https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage # see rootfs/usr/local/bin/git-credential-github - gosu ${ATLANTIS_USER} git config --global credential.helper 'github' + gosu "${ATLANTIS_USER}" git config --global credential.helper 'github' # Use a primitive init handler to catch signals and handle them properly # Use gosu to drop privileges # Use env to setup the shell environment for atlantis # Then lastly, start the atlantis server - exec dumb-init gosu ${ATLANTIS_USER} env BASH_ENV=/etc/direnv/bash atlantis server + exec dumb-init gosu "${ATLANTIS_USER}" env BASH_ENV=/etc/direnv/bash atlantis server fi diff --git a/rootfs/etc/profile.d/aws.sh b/rootfs/etc/profile.d/aws.sh index c8431fd13..cbd721249 100755 --- a/rootfs/etc/profile.d/aws.sh +++ b/rootfs/etc/profile.d/aws.sh @@ -4,7 +4,7 @@ # In this script, we do not care about return values, as problems are detected by the resulting empty value. export AWS_REGION_ABBREVIATION_TYPE=${AWS_REGION_ABBREVIATION_TYPE:-fixed} -export AWS_DEFAULT_SHORT_REGION=${AWS_DEFAULT_SHORT_REGION:-$(aws-region --${AWS_REGION_ABBREVIATION_TYPE} ${AWS_DEFAULT_REGION:-us-west-2})} +export AWS_DEFAULT_SHORT_REGION=${AWS_DEFAULT_SHORT_REGION:-$(aws-region --"${AWS_REGION_ABBREVIATION_TYPE}" "${AWS_DEFAULT_REGION:-us-west-2}")} export GEODESIC_AWS_HOME function _aws_config_home() { @@ -102,7 +102,7 @@ function aws_sdk_assume_role() { history -c history -r else - AWS_PROFILE="$role" $* + AWS_PROFILE="$role" "$@" fi ASSUME_ROLE="$assume_role" } @@ -154,7 +154,8 @@ function export_current_aws_role() { local sso_role_name=$(echo "$role_part" | cut -d'_' -f2) # This selects the second field delimited by '_' # Find all profiles that have matching role names - local profile_names=($(crudini --get --format=lines "$config_file" | grep "$sso_role_name" | cut -d' ' -f 3)) + local profile_names + mapfile -t profile_names < <(crudini --get --format=lines "$config_file" | grep "$sso_role_name" | cut -d' ' -f 3) local profile_name for profile_name in "${profile_names[@]}"; do # Skip the generic profiles @@ -173,7 +174,7 @@ function export_current_aws_role() { # Normal IAM role # Assumed roles in AWS config file use the role ARN, not the assumed role ARN, so adjust accordingly. local role_arn=$(printf "%s" "$current_role" | sed 's/:sts:/:iam:/g' | sed 's,:assumed-role/,:role/,') - role_names=($(crudini --get --format=lines "$config_file" | grep "$role_arn" | cut -d' ' -f 3)) + mapfile -t role_names < <(crudini --get --format=lines "$config_file" | grep "$role_arn" | cut -d' ' -f 3) for rn in "${role_names[@]}"; do if [[ $rn == "default" ]] || [[ $rn =~ -identity$ ]]; then continue @@ -257,7 +258,7 @@ function refresh_current_aws_role_if_needed() { [[ $aws_profile =~ $is_exported ]] || aws_profile="" local credentials_mtime=$(stat -c "%Y" "${AWS_SHARED_CREDENTIALS_FILE:-${GEODESIC_AWS_HOME}/credentials}" 2>/dev/null) local role_fingerprint="${aws_profile}/${credentials_mtime}/${AWS_ACCESS_KEY_ID}" - if [[ $role_fingerprint != $GEODESIC_AWS_ROLE_CACHE ]]; then + if [[ $role_fingerprint != "$GEODESIC_AWS_ROLE_CACHE" ]]; then export_current_aws_role export GEODESIC_AWS_ROLE_CACHE="${role_fingerprint}" fi diff --git a/rootfs/templates/wrapper-body.sh b/rootfs/templates/wrapper-body.sh index f74e9d41e..219606894 100755 --- a/rootfs/templates/wrapper-body.sh +++ b/rootfs/templates/wrapper-body.sh @@ -269,7 +269,8 @@ function _our_shell_pid() { } function _running_shell_count() { - local count=($(_running_shell_pids || true)) + local count + mapfile -t count < <(_running_shell_pids || true) echo "${#count[@]}" } @@ -299,7 +300,7 @@ function wait_for_container_exit() { # Wait for our shell to quit, regardless, because new shells might not be found until triggered by our shell quitting. if [ -z "$(_our_shell_pid)" ] && [ "$(_running_shell_count)" -gt 0 ]; then printf 'New shells started from other sources, docker container still running.\n' >&2 - printf 'Use `%s stop` to stop container gracefully, or\n force quit with `docker kill %s`\n' "$(basename $0)" "${DOCKER_NAME}" >&2 + printf 'Use `%s stop` to stop container gracefully, or\n force quit with `docker kill %s`\n' "$(basename "$0")" "${DOCKER_NAME}" >&2 _on_shell_exit return 7 fi @@ -343,7 +344,7 @@ function run_exit_hooks() { # Are other shells running? if [ -n "$our_shell_pid" ]; then # remove our shell from the list - shell_pids=($(printf "%s\n" "${shell_pids[@]}" | grep -v "^$our_shell_pid\$")) + mapfile -t shell_pids < <(printf "%s\n" "${shell_pids[@]}" | grep -v "^$our_shell_pid\$") fi local shells=${#shell_pids[@]} @@ -351,7 +352,7 @@ function run_exit_hooks() { if [ "$shells" -gt 0 ]; then printf "Docker container still running. " >&2 [ "$shells" -eq 1 ] && echo -n "Quit 1 other shell " >&2 || echo -n "Quit $shells other shells " >&2 - printf 'to terminate.\n Use `%s stop` to stop gracefully, or\n force quit with `docker kill %s`\n' "$(basename $0)" "${DOCKER_NAME}" >&2 + printf 'to terminate.\n Use `%s stop` to stop gracefully, or\n force quit with `docker kill %s`\n' "$(basename "$0")" "${DOCKER_NAME}" >&2 _on_shell_exit return 0 fi @@ -655,7 +656,7 @@ function use() { _polite_stop() { name="$1" [ -n "$name" ] || return 1 - if [ $(docker ps -q --filter "name=${name}" | wc -l | tr -d " ") -eq 0 ]; then + if [ "$(docker ps -q --filter "name=${name}" | wc -l | tr -d " ")" -eq 0 ]; then echo "# No running containers found for ${name}" return fi @@ -663,11 +664,11 @@ _polite_stop() { printf "# Signalling '%s' to stop..." "${name}" docker kill -s TERM "${name}" >/dev/null for i in {1..9}; do - if [ $i -eq 9 ] || [ $(docker ps -q --filter "name=${name}" | wc -l | tr -d " ") -eq 0 ]; then + if [ "$i" -eq 9 ] || [ "$(docker ps -q --filter "name=${name}" | wc -l | tr -d " ")" -eq 0 ]; then printf " '%s' stopped gracefully.\n\n" "${name}" return 0 fi - [ $i -lt 8 ] && sleep 1 + [ "$i" -lt 8 ] && sleep 1 done printf " '%s' did not stop gracefully. Killing it.\n\n" "${name}" @@ -679,16 +680,17 @@ function stop() { exec 1>&2 name=${targets[1]} if [ -n "$name" ]; then - _polite_stop ${name} + _polite_stop "${name}" return $? fi - RUNNING_NAMES=($(docker ps --filter name="^/${DOCKER_NAME}(-\d{8})?\$" --format '{{ .Names }}')) + local RUNNING_NAMES + mapfile -t RUNNING_NAMES < <(docker ps --filter name="^/${DOCKER_NAME}(-\d{8})?\$" --format '{{ .Names }}') if [ -z "$RUNNING_NAMES" ]; then echo "# No running containers found for ${DOCKER_NAME}" return fi if [ ${#RUNNING_NAMES[@]} -eq 1 ]; then - echo "# Stopping ${RUNNING_NAMES[@]}..." + echo "# Stopping ${RUNNING_NAMES[*]}..." _polite_stop "${RUNNING_NAMES[@]}" return $? fi