diff --git a/packages/ytl-linux-digabi2-examnet/Makefile b/packages/ytl-linux-digabi2-examnet/Makefile index c577efa..c24a1ac 100644 --- a/packages/ytl-linux-digabi2-examnet/Makefile +++ b/packages/ytl-linux-digabi2-examnet/Makefile @@ -1,5 +1,5 @@ NAME := ytl-linux-digabi2-examnet -VERSION := 0.0.19 +VERSION := 0.0.20 DEPENDENCIES := \ --depends apt \ diff --git a/packages/ytl-linux-digabi2-examnet/README.md b/packages/ytl-linux-digabi2-examnet/README.md index 6727e27..da91cc7 100644 --- a/packages/ytl-linux-digabi2-examnet/README.md +++ b/packages/ytl-linux-digabi2-examnet/README.md @@ -4,19 +4,22 @@ This is a proof-of-concept of a procedure which creates proper network settings for Abitti 2 exam server. The setup requires that the server has two network devices - * A WAN device connected to the internet. At the moment this is used to get a - SSL certificate and DNS address for the server. According to the initial plans - it might be later used e.g. to download exam items and upload candidate data. - At the moment a wireless device is good enough for a WAN connection. - * A LAN device connected to the closed local area network. This is an Abitti 1 - style network without any external DHCP/DNS servers. After executing the script - the server starts working as a DHCP/DNS server for the LAN. + +- A WAN device connected to the internet. At the moment this is used to get a + SSL certificate and DNS address for the server. According to the initial plans + it might be later used e.g. to download exam items and upload candidate data. + At the moment a wireless device is good enough for a WAN connection. +- A LAN device connected to the closed local area network. This is an Abitti 1 + style network without any external DHCP/DNS servers. After executing the script + the server starts working as a DHCP/DNS server for the LAN. ## Usage The script is executed from command line: -`$ sudo ytl-linux-digabi2-examnet` +```bash +sudo ytl-linux-digabi2-examnet +``` If executed without parameters, it asks the WAN and LAN devices as well as the server number. It is possible to run multiple servers in one LAN but they must have @@ -24,11 +27,15 @@ different server numbers. It is possible to supply the three parameters in command line: -`ytl-linux-digabi2-examnet wan-device lan-device server-number` +```bash +ytl-linux-digabi2-examnet wan-device lan-device server-number` +``` Example: -`$ sudo ytl-linux-digabi2-examnet wlo1 eth0 1` +```bash +sudo ytl-linux-digabi2-examnet wlo1 eth0 1 +``` It is also possible to run the script in GUI mode (parameter `--gui`). In this case the parameters are asked with Zenity. @@ -37,7 +44,9 @@ parameters are asked with Zenity. Following command should restore the system to pristine state: -`$ sudo ytl-linux-digabi2-examnet --remove` +```bash +sudo ytl-linux-digabi2-examnet --remove +``` It removes the settings files created by this script. It also removes all NetworkManager connections which have a name starting with `yo-`. This is the prefix used by the @@ -47,6 +56,27 @@ script to create the static connection for the local network. The debugging messages can be printed to a given file: -`$ DEBUG=/tmp/whatta.log sudo ytl-linux-digabi2-examnet` +```bash +DEBUG=/tmp/whatta.log sudo ytl-linux-digabi2-examnet +``` The list of exit codes can be found in the script. + +## Building locally + +For macOS, install fpm e.g. with Ruby gem: + +```bash +# Install Ruby and gem, set path +brew install ruby +echo 'export PATH="/opt/homebrew/opt/ruby/bin:$PATH"' >> ~/.zshrc +echo 'export PATH="$(gem environment gemdir)/bin:$PATH"' >> ~/.zshrc +# Install fpm +gem install fpm +``` + +Then build the Debian package: + +```bash +make deb +``` diff --git a/packages/ytl-linux-digabi2-examnet/templates/docker-daemon.json.template b/packages/ytl-linux-digabi2-examnet/templates/docker-daemon.json.template index 5b26125..3c837fe 100644 --- a/packages/ytl-linux-digabi2-examnet/templates/docker-daemon.json.template +++ b/packages/ytl-linux-digabi2-examnet/templates/docker-daemon.json.template @@ -1,3 +1,7 @@ { - "dns": ["${DOCKER_BRIDGE_NETWORK_DNS_RESOLVER_IP}"] + "dns": ["${DOCKER_NETWORK_DNS_RESOLVER_IP}"], + "default-address-pools": + [ + {"base": "${DOCKER_NETWORK_POOL_BASE_IP}/16", "size":24} + ] } diff --git a/packages/ytl-linux-digabi2-examnet/ytl-linux-digabi2-docker-configure.sh b/packages/ytl-linux-digabi2-examnet/ytl-linux-digabi2-docker-configure.sh new file mode 100755 index 0000000..599c231 --- /dev/null +++ b/packages/ytl-linux-digabi2-examnet/ytl-linux-digabi2-docker-configure.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +set -euo pipefail + +readonly PATH_DOCKER=/etc/docker +readonly PATH_DOCKER_DAEMON_CONF=$PATH_DOCKER/daemon.json +readonly PATH_TEMPLATES=/etc/ytl-linux-digabi2-examnet/templates +readonly PATH_DOCKER_DAEMON_CONF_TEMPLATE=$PATH_TEMPLATES/docker-daemon.json.template + +function restart_docker() { + /usr/bin/systemctl restart docker +} + +function get_available_ip_range() { + _ALLOWED_IP_RANGES=("10.0." "192.168." "172.17.") + + for range in "${_ALLOWED_IP_RANGES[@]}"; do + _USED=false + for reserved in "$@"; do + if [[ $reserved == $range* ]]; then + _USED=true + break + fi + done + if [[ "$_USED" == false ]]; then + # return the first available + echo "$range" + return + fi + done + exit -1 +} + +DOCKER_NETWORK_PREFIX=$(get_available_ip_range "$@") +DOCKER_NETWORK_DNS_RESOLVER_IP="$DOCKER_NETWORK_PREFIX"0.1 +DOCKER_NETWORK_POOL_BASE_IP="$DOCKER_NETWORK_PREFIX"0.0 + +export DOCKER_NETWORK_DNS_RESOLVER_IP +export DOCKER_NETWORK_POOL_BASE_IP + +echo "Created Docker configuration, writing to $PATH_DOCKER_DAEMON_CONF" +echo "$(envsubst < $PATH_DOCKER_DAEMON_CONF_TEMPLATE)" +write_file $PATH_DOCKER_DAEMON_CONF "$(envsubst < $PATH_DOCKER_DAEMON_CONF_TEMPLATE)" +restart_docker diff --git a/packages/ytl-linux-digabi2-examnet/ytl-linux-digabi2-examnet b/packages/ytl-linux-digabi2-examnet/ytl-linux-digabi2-examnet index bf1449c..e4714e1 100755 --- a/packages/ytl-linux-digabi2-examnet/ytl-linux-digabi2-examnet +++ b/packages/ytl-linux-digabi2-examnet/ytl-linux-digabi2-examnet @@ -27,6 +27,7 @@ readonly EXIT_CODE_CANNOT_CHANGE_SERVICE_STATE=23 # Cannot change service st readonly EXIT_CODE_MISSING_CERTIFICATE=24 # Cannot find certificate (e.g. download failure, missing file, invalid API key) readonly EXIT_CODE_INVALID_FRIENDLY_NAME=25 # Friendly name contains illegal characters readonly EXIT_CODE_NETWORK_NOT_ONLINE=27 # Network did not come up within timeout +readonly EXIT_CODE_FAILED_TO_CONFIGURE_DOCKER=28 # Failed to configure or restart Docker readonly SCRIPT_PATH=$0 readonly PARAM_NET_DEVICE_WAN=$1 @@ -35,7 +36,6 @@ readonly PARAM_SERVER_NUMBER=$3 readonly PARAM_SERVER_FRIENDLY_NAME=$4 readonly NETWORK_DEVICE_FILTER_RE="^docker|^br|^veth|^lo$" -readonly DOCKER_BRIDGE_NETWORK_DNS_RESOLVER_IP="172.17.0.1" readonly PATH_TEMPLATES=/etc/ytl-linux-digabi2-examnet/templates readonly PATH_RESOLVED=/etc/systemd/resolved.conf.d @@ -45,9 +45,6 @@ readonly PATH_DNSMASQ=/etc/dnsmasq.d readonly PATH_DNSMASQ_CONF=$PATH_DNSMASQ/ytl-linux.conf readonly PATH_DNSMASQ_CONF_TEMPLATE=$PATH_TEMPLATES/dnsmasq.conf.template readonly PATH_DNSMASQ_STATIC_DNS_CONF=$PATH_DNSMASQ/ytl-linux-static-dns-records.conf -readonly PATH_DOCKER=/etc/docker -readonly PATH_DOCKER_DAEMON_CONF=$PATH_DOCKER/daemon.json -readonly PATH_DOCKER_DAEMON_CONF_TEMPLATE=$PATH_TEMPLATES/docker-daemon.json.template readonly PATH_NAKSU2_WORKDIR="${NAKSU2_WORKDIR:-/home/school/.local/share/digabi/naksu2}" readonly PATH_NAKSU2_CERTS_DIR="$PATH_NAKSU2_WORKDIR/certs" readonly PATH_NAKSU2_CERT="$PATH_NAKSU2_CERTS_DIR/cert.pem" @@ -283,14 +280,8 @@ function check_server_number() { fi } -function get_lan_ip_prefix() { - _IP_WAN=$1 - - if [[ "$_IP_WAN" =~ ^192\.168\. ]]; then - $BIN_ECHO "10.0." - else - $BIN_ECHO "192.168." - fi +function get_ip_prefix() { + echo "${1%.*.*}." } function write_file() { @@ -674,11 +665,9 @@ export IP_WAN export IP_LAN export SERVER_NUMBER -IP_LAN_PREFIX=$(get_lan_ip_prefix "$IP_WAN") +IP_LAN_PREFIX=$(get_ip_prefix "$IP_LAN") export IP_LAN_PREFIX -export DOCKER_BRIDGE_NETWORK_DNS_RESOLVER_IP - debug "SUBNETS_PER_SERVER: $CONST_SUBNETS_PER_SERVER" SERVER_HOST_NUMBER=$((SERVER_NUMBER * CONST_SUBNETS_PER_SERVER)) @@ -733,7 +722,6 @@ restart_networkmanager wait_for_network_online write_file $PATH_RESOLVED_CONF "$(envsubst < $PATH_RESOLVED_CONF_TEMPLATE)" -write_file $PATH_DOCKER_DAEMON_CONF "$(envsubst < $PATH_DOCKER_DAEMON_CONF_TEMPLATE)" remove_dnsmasq_settings write_file $PATH_DNSMASQ_CONF "$(envsubst < $PATH_DNSMASQ_CONF_TEMPLATE)" @@ -756,6 +744,9 @@ enable_systemd_services restart_systemd_resolved restart_dnsmasq restart_examnet_daemon -restart_docker + +debug "Configuring Docker daemon" +ytl-linux-digabi2-docker-configure.sh "${IP_WAN}" "${IP_LAN}" +exit_if_error $? $EXIT_CODE_FAILED_TO_CONFIGURE_DOCKER "Failed to configure and restart Docker" print_info "Changes made successfully"