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). Review
on CodeApprove --------- 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}"