From 8dadc6623af0d33c040f3201b388b4ef08662f41 Mon Sep 17 00:00:00 2001
From: jotaen4tinypilot <83721279+jotaen4tinypilot@users.noreply.github.com>
Date: Wed, 17 Jan 2024 14:50:02 +0100
Subject: [PATCH] Add script for stripping TinyPilot marker sections (#1720)
Related https://github.com/tiny-pilot/tinypilot/issues/1710.
This PR adds a unified script to remove TinyPilot marker sections from
files. We will [use this script in a subsequent
PR](https://github.com/tiny-pilot/tinypilot/pull/1722) to simplify the
corresponding instances in the
[unset-static-ip](https://github.com/tiny-pilot/tinypilot/blob/2e211199a21a2a6c285c5d1d2ff60eff6afa77d4/debian-pkg/opt/tinypilot-privileged/scripts/unset-static-ip#L64-L81)
and
[change-hostname](https://github.com/tiny-pilot/tinypilot/blob/8e99d5a666df12d851b14dd4276e8b95ab958493/debian-pkg/opt/tinypilot-privileged/scripts/change-hostname#L62-L79)
privileged scripts.
## Notes
- Unless someone feels strongly about the [originally mentioned
`remove-tinypilot-lines` script
name](https://github.com/tiny-pilot/tinypilot/issues/1710#:~:text=opt/tinypilot/scripts/-,remove%2Dtinypilot%2Dlines,-%3C%20example.conf)
(or any other name), I thought that `strip-marker-sections` sounded most
expressive.
- I added a comment to the `lib/markers.sh` file, to explain the marker
idea in a bit more detail.
- There will be automated bash tests for this in [a subsequent
PR](https://github.com/tiny-pilot/tinypilot/pull/1721).
---------
Co-authored-by: Jan Heuermann
---
.../scripts/lib/markers.sh | 8 +-
.../scripts/strip-marker-sections | 94 +++++++++++++++++++
2 files changed, 100 insertions(+), 2 deletions(-)
create mode 100755 debian-pkg/opt/tinypilot-privileged/scripts/strip-marker-sections
diff --git a/debian-pkg/opt/tinypilot-privileged/scripts/lib/markers.sh b/debian-pkg/opt/tinypilot-privileged/scripts/lib/markers.sh
index 47fa75ffe..9f2710f06 100755
--- a/debian-pkg/opt/tinypilot-privileged/scripts/lib/markers.sh
+++ b/debian-pkg/opt/tinypilot-privileged/scripts/lib/markers.sh
@@ -1,9 +1,13 @@
#!/bin/bash
+#
+# We use the marker section technique to programmatically add
+# TinyPilot-specific configuration to system config files. Wrapping up such
+# addendums into markers allows us to maintain bits of custom configuration
+# without having to properly parse the entire file.
+#
# Shellcheck can't detect when variables are used elsewhere so we need to
# disable the unused variable check for this file.
# shellcheck disable=SC2034
-#
-# Markers used to denote autogenerated changes to config files..
readonly MARKER_START='# --- AUTOGENERATED BY TINYPILOT - START ---'
readonly MARKER_END='# --- AUTOGENERATED BY TINYPILOT - END ---'
diff --git a/debian-pkg/opt/tinypilot-privileged/scripts/strip-marker-sections b/debian-pkg/opt/tinypilot-privileged/scripts/strip-marker-sections
new file mode 100755
index 000000000..0925419ea
--- /dev/null
+++ b/debian-pkg/opt/tinypilot-privileged/scripts/strip-marker-sections
@@ -0,0 +1,94 @@
+#!/bin/bash
+#
+# Strips TinyPilot marker sections from a file.
+#
+# If the target file contains marker sections, this script removes the markers
+# and any content in between them.
+# If the target file doesn’t contain marker sections, running this script is a
+# noop.
+# If the target file contains unmatched/orphaned markers, this script fails.
+
+# We don’t use `set -x`, because it would output every single iteration of the
+# while loop when iterating through the lines of the target file, and hence
+# generate a lot of noise.
+
+# Exit on first failure.
+set -e
+
+# Exit on unset variable.
+set -u
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
+readonly SCRIPT_DIR
+# shellcheck source=lib/markers.sh
+. "${SCRIPT_DIR}/lib/markers.sh"
+
+print_help() {
+ cat << EOF
+Usage: ${0##*/} [--help] TARGET_FILE
+Strips TinyPilot marker sections from a file.
+ TARGET_FILE Path to file with marker sections.
+ --help Display this help and exit.
+EOF
+}
+
+# Parse command-line arguments.
+TARGET_FILE=''
+while [[ "$#" -gt 0 ]]; do
+ case "$1" in
+ --help)
+ print_help
+ exit
+ ;;
+ -*)
+ echo "Illegal option: $1" >&2
+ exit 1
+ ;;
+ *)
+ TARGET_FILE="$1"
+ shift
+ ;;
+ esac
+done
+readonly TARGET_FILE
+
+# Ensure target file is specified.
+if [[ -z "${TARGET_FILE}" ]]; then
+ echo 'Input parameter missing: TARGET_FILE' >&2
+ exit 1
+fi
+
+# Ensure target file exists and is a file.
+if [[ ! -f "${TARGET_FILE}" ]]; then
+ echo "Not a file: ${TARGET_FILE}" >&2
+ exit 1
+fi
+
+# Read the original file line by line, and remove marker sections.
+# This is done by iterating through the lines, and filtering out lines that are
+# either markers themselves, or in between markers.
+preserved_lines=()
+is_in_marker_section='false'
+while IFS='' read -r line; do
+ if [[ "${line}" == "${MARKER_END}" ]]; then
+ if ! "${is_in_marker_section}"; then
+ echo 'Unmatched end marker' >&2
+ exit 1
+ fi
+ is_in_marker_section='false'
+ continue
+ fi
+ if "${is_in_marker_section}" || [[ "${line}" == "${MARKER_START}" ]]; then
+ is_in_marker_section='true'
+ continue
+ fi
+ preserved_lines+=("${line}")
+done < "${TARGET_FILE}"
+
+if "${is_in_marker_section}"; then
+ echo 'Unmatched start marker' >&2
+ exit 1
+fi
+
+# Populate preserved lines to file.
+printf "%s\n" "${preserved_lines[@]}" > "${TARGET_FILE}"