diff --git a/dist/dist-packages/linux/nfpm-openziti-controller.yaml b/dist/dist-packages/linux/nfpm-openziti-controller.yaml index 832203c52..c7c13029c 100644 --- a/dist/dist-packages/linux/nfpm-openziti-controller.yaml +++ b/dist/dist-packages/linux/nfpm-openziti-controller.yaml @@ -43,9 +43,28 @@ contents: - dst: /usr/lib/tmpfiles.d/openziti-controller.conf src: ./dist/dist-packages/linux/openziti-controller/openziti-controller.tmpfiles.conf + +scripts: + postinstall: ./dist/dist-packages/linux/openziti-controller/postinstall.bash + postremove: ./dist/dist-packages/linux/openziti-controller/postrm + +deb: + scripts: + templates: ./dist/dist-packages/linux/openziti-controller/templates + config: ./dist/dist-packages/linux/openziti-controller/config + depends: - openziti # ziti CLI - systemd (>= ${MINIMUM_SYSTEMD_VERSION}) -scripts: - postinstall: ./dist/dist-packages/linux/openziti-controller/postinstall.bash +overrides: + deb: + # debconf is Debian-only; a shared top-level "depends" would land an + # unsatisfiable "debconf" Requires on the rpm build. overrides.deb.depends + # replaces the whole list for deb, so the common deps are repeated here. + depends: + - openziti # ziti CLI + - systemd (>= ${MINIMUM_SYSTEMD_VERSION}) + - debconf (>= 0.5) | debconf-2.0 + + diff --git a/dist/dist-packages/linux/nfpm-openziti-router.yaml b/dist/dist-packages/linux/nfpm-openziti-router.yaml index a682bd0fe..17f008fc8 100644 --- a/dist/dist-packages/linux/nfpm-openziti-router.yaml +++ b/dist/dist-packages/linux/nfpm-openziti-router.yaml @@ -46,7 +46,23 @@ contents: scripts: postinstall: ./dist/dist-packages/linux/openziti-router/postinstall.bash + postremove: ./dist/dist-packages/linux/openziti-router/postrm + +deb: + scripts: + templates: ./dist/dist-packages/linux/openziti-router/templates + config: ./dist/dist-packages/linux/openziti-router/config depends: - openziti # ziti CLI - systemd (>= ${MINIMUM_SYSTEMD_VERSION}) + +overrides: + deb: + # debconf is Debian-only; a shared top-level "depends" would land an + # unsatisfiable "debconf" Requires on the rpm build. overrides.deb.depends + # replaces the whole list for deb, so the common deps are repeated here. + depends: + - openziti # ziti CLI + - systemd (>= ${MINIMUM_SYSTEMD_VERSION}) + - debconf (>= 0.5) | debconf-2.0 diff --git a/dist/dist-packages/linux/openziti-controller/config b/dist/dist-packages/linux/openziti-controller/config new file mode 100755 index 000000000..1c11482e7 --- /dev/null +++ b/dist/dist-packages/linux/openziti-controller/config @@ -0,0 +1,26 @@ +#!/bin/sh +# debconf "config" script: asks questions only, never configures anything. +# Invoked by dpkg-preconfigure before the package's files are unpacked, so +# frontends (dialog, gnome, noninteractive, ...) can batch/skip questions +# before postinst ever runs. See debconf-devel(7) and Debian Policy 3.9.1. +set -e + +. /usr/share/debconf/confmodule + +STATE_DIR="/var/lib/ziti-controller" + +# Only offer the wizard when there's no existing config; re-asking on every +# reconfigure of an already-configured controller would be noise, and the +# wizard isn't meant to run against a live config.yml. +# +# Priority "high" matches debconf's out-of-the-box priority threshold, so an +# interactive install (dialog/readline/gnome frontend, real TTY) still asks +# by default -- same UX as before. An admin who wants silence can lower +# their debconf priority (dpkg-reconfigure debconf); DEBIAN_FRONTEND= +# noninteractive always skips the prompt regardless of priority. +if [ ! -f "${STATE_DIR}/config.yml" ]; then + db_input high openziti-controller/configure-now || true + db_go +fi + +exit 0 diff --git a/dist/dist-packages/linux/openziti-controller/postinstall.bash b/dist/dist-packages/linux/openziti-controller/postinstall.bash index c91443c2d..fe47f4cea 100755 --- a/dist/dist-packages/linux/openziti-controller/postinstall.bash +++ b/dist/dist-packages/linux/openziti-controller/postinstall.bash @@ -247,10 +247,42 @@ case "$action" in ;; esac -# If stdin is a TTY and the controller has no config yet, offer to run -# bootstrap interactively. This fires on fresh install and on upgrade if -# config.yml was deleted. -if [[ -t 0 ]] && [[ ! -f "${STATE_DIR}/config.yml" ]]; then +# This script is shared by both the deb and rpm builds (see +# build-packages.bash), but debconf is deb-only: the "config" script and +# "templates" file that ask this question are wired up only for the deb +# packager (nfpm's deb.scripts.{config,templates}). rpm has no equivalent +# preseeding mechanism, so it keeps the plain TTY-gated prompt. +if [[ -f /usr/share/debconf/confmodule ]]; then + # If the controller has no config yet, ask (via debconf) whether to run + # bootstrap now. The question itself was already asked by the "config" + # script before this postinst ran (or answered from its default); here we + # only retrieve the recorded answer and act on it. Under the noninteractive + # frontend (DEBIAN_FRONTEND=noninteractive, e.g. apt-get -y) debconf never + # touches the terminal — it resolves straight to the template's Default + # ("false") — so this never blocks a scripted install. + if [[ ! -f "${STATE_DIR}/config.yml" ]]; then + # shellcheck disable=SC1091 + set +o nounset + . /usr/share/debconf/confmodule + db_get openziti-controller/configure-now || RET=false + set -o nounset + if [[ "${RET}" == "true" ]]; then + # Run as child process (not exec) so we can catch SIGINT/failure and + # still exit 0 to dpkg — the package is installed regardless. + set +o errexit + /opt/openziti/etc/controller/bootstrap.bash + _rc=$? + set -o errexit + if (( _rc != 0 )); then + echo "Bootstrap exited with code ${_rc}." + echo "Re-run: /opt/openziti/etc/controller/bootstrap.bash" + fi + else + echo "Run /opt/openziti/etc/controller/bootstrap.bash when ready." + fi + db_stop + fi +elif [[ -t 0 ]] && [[ ! -f "${STATE_DIR}/config.yml" ]]; then read -r -p "Configure ziti-controller now? [Y/n]: " _answer case "${_answer,,}" in n|no) diff --git a/dist/dist-packages/linux/openziti-controller/postrm b/dist/dist-packages/linux/openziti-controller/postrm new file mode 100755 index 000000000..d34696051 --- /dev/null +++ b/dist/dist-packages/linux/openziti-controller/postrm @@ -0,0 +1,12 @@ +#!/bin/sh +# Clean up our debconf answers on purge, per debconf-devel(7) "Purging". +set -e + +if [ "$1" = purge ]; then + if [ -f /usr/share/debconf/confmodule ]; then + . /usr/share/debconf/confmodule + db_purge + fi +fi + +exit 0 diff --git a/dist/dist-packages/linux/openziti-controller/templates b/dist/dist-packages/linux/openziti-controller/templates new file mode 100644 index 000000000..538e132d6 --- /dev/null +++ b/dist/dist-packages/linux/openziti-controller/templates @@ -0,0 +1,9 @@ +Template: openziti-controller/configure-now +Type: boolean +Default: true +Description: Configure ziti-controller now? + The controller has no config.yml yet. You can run the bootstrap wizard + now to generate an initial configuration and PKI. + . + If you decline, you can run it later as root: + /opt/openziti/etc/controller/bootstrap.bash diff --git a/dist/dist-packages/linux/openziti-router/config b/dist/dist-packages/linux/openziti-router/config new file mode 100755 index 000000000..2c735a596 --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/config @@ -0,0 +1,26 @@ +#!/bin/sh +# debconf "config" script: asks questions only, never configures anything. +# Invoked by dpkg-preconfigure before the package's files are unpacked, so +# frontends (dialog, gnome, noninteractive, ...) can batch/skip questions +# before postinst ever runs. See debconf-devel(7) and Debian Policy 3.9.1. +set -e + +. /usr/share/debconf/confmodule + +STATE_DIR="/var/lib/ziti-router" + +# Only offer the wizard when there's no existing config; re-asking on every +# reconfigure of an already-configured router would be noise, and the +# wizard isn't meant to run against a live config.yml. +# +# Priority "high" matches debconf's out-of-the-box priority threshold, so an +# interactive install (dialog/readline/gnome frontend, real TTY) still asks +# by default -- same UX as before. An admin who wants silence can lower +# their debconf priority (dpkg-reconfigure debconf); DEBIAN_FRONTEND= +# noninteractive always skips the prompt regardless of priority. +if [ ! -f "${STATE_DIR}/config.yml" ]; then + db_input high openziti-router/configure-now || true + db_go +fi + +exit 0 diff --git a/dist/dist-packages/linux/openziti-router/postinstall.bash b/dist/dist-packages/linux/openziti-router/postinstall.bash index 5bb3cd1bf..d6f4e6cef 100755 --- a/dist/dist-packages/linux/openziti-router/postinstall.bash +++ b/dist/dist-packages/linux/openziti-router/postinstall.bash @@ -247,10 +247,42 @@ case "$action" in ;; esac -# If stdin is a TTY and the router has no config yet, offer to run -# bootstrap interactively. This fires on fresh install and on upgrade if -# config.yml was deleted. -if [[ -t 0 ]] && [[ ! -f "${STATE_DIR}/config.yml" ]]; then +# This script is shared by both the deb and rpm builds (see +# build-packages.bash), but debconf is deb-only: the "config" script and +# "templates" file that ask this question are wired up only for the deb +# packager (nfpm's deb.scripts.{config,templates}). rpm has no equivalent +# preseeding mechanism, so it keeps the plain TTY-gated prompt. +if [[ -f /usr/share/debconf/confmodule ]]; then + # If the router has no config yet, ask (via debconf) whether to run + # bootstrap now. The question itself was already asked by the "config" + # script before this postinst ran (or answered from its default); here we + # only retrieve the recorded answer and act on it. Under the noninteractive + # frontend (DEBIAN_FRONTEND=noninteractive, e.g. apt-get -y) debconf never + # touches the terminal — it resolves straight to the template's Default + # ("false") — so this never blocks a scripted install. + if [[ ! -f "${STATE_DIR}/config.yml" ]]; then + # shellcheck disable=SC1091 + set +o nounset + . /usr/share/debconf/confmodule + db_get openziti-router/configure-now || RET=false + set -o nounset + if [[ "${RET}" == "true" ]]; then + # Run as child process (not exec) so we can catch SIGINT/failure and + # still exit 0 to dpkg — the package is installed regardless. + set +o errexit + /opt/openziti/etc/router/bootstrap.bash + _rc=$? + set -o errexit + if (( _rc != 0 )); then + echo "Bootstrap exited with code ${_rc}." + echo "Re-run: /opt/openziti/etc/router/bootstrap.bash" + fi + else + echo "Run /opt/openziti/etc/router/bootstrap.bash when ready." + fi + db_stop + fi +elif [[ -t 0 ]] && [[ ! -f "${STATE_DIR}/config.yml" ]]; then read -r -p "Configure ziti-router now? [Y/n]: " _answer case "${_answer,,}" in n|no) diff --git a/dist/dist-packages/linux/openziti-router/postrm b/dist/dist-packages/linux/openziti-router/postrm new file mode 100755 index 000000000..d34696051 --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/postrm @@ -0,0 +1,12 @@ +#!/bin/sh +# Clean up our debconf answers on purge, per debconf-devel(7) "Purging". +set -e + +if [ "$1" = purge ]; then + if [ -f /usr/share/debconf/confmodule ]; then + . /usr/share/debconf/confmodule + db_purge + fi +fi + +exit 0 diff --git a/dist/dist-packages/linux/openziti-router/templates b/dist/dist-packages/linux/openziti-router/templates new file mode 100644 index 000000000..dd611ce8b --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/templates @@ -0,0 +1,9 @@ +Template: openziti-router/configure-now +Type: boolean +Default: true +Description: Configure ziti-router now? + The router has no config.yml yet. You can run the bootstrap wizard + now to generate an initial configuration and PKI. + . + If you decline, you can run it later as root: + /opt/openziti/etc/router/bootstrap.bash