From cfe0b33e3722d885e92da156a7112ea9f863417d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rud=C3=A1=20Moura?= Date: Tue, 3 Dec 2024 10:48:58 -0300 Subject: [PATCH 1/5] feat: add "check" command Sanity check Quipucords setup and configurations. This command will check and print the status of important files and directories that the installer creates for running Quipucords. Example of status: OK, Not owned by you and Missing. The return code for the command is the number of problematic files/dirs. Relates to JIRA: DISCOVERY-729 --- bin/quipucords-installer | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/bin/quipucords-installer b/bin/quipucords-installer index 4f3aa27..3c40cc7 100755 --- a/bin/quipucords-installer +++ b/bin/quipucords-installer @@ -26,6 +26,7 @@ usage() { echo " uninstall Uninstall Quipucords" echo " create-server-password Create a Quipucords server password" echo " create-app-secret Create a Quipucords application secret" + echo " check Check Quipucords setup and configurations" exit 1 } @@ -74,6 +75,7 @@ set_default_vars() { # Do not allow a user's custom PATH environment to interfere. export PATH="${INSTALLER_BIN_DIR}:/usr/bin:/bin:/usr/sbin:/sbin" + QUIPUCORDS_CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/quipucords" QUIPUCORDS_ENV_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/quipucords/env" QUIPUCORDS_DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/quipucords" SYSTEMD_CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/containers/systemd" @@ -157,6 +159,10 @@ EOFDOC uninstall) uninstall ;; + check) + check + exit $? + ;; create-server-password) create-server-password exit $? @@ -409,6 +415,75 @@ upgrade() { return $? } +check_directory_status() { + if [ -d "${1}" ]; then + if [ -O "${1}" ]; then + return 0 # OK + else + return 1 # Not owned by you + fi + fi + return 2 # Missing +} + +check_file_status() { + if [ -f "${1}" ]; then + if [ -O "${1}" ]; then + return 0 # OK + else + return 1 # Not owned by you + fi + fi + return 2 # Missing +} + +check_and_print_status() { + if [ "${1}" == "d" ]; then + check_directory_status "${2}" + else + check_file_status "${2}" + fi + local status=$? + if [ $status -eq 0 ]; then + echo "${2}: OK" + return 0 + fi + if [ $status -eq 1 ]; then + echo "${2}: ERROR: Not owned by you" + return 1 + fi + echo "${2}: ERROR: Missing" + return 2 +} + +check() { + echo "Checking Quipucords setup and configurations..." + local result=0 + check_and_print_status d "${QUIPUCORDS_DATA_DIR}" || result=$((result + 1)) + for name in certs data db log sshkeys; do + local subdirectory="${QUIPUCORDS_DATA_DIR}/$name" + check_and_print_status d "$subdirectory" || result=$((result + 1)) + done + check_and_print_status f "${QUIPUCORDS_DATA_DIR}/certs/server.key" || result=$((result + 1)) + check_and_print_status f "${QUIPUCORDS_DATA_DIR}/certs/server.crt" || result=$((result + 1)) + check_and_print_status f "${QUIPUCORDS_DATA_DIR}/data/secret.txt" || result=$((result + 1)) + check_and_print_status d "${QUIPUCORDS_DATA_DIR}/db/userdata" || result=$((result + 1)) + check_and_print_status d "${QUIPUCORDS_CONFIG_DIR}" || result=$((result + 1)) + check_and_print_status d "${QUIPUCORDS_ENV_DIR}" || result=$((result + 1)) + for name in ansible app celery-worker db redis server; do + local env_file="$QUIPUCORDS_ENV_DIR/env-${name}.env" + check_and_print_status f "${env_file}" || result=$((result + 1)) + done + check_and_print_status d "${SYSTEMD_CONFIG_DIR}" || result=$((result + 1)) + for name in app celery-worker db redis server; do + local container_file="${SYSTEMD_CONFIG_DIR}/quipucords-${name}.container" + check_and_print_status f "${container_file}" || result=$((result + 1)) + done + local network_file="${SYSTEMD_CONFIG_DIR}/quipucords.network" + check_and_print_status f "${network_file}" || result=$((result + 1)) + return $result +} + stop_containers() { echo "Stopping Quipucords ..." systemctl --user stop quipucords-app || true From abf210ec5b9e54203d6e8ec28b9154d18ff7a767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rud=C3=A1=20Moura?= Date: Tue, 10 Dec 2024 11:15:20 -0300 Subject: [PATCH 2/5] feat: "check" command verify permissions (writable/read-only) Output: ... ERROR: Not writable by you (read-only) Relates to JIRA: DISCOVERY-729 --- bin/quipucords-installer | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/bin/quipucords-installer b/bin/quipucords-installer index 3c40cc7..78dd08a 100755 --- a/bin/quipucords-installer +++ b/bin/quipucords-installer @@ -418,23 +418,31 @@ upgrade() { check_directory_status() { if [ -d "${1}" ]; then if [ -O "${1}" ]; then - return 0 # OK + if [ -r "${1}" ] && [ -w "${1}" ] && [ -x "${1}" ]; then + return 0 # OK + else + return 1 # Not writable + fi else - return 1 # Not owned by you + return 2 # Not owned by you fi fi - return 2 # Missing + return 3 # Missing } check_file_status() { if [ -f "${1}" ]; then if [ -O "${1}" ]; then - return 0 # OK + if [ -r "${1}" ] && [ -w "${1}" ]; then + return 0 # OK + else + return 1 # Not writable + fi else - return 1 # Not owned by you + return 2 # Not owned by you fi fi - return 2 # Missing + return 3 # Missing } check_and_print_status() { @@ -449,11 +457,15 @@ check_and_print_status() { return 0 fi if [ $status -eq 1 ]; then - echo "${2}: ERROR: Not owned by you" + echo "${2}: ERROR: Wrong permission(s)" return 1 fi + if [ $status -eq 2 ]; then + echo "${2}: ERROR: Not owned by you (bad ownership)" + return 2 + fi echo "${2}: ERROR: Missing" - return 2 + return 3 } check() { From 9f8c8be9daa29d0b97cda6a3e14fb9ae109b9757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rud=C3=A1=20Moura?= Date: Wed, 11 Dec 2024 15:34:53 -0300 Subject: [PATCH 3/5] feat: "check" command displays permissions and ownership Relates to JIRA: DISCOVERY-729 --- bin/quipucords-installer | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/bin/quipucords-installer b/bin/quipucords-installer index 78dd08a..fa4b278 100755 --- a/bin/quipucords-installer +++ b/bin/quipucords-installer @@ -421,7 +421,7 @@ check_directory_status() { if [ -r "${1}" ] && [ -w "${1}" ] && [ -x "${1}" ]; then return 0 # OK else - return 1 # Not writable + return 1 # Bad permissions fi else return 2 # Not owned by you @@ -436,7 +436,7 @@ check_file_status() { if [ -r "${1}" ] && [ -w "${1}" ]; then return 0 # OK else - return 1 # Not writable + return 1 # Bad permissions fi else return 2 # Not owned by you @@ -453,15 +453,18 @@ check_and_print_status() { fi local status=$? if [ $status -eq 0 ]; then - echo "${2}: OK" + perms_owner=$(stat -c '%A %U' "${2}") + echo "${2}: OK: ${perms_owner}" return 0 fi if [ $status -eq 1 ]; then - echo "${2}: ERROR: Wrong permission(s)" + perms=$(stat -c '%a %A' "${2}") + echo "${2}: ERROR: Incorrect permission(s): ${perms}" return 1 fi if [ $status -eq 2 ]; then - echo "${2}: ERROR: Not owned by you (bad ownership)" + owner=$(stat -c '%u %U' "${2}") + echo "${2}: ERROR: Not owned by you (incorrect ownership): ${owner}" return 2 fi echo "${2}: ERROR: Missing" From a7f5149c580937aec97f58262e7a06bf6f69156f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rud=C3=A1=20Moura?= Date: Mon, 16 Dec 2024 17:16:58 -0300 Subject: [PATCH 4/5] refactor: substitute if/then/else with logic operators --- bin/quipucords-installer | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/bin/quipucords-installer b/bin/quipucords-installer index fa4b278..2973b0a 100755 --- a/bin/quipucords-installer +++ b/bin/quipucords-installer @@ -416,33 +416,17 @@ upgrade() { } check_directory_status() { - if [ -d "${1}" ]; then - if [ -O "${1}" ]; then - if [ -r "${1}" ] && [ -w "${1}" ] && [ -x "${1}" ]; then - return 0 # OK - else - return 1 # Bad permissions - fi - else - return 2 # Not owned by you - fi - fi - return 3 # Missing + [[ ! -d "${1}" ]] && return 3 # Missing + [[ ! -O "${1}" ]] && return 2 # Not owned by you + [[ -r "${1}" ]] && [[ -w "${1}" ]] && return 0 # OK + return 1 # Bad permissions } check_file_status() { - if [ -f "${1}" ]; then - if [ -O "${1}" ]; then - if [ -r "${1}" ] && [ -w "${1}" ]; then - return 0 # OK - else - return 1 # Bad permissions - fi - else - return 2 # Not owned by you - fi - fi - return 3 # Missing + [[ ! -f "${1}" ]] && return 3 # Missing + [[ ! -O "${1}" ]] && return 2 # Not owned by you + [[ -r "${1}" ]] && [[ -w "${1}" ]] && return 0 # OK + return 1 # Bad permissions } check_and_print_status() { From ee8fda3e3f91ca27194db1a4ee70b6d05338b2de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rud=C3=A1=20Moura?= Date: Mon, 16 Dec 2024 19:03:16 -0300 Subject: [PATCH 5/5] refactor: split check_and_print_status to check dirs or files --- bin/quipucords-installer | 64 ++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/bin/quipucords-installer b/bin/quipucords-installer index 2973b0a..bfb084a 100755 --- a/bin/quipucords-installer +++ b/bin/quipucords-installer @@ -429,57 +429,63 @@ check_file_status() { return 1 # Bad permissions } -check_and_print_status() { - if [ "${1}" == "d" ]; then - check_directory_status "${2}" - else - check_file_status "${2}" - fi - local status=$? - if [ $status -eq 0 ]; then +print_path_status() { + local owner perms perms_owner + if [ "${1}" -eq 0 ]; then perms_owner=$(stat -c '%A %U' "${2}") echo "${2}: OK: ${perms_owner}" - return 0 - fi - if [ $status -eq 1 ]; then + elif [ "${1}" -eq 1 ]; then perms=$(stat -c '%a %A' "${2}") echo "${2}: ERROR: Incorrect permission(s): ${perms}" - return 1 - fi - if [ $status -eq 2 ]; then + elif [ "${1}" -eq 2 ]; then owner=$(stat -c '%u %U' "${2}") echo "${2}: ERROR: Not owned by you (incorrect ownership): ${owner}" - return 2 + elif [ "${1}" -eq 3 ]; then + echo "${2}: ERROR: Missing" + else + echo "${2}: ERROR: Unknown status" fi - echo "${2}: ERROR: Missing" - return 3 +} + +check_directory_and_print_status() { + check_directory_status "${1}" + local exit_status=$? + print_path_status ${exit_status} "${1}" + return $exit_status +} + +check_file_and_print_status() { + check_file_status "${1}" + local exit_status=$? + print_path_status ${exit_status} "${1}" + return $exit_status } check() { echo "Checking Quipucords setup and configurations..." local result=0 - check_and_print_status d "${QUIPUCORDS_DATA_DIR}" || result=$((result + 1)) + check_directory_and_print_status "${QUIPUCORDS_DATA_DIR}" || result=$((result + 1)) for name in certs data db log sshkeys; do local subdirectory="${QUIPUCORDS_DATA_DIR}/$name" - check_and_print_status d "$subdirectory" || result=$((result + 1)) + check_directory_and_print_status "$subdirectory" || result=$((result + 1)) done - check_and_print_status f "${QUIPUCORDS_DATA_DIR}/certs/server.key" || result=$((result + 1)) - check_and_print_status f "${QUIPUCORDS_DATA_DIR}/certs/server.crt" || result=$((result + 1)) - check_and_print_status f "${QUIPUCORDS_DATA_DIR}/data/secret.txt" || result=$((result + 1)) - check_and_print_status d "${QUIPUCORDS_DATA_DIR}/db/userdata" || result=$((result + 1)) - check_and_print_status d "${QUIPUCORDS_CONFIG_DIR}" || result=$((result + 1)) - check_and_print_status d "${QUIPUCORDS_ENV_DIR}" || result=$((result + 1)) + check_file_and_print_status "${QUIPUCORDS_DATA_DIR}/certs/server.key" || result=$((result + 1)) + check_file_and_print_status "${QUIPUCORDS_DATA_DIR}/certs/server.crt" || result=$((result + 1)) + check_file_and_print_status "${QUIPUCORDS_DATA_DIR}/data/secret.txt" || result=$((result + 1)) + check_directory_and_print_status "${QUIPUCORDS_DATA_DIR}/db/userdata" || result=$((result + 1)) + check_directory_and_print_status "${QUIPUCORDS_CONFIG_DIR}" || result=$((result + 1)) + check_directory_and_print_status "${QUIPUCORDS_ENV_DIR}" || result=$((result + 1)) for name in ansible app celery-worker db redis server; do local env_file="$QUIPUCORDS_ENV_DIR/env-${name}.env" - check_and_print_status f "${env_file}" || result=$((result + 1)) + check_file_and_print_status "${env_file}" || result=$((result + 1)) done - check_and_print_status d "${SYSTEMD_CONFIG_DIR}" || result=$((result + 1)) + check_directory_and_print_status "${SYSTEMD_CONFIG_DIR}" || result=$((result + 1)) for name in app celery-worker db redis server; do local container_file="${SYSTEMD_CONFIG_DIR}/quipucords-${name}.container" - check_and_print_status f "${container_file}" || result=$((result + 1)) + check_file_and_print_status "${container_file}" || result=$((result + 1)) done local network_file="${SYSTEMD_CONFIG_DIR}/quipucords.network" - check_and_print_status f "${network_file}" || result=$((result + 1)) + check_file_and_print_status "${network_file}" || result=$((result + 1)) return $result }