From f447d7a70af46bf94494ced65834c9ed4efb3ad3 Mon Sep 17 00:00:00 2001 From: Matteo Nastasi Date: Wed, 7 Oct 2026 09:50:11 +0000 Subject: [PATCH] write every file of the machine from the "system" action The nginx configuration and the nftables rules were written by an ordinary install, the systemd unit by "INSTALL.sh system", and the sysv script it replaces had always been there. Three files that all belong to the machine and not to the tree of the site, written from two different places. They now all come from the "system" action, with the same options as the install: the nginx configuration of the site, the nftables rules of the daemon machine, and the way the daemon is started. An install writes none of them. An install is run whenever the code changes; these follow the shape of the machine, which changes almost never, and writing them every time only risks overwriting a file somebody has since adapted. What the action writes depends on the machine, as before: no nginx configuration with -S apache, on a daemon machine (-m server) or in the historic -D FALSE mode; no nftables rules unless the daemon is on tcp and -I gives the address of the front; no daemon on a front, so no unit and no sysv script there. Only the sysv script is still installed by the action itself, being the one file that is of no use anywhere else; everything else is written in Etc and the action ends with the list of what to copy where. An install now says that the files of the machine come from "system". -h lists the action. pool_size() reads the installed tree when the tree being built is not there, which is the case in the action. Checked in the container: an install of all three roles writes no file of the machine, and the action writes, for -m full, the three nginx files and the unit; for -m server, the nftables rules with the pool read from the installed tree (8090-8099 plus 8100) and the unit; for -m front, the nginx files alone. The unit passes systemd-analyze verify. nft is not installed there, so the rules were checked with nft -c in the earlier commits, where the generator was the same. Co-Authored-By: Claude Opus 5 (1M context) --- INSTALL.sh | 174 +++++++++++++++++++++++++--------------- WARNING.txt | 24 +++--- system/nginx/brisk.conf | 11 +-- 3 files changed, 129 insertions(+), 80 deletions(-) diff --git a/INSTALL.sh b/INSTALL.sh index 685a604..651bc93 100755 --- a/INSTALL.sh +++ b/INSTALL.sh @@ -41,15 +41,15 @@ install_mode="full" # apache install the .htaccess files, as it has always done # nginx install none of them web_server="apache" -# With -S nginx INSTALL.sh writes the nginx configuration of the site next to -# the brisk configuration, in Etc. The pages the daemon does not serve go to +# With -S nginx the "system" action writes the nginx configuration of the site +# next to the brisk configuration, in Etc. The pages the daemon does not serve go to # php-fpm: where it listens (anything fastcgi_pass accepts) and where the # tree is on that machine, which is not this one when php-fpm runs on the # daemon host. An empty fpm_root means the root of the site here. fpm_pass="unix:/run/php/php8.4-fpm.sock" fpm_root="" -# With -m server and the daemon on tcp, INSTALL.sh writes in Etc the nftables -# rules that let only the front reach the daemon ports - and php-fpm, when +# With -m server and the daemon on tcp, the "system" action writes in Etc the +# nftables rules that let only the front reach the daemon ports - and php-fpm, when # the php-fpm of this machine serves the front. front_ip is the address of the # front as this machine sees it; fpm_pool_glob is where the php-fpm pools are # looked for. @@ -62,6 +62,8 @@ function usage () { echo "$1 -h" echo "$1 chk - run lintian on all ph* files." echo "$1 pkg - build brisk packages." + echo "$1 system [same options] - write in Etc the files of the machine:" + echo " nginx conf, nftables rules, systemd unit." echo "$1 [-W] [-n 3|5] [-c 2|8] [-t <(n>=4)>] [-T ] [-r ] [-G ] [-A ] [-a ] [-f ] [-p ] [-U ] [-D ] [-u ] [-d ] [-w ] [-k ] [-l ] [-y ] [-P ] [-m ] [-S ] [-F ] [-B ] [-I ] [-x]" echo " -h this help" echo " -f use this config file" @@ -91,12 +93,12 @@ function usage () { echo " -m machine role: full|server|front - def. \"$install_mode\"" echo " (server: no images, no static; front: no private dirs)" echo " -S http server: apache|nginx - def. \"$web_server\"" - echo " (nginx: no .htaccess installed, nginx conf written in Etc)" + echo " (nginx: no .htaccess installed; \"system\" writes the nginx conf)" echo " -F php-fpm address for nginx - def. \"$fpm_pass\"" echo " (e.g. 10.0.0.6:9000 when php-fpm runs on the daemon machine)" echo " -B site root on the php-fpm host - def. the root of the site here" echo " -I address of the front machine - def. \"$front_ip\"" - echo " (-m server with -U tcp://: nftables rules written in Etc)" + echo " (-m server with -U tcp://: \"system\" writes the nftables rules)" echo " -x copy tests as normal php - def. \"$test_add\"" echo } @@ -164,11 +166,18 @@ function inst_var() { inst_name | sed 's/[^A-Za-z0-9_]/_/g' } -# USOCK_POOL_N as the installed tree defines it +# USOCK_POOL_N as the tree defines it. During an installation the tree being +# built is the one to read; the "system" action runs on its own, with only the +# installed tree to look at. function pool_size() { - local n + local f n - n="$(sed -n "s/^define('USOCK_POOL_N', *\([0-9]\+\)).*/\1/p" "${web_path}__/spush/brisk-spush.phh")" + for f in "${web_path}__/spush/brisk-spush.phh" "${web_path}/spush/brisk-spush.phh"; do + if [ -f "$f" ]; then + n="$(sed -n "s/^define('USOCK_POOL_N', *\([0-9]\+\)).*/\1/p" "$f")" + break + fi + done echo "${n:-10}" } @@ -203,7 +212,8 @@ function has_systemd() { [ -d /run/systemd/system ] && command -v systemctl >/dev/null 2>&1 } -# The systemd unit of the daemon, written in Etc as .service, to be +# The systemd unit of the daemon, written in Etc as .service by the +# "system" action, to be # copied by hand into /etc/systemd/system/. It replaces bin/brisk-init.sh, # which wrapped the daemon in a screen session and respawned it with a shell # loop: Restart= is that loop, and the log goes to the journal instead of @@ -337,7 +347,7 @@ function nft_conf_gen() { echo " php-fpm serves the front from here (port ${fpm_ports}): included" else echo " php-fpm does not listen on tcp here: only the daemon ports are covered." - echo " Configure php-fpm first and run INSTALL.sh again if it has to serve the front." + echo " Configure php-fpm first and run \"INSTALL.sh system\" again if it has to serve the front." fi } @@ -713,15 +723,28 @@ fi max_players=$((40 + players_n * tables_n)) +# The "system" action writes every file that belongs to the machine rather +# than to the tree of the site: the nginx configuration, the nftables rules +# and the way the daemon is started. None of them is installed, because none +# of their directories belongs to this user: they are written in Etc, beside +# the brisk configuration, and the action says what to copy where. +# +# They are not written by an ordinary installation on purpose: an install is +# run whenever the code changes, while these follow the shape of the machine, +# which changes almost never. if [ "$action" = "system" ]; then - scrname="$(echo "$prefix_path" | sed 's@^/@@g;s@/$@@g;s@/@_@g;')" + scrname="$(inst_name)" echo echo "script name: [$scrname]" echo "brisk path: [$web_path]" echo "private path: [$legal_path]" echo "system user: [$sys_user]" + echo "machine role: [$install_mode]" + echo "http server: [$web_server]" echo - if has_systemd; then + if [ "$install_mode" = "front" ]; then + echo "init system: [-] no daemon on a front" + elif has_systemd; then echo "init system: [systemd] -> a unit, written in Etc" else echo "init system: [no systemd] -> the sysv script, in /etc/init.d" @@ -729,39 +752,77 @@ if [ "$action" = "system" ]; then echo read -p "press enter to continue" sure - if has_systemd; then - # Etc is where the other generated files go; this action runs before - # the pre-check that looks it up, so it is looked up here. - etc_path="$(searchetc "$(dirname "$web_path")" Etc)" - if [ $? -ne 0 ]; then - echo "Etc directory not found above $(dirname "$web_path")" - exit 1 - fi - echo "systemd unit:" - systemd_unit_gen - echo - echo "... DONE." - echo "DON'T FORGET: the unit is only written, not installed. Copy it, then:" - echo - echo " su -c 'cp $etc_path/${scrname}.service /etc/systemd/system/'" - echo " su -c 'systemctl daemon-reload'" - echo " su -c 'systemctl enable --now ${scrname}'" - echo - exit 0 + # Etc is where the generated files go. This action runs before the + # pre-check that looks it up, so it is looked up here. + etc_path="$(searchetc "$(dirname "$web_path")" Etc)" + if [ $? -ne 0 ]; then + echo "Etc directory not found above $(dirname "$web_path")" + exit 1 fi - cp bin/brisk-init.sh brisk-init.sh.wrk - sed -i "s@^BPATH=.*@BPATH=\"${web_path}\"@g;s@^PPATH=.*@PPATH=\"${legal_path}\"@g;s@^SSUFF=.*@SSUFF=\"${scrname}\"@g;s@^BUSER=.*@BUSER=\"${sys_user}\"@g" brisk-init.sh.wrk + sys_todo="" + + # --- nginx --- + # The daemon machine of a split installation has no nginx: the + # configuration belongs to the front. And the historic mode needs a + # descriptor handover module this configuration knows nothing about. + if [ "$web_server" != "nginx" ]; then + echo "nginx configuration not written: -S apache." + elif [ "$install_mode" = "server" ]; then + echo "nginx configuration not written: it goes on the front machine (-m front)." + elif [ "$http_direct" != "TRUE" ]; then + echo "nginx configuration not written: -D FALSE needs the descriptor handover" + echo "module, see WARNING.txt." + else + echo "nginx configuration:" + nginx_conf_gen + sys_todo="${sys_todo} su -c 'ln -s $etc_path/nginx-${scrname}.conf /etc/nginx/conf.d/'\n" + sys_todo="${sys_todo} include $etc_path/nginx-${scrname}-server.conf inside the server {} of the site\n" + sys_todo="${sys_todo} su -c 'nginx -t' && su -c 'systemctl reload nginx'\n" + fi - su -c "cp brisk-init.sh.wrk /etc/init.d/${scrname}" + # --- nftables --- + # Over tcp the ports of the daemon have to be closed to everybody but + # the front, whatever the http server of the front is. + if [ "$install_mode" != "server" ] || ! echo "$usock_path_pfx" | grep -q '^tcp://'; then + : + elif [ -z "$front_ip" ]; then + echo "nftables rules not written: pass the address of the front with -I." + else + echo "nftables rules:" + nft_conf_gen + sys_todo="${sys_todo} su -c 'cp $etc_path/${scrname}.nft /etc/nftables.d/'\n" + sys_todo="${sys_todo} su -c 'nft -c -f /etc/nftables.d/${scrname}.nft' && su -c 'nft -f /etc/nftables.d/${scrname}.nft'\n" + fi + + # --- how the daemon is started --- + if [ "$install_mode" = "front" ]; then + : # no daemon here + elif has_systemd; then + echo "systemd unit:" + systemd_unit_gen + sys_todo="${sys_todo} su -c 'cp $etc_path/${scrname}.service /etc/systemd/system/'\n" + sys_todo="${sys_todo} su -c 'systemctl daemon-reload'\n" + sys_todo="${sys_todo} su -c 'systemctl enable --now ${scrname}'\n" + else + # No systemd: the sysv script is what starts the daemon, and this is + # the one file the action installs itself, as it always has. + cp bin/brisk-init.sh brisk-init.sh.wrk + sed -i "s@^BPATH=.*@BPATH=\"${web_path}\"@g;s@^PPATH=.*@PPATH=\"${legal_path}\"@g;s@^SSUFF=.*@SSUFF=\"${scrname}\"@g;s@^BUSER=.*@BUSER=\"${sys_user}\"@g" brisk-init.sh.wrk + su -c "cp brisk-init.sh.wrk /etc/init.d/${scrname}" + rm brisk-init.sh.wrk + echo "sysv script installed as /etc/init.d/${scrname}" + sys_todo="${sys_todo} su -c 'update-rc.d $scrname defaults'\n" + fi - rm brisk-init.sh.wrk echo echo "... DONE." - echo "DON'T FORGET: after the first installation you MUST configure your run-levels accordingly" - echo - echo "Example: su -c 'update-rc.d $scrname defaults'" - echo + if [ -n "$sys_todo" ]; then + echo "DON'T FORGET: nothing above is in place yet. To put it there:" + echo + printf "$sys_todo" + echo + fi exit 0 fi # @@ -1116,32 +1177,6 @@ elif [ ! -f "$etc_path/.htaccess" ]; then EOEOF fi -# nginx on the daemon machine of a split installation has nothing to do: the -# configuration belongs to the front. And the historic mode needs a -# descriptor handover module this configuration knows nothing about. -if [ "$web_server" = "nginx" ]; then - if [ "$install_mode" = "server" ]; then - echo "nginx configuration not written: it goes on the front machine (-m front)." - elif [ "$http_direct" != "TRUE" ]; then - echo "nginx configuration not written: -D FALSE needs the descriptor handover" - echo "module, see WARNING.txt." - else - echo "nginx configuration:" - nginx_conf_gen - fi -fi - -# The daemon machine of a split installation: whatever the http server of the -# front, the ports here have to be closed to everybody but the front. -if [ "$install_mode" = "server" ] && echo "$usock_path_pfx" | grep -q '^tcp://'; then - if [ -z "$front_ip" ]; then - echo "nftables rules not written: pass the address of the front with -I." - else - echo "nftables rules:" - nft_conf_gen - fi -fi - if [ -d ${web_path} ]; then mv ${web_path} ${web_path}.old fi @@ -1168,6 +1203,13 @@ case "$install_mode" in echo ;; esac +# The files of the machine - nginx, nftables, the way the daemon starts - are +# not touched by an install: they follow the shape of the machine, not the +# code. On a first installation they are still missing. +echo "The files of the MACHINE (nginx configuration, nftables rules, systemd unit)" +echo "are written by \"$0 system\" with these same options, not from here." +echo + if [ -f WARNING.txt ]; then echo ; echo " ==== WARNING ====" echo diff --git a/WARNING.txt b/WARNING.txt index 6de382f..2d7d94a 100644 --- a/WARNING.txt +++ b/WARNING.txt @@ -18,16 +18,22 @@ Sample configuration, ready to be adapted: system/nginx/brisk.conf -> /etc/nginx/sites-available/brisk system/nginx/brisk-daemon.inc -> /etc/nginx/brisk-daemon.inc -Or let INSTALL.sh write it with -S nginx: three files in Etc, beside the -brisk configuration, already aligned with -P, -U and the root of the site -(nginx-.conf at http level, nginx--server.conf inside the -server {}, nginx--daemon.inc for the nine daemon urls). -F and -B say -where php-fpm is when it does not run on the same machine. +Or let "INSTALL.sh system" write it with -S nginx: three files in Etc, +beside the brisk configuration, already aligned with -P, -U and the root of +the site (nginx-.conf at http level, nginx--server.conf inside +the server {}, nginx--daemon.inc for the nine daemon urls). -F and -B +say where php-fpm is when it does not run on the same machine. With the daemon on a machine of its own (-m server -U tcp://...), pass -I -with the address of the front: INSTALL.sh writes in Etc .nft, the -nftables rules that leave the daemon ports, and php-fpm when it listens on -tcp there, reachable by the front alone. Copy it into /etc/nftables.d/. +with the address of the front and the same action writes in Etc .nft, +the nftables rules that leave the daemon ports, and php-fpm when it listens +on tcp there, reachable by the front alone. Copy it into /etc/nftables.d/. + +Everything that belongs to the machine rather than to the tree of the site - +these files and the way the daemon is started - comes from that one action, +with the same options as the install. An ordinary install writes none of it: +it is run whenever the code changes, while these follow the shape of the +machine, which changes almost never. The values to keep aligned with those passed to INSTALL.sh are listed at the top of brisk.conf: the root of the site, the url prefix and the path of the @@ -103,7 +109,7 @@ usermgmt.php, the .css and the .js) is still served by apache. 13 that script is never run: the sysv compatibility generator of systemd is gone, so nothing turns it into a service and nothing starts it at boot. -Where systemd is in charge, the action now writes a unit in Etc instead, +Where systemd is in charge the action writes a unit instead, in Etc as .service beside the other generated files, and leaves /etc/init.d alone. It is only written: copy it, reload, enable. diff --git a/system/nginx/brisk.conf b/system/nginx/brisk.conf index 4e21920..f018f12 100644 --- a/system/nginx/brisk.conf +++ b/system/nginx/brisk.conf @@ -15,9 +15,9 @@ # the unix sockets <- usock_path_pfx (-U) + + ".sock", N from 0 to # USOCK_POOL_N-1 (10 by default, in brisk-spush.phh) # -# Instead of adapting this file by hand, INSTALL.sh -S nginx writes the same -# configuration already aligned with those values, in Etc beside the brisk -# configuration ( comes from -P): +# Instead of adapting this file by hand, "INSTALL.sh system" with -S nginx +# writes the same configuration already aligned with those values, in Etc +# beside the brisk configuration ( comes from -P): # nginx-.conf http level: the upgrade map and the upstream # nginx--server.conf to include inside the server {} of the site # nginx--daemon.inc included by each of the nine daemon urls @@ -55,8 +55,9 @@ upstream brisk_daemon { # blacklist are built on, and it still speaks plain http, so the session # cookies cross the network in clear. The port has to be reachable by this # machine and by nothing else: with -I
, the -# "-m server" installation writes the nftables rules that do it in its Etc, -# .nft, php-fpm included when it listens there for this machine. +# "system" action on the daemon machine writes the nftables rules that do it +# in its Etc, .nft, php-fpm included when it listens there for this +# machine. # And the comet streams sit idle for as long as proxy_read_timeout allows, # an hour below: anything stateful in between - # a firewall, a NAT - will drop them long before that unless it is told not -- 2.47.3