#! /usr/bin/env bash # file : etc/private/install/brep-install # license : MIT; see accompanying LICENSE file # Setup HTTP-only brep instance with unsigned package submission support via # direct repository publishing (brep/handler/submit/submit-pub). # # NOTE: this setup should only be used in private/trusted environments. # # Unless the --setup option is specified, create the 'brep' group and user and # re-run itself with the --setup option under this user. In the setup mode # install and configure the brep instance, automating the instructions from # the INSTALL file, including: # # - Build the build2 toolchain (installing it to /usr/local/) and brep # (installing it to ~brep/install/). # # - Install PostgreSQL and create brep users/databases. # # - Installing Apache2 and configure HTTP server with the brep module. # # Note that the script is written for use on Debian-based distributions so you # will need to adjust it to match other distributions or operating systems. # # Options: # # --mount # # Mount the virtio-9p device with id 'state' as the /var/brep directory. # This directory is expected to either contain the pkg repository or be # empty, in which case an empty repository will be automatically # initialized. If this option is unspecified, the directory will be created # in the local filesystem. # # --brep-user # # User and group ids to use when creating the 'brep' group and user. If # unspecified, 63700 is used. # # --setup # # Install and configure the brep instance, assuming that the 'brep' user # already exists and this script is executed as this user. # # --clean # # At the end of the brep instance setup remove installation environment- # specific traces (host name/IP from the configuration files, etc). Normally # you would use this option to make the "clean" machine copy for # distribution. Note that if this option is specified, then the brep # instance will only be unusable after the machine reboot. # usage="Usage: $0 []" # build2 toolchain repository certificate fingerprint. Note: this is a # repository the toolchain installation script downloads the build2 packages # from. # toolchain_repo_cert_fp="86:BA:D4:DE:2C:87:1A:EE:38:C7:F1:64:7F:65:77:02:15:79:F3:C4:83:C0:AB:5A:EA:F4:F7:8C:1D:63:30:C6" #toolchain_repo_cert_fp="37:CE:2C:A5:1D:CF:93:81:D7:07:46:AD:66:B3:C3:90:83:B8:96:9E:34:F0:E7:B3:A2:B0:6C:EF:66:A4:BE:65" # brep package repository URL and certificate fingerprint. # #brep_repo_url="https://pkg.cppget.org/1/alpha" #brep_repo_cert_fp="86:BA:D4:DE:2C:87:1A:EE:38:C7:F1:64:7F:65:77:02:15:79:F3:C4:83:C0:AB:5A:EA:F4:F7:8C:1D:63:30:C6" brep_repo_url="https://stage.build2.org/1" brep_repo_cert_fp="37:CE:2C:A5:1D:CF:93:81:D7:07:46:AD:66:B3:C3:90:83:B8:96:9E:34:F0:E7:B3:A2:B0:6C:EF:66:A4:BE:65" owd=`pwd` trap "{ exit 1; }" ERR trap "{ cd $owd; }" EXIT set -o errtrace # Trap in functions. function info () { echo "$*" 1>&2; } function error () { info "error: $*"; exit 1; } # Trace a command line, quoting empty arguments as well as those that contain # spaces. # function trace () # ... { local s="+" while [ "$#" -gt 0 ]; do if [ -z "$1" -o -z "${1##* *}" ]; then s="$s \"$1\"" else s="$s $1" fi shift done info "$s" } # Trace and run a command. # run () # ... { trace "$@" "$@" } # The chosen fixed id for the 'brep' user. Note: must match the id of the # 'brep' user on the host. # # Note that Linux assigns the [0 99] range for the statically allocated system # users and [100 499] -- for dynamic allocations by administrators and post- # install scripts. Debian, in turn, assigns the [100 999] range for the # dynamically allocated system users and [60000 64999] -- for statically # allocated on demand "obscure package users". # brep_id=63700 # Update the README file on change. # Parse the command line options and, while at it, compose the options array # for potential re-execution as the 'brep' user. # mount= setup= clean= ops=() while [ "$#" -gt 0 ]; do case "$1" in --mount) mount=true ops+=("$1") shift ;; --brep-user) shift brep_id="$1" shift ;; --setup) setup=true shift ;; --clean) clean=true ops+=("$1") shift ;; *) break # The end of options is encountered. ;; esac done if [ "$#" -ne 0 ]; then error "$usage" fi scr_exe="$(realpath "${BASH_SOURCE[0]}")" scr_dir="$(dirname "$scr_exe")" # Unless we are not in the setup mode, non-interactively add the 'brep' # user/group and re-execute the script in the setup mode as this user. # if [ ! "$setup" ]; then run sudo addgroup --gid "$brep_id" brep run sudo adduser --uid "$brep_id" --gid "$brep_id" --disabled-password \ --gecos "" brep run sudo tee -a /etc/sudoers.d/brep >/dev/null </dev/null </dev/null run psql -d brep_build -c "$q" >/dev/null run psql -d brep_submit_package -c "$q" >/dev/null run sudo sudo -u www-data psql -d brep_package -c "$q" >/dev/null run sudo sudo -u www-data psql -d brep_build -c "$q" >/dev/null # Setup the connection between the databases. # run sudo sudo -u postgres psql -d brep_build </dev/null run psql -d brep_build -c 'SELECT package_name FROM build' >/dev/null run psql -d brep_build -c 'SELECT DISTINCT name FROM build_package' >/dev/null run psql -d brep_submit_package -c 'SELECT canonical_name, summary FROM repository' >/dev/null # Setup executing the brep-startup script on boot. # run sudo cp "$scr_dir/brep-startup.service" /etc/systemd/system/ run sudo systemctl start brep-startup.service # Make sure there are no issues. run sudo systemctl enable brep-startup.service # Prepare directories for the package submission service. # run mkdir submit-data run mkdir submit-temp run setfacl -m g:www-data:rwx submit-data run setfacl -m g:www-data:rwx submit-temp # Make the Apache2 user owned directories fully accessible by the 'brep' user # (which the submit-pub submission handler will run as). # run setfacl -dm g:brep:rwx submit-data run setfacl -dm g:brep:rwx submit-temp # Add the Apache2 user to sudoers, so the submission handler can re-execute # itself as the 'brep' user. # run sudo tee -a /etc/sudoers.d/www-data >/dev/null </dev/null # Make sure the Apache2 service depends on PostgreSQL and # brep-startup.service, so that they are started in proper order. # run sudo mkdir -p /etc/systemd/system/apache2.service.d/ run sudo tee /etc/systemd/system/apache2.service.d/postgresql.conf >/dev/null </dev/null </dev/null </dev/null || ec="$?" if [ "$ec" -ne 3 ]; then error "exit code 3 (unit is not active) is expected instead of $ec" fi # Verify that Apache2 is started after PostgreSQL is started. # run sudo systemctl start postgresql run sleep 3 run sudo systemctl status apache2 >/dev/null # Setup periodic loader execution. # run sudo cp "$scr_dir/brep-load.service" /etc/systemd/system/ run sudo cp "$scr_dir/brep-load.timer" /etc/systemd/system/ run sudo systemctl start brep-load.service # Make sure there are no issues. run sudo systemctl start brep-load.timer run sudo systemctl status brep-load.timer >/dev/null run sudo systemctl enable brep-load.timer run sudo systemctl status brep-load.timer >/dev/null # Cleanup the installation environment-specific traces, if requested. # if [ "$clean" ]; then # Stop the relevant services. # run sudo systemctl stop brep-load.timer run sudo systemctl stop apache2 # Remove the host name/IP from the configuration. # run cp "$scr_dir/brep-module.conf" config/ # Adjusted by brep-startup. run rm config/loadtab # Recreated by brep-startup. # Finally, stop networking and cleanup the DHCP lease information. # # Note that after networking is stopped, sudo prints the 'unable to resolve # host' diagnostics while trying to obtain the host IP. Thus, we execute the # last two commands via a single sudo call. # run sudo bash -c "systemctl stop networking && rm -rf /var/lib/dhcp/*.leases" fi