Skip to content

Commit

Permalink
Add status server (getumbrel#812)
Browse files Browse the repository at this point in the history

Co-authored-by: Mayank <mayankchhabra9@gmail.com>
Co-authored-by: Aaron Dewes <aaron.dewes@web.de>
Co-authored-by: Lounès Ksouri <dev@louneskmt.com>
  • Loading branch information
4 people authored Jun 10, 2021
1 parent 95e4437 commit 2fb71be
Show file tree
Hide file tree
Showing 18 changed files with 695 additions and 3 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
.ssh
.viminfo

# Python bytecode
__pycache__
*.py[cod]

# umbrel-dev
docker-compose.override.yml

Expand Down
7 changes: 7 additions & 0 deletions scripts/start
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ check_dependencies rsync jq curl
UMBREL_ROOT="$(dirname $(readlink -f "${BASH_SOURCE[0]}"))/.."
UMBREL_LOGS="${UMBREL_ROOT}/logs"

set_status="${UMBREL_ROOT}/scripts/umbrel-os/status-server/set-status"

$set_status umbrel started

if [[ ! -d "$UMBREL_ROOT" ]]; then
echo "Root dir does not exist '$UMBREL_ROOT'"
$set_status umbrel errored umbrel-root-missing
exit 1
fi

Expand Down Expand Up @@ -109,3 +114,5 @@ echo " http://${DEVICE_IP}"
if [[ ! -z "${hidden_service_url:-}" ]]; then
echo " http://${hidden_service_url}"
fi

$set_status umbrel completed
3 changes: 3 additions & 0 deletions scripts/umbrel-os/external-storage/monitor
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ UMBREL_ROOT="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../../..)"
block_device="${1}"
mount_point="${2}"

set_status="/sd-root/${UMBREL_ROOT}/scripts/umbrel-os/status-server/set-status"

check_if_not_already_running() {
if ps ax | grep $0 | grep -v $$ | grep bash | grep -v grep
then
Expand Down Expand Up @@ -42,6 +44,7 @@ main () {
done

echo "Stopping Umbrel due to failed storage device check..."
$set_status mount errored monitor-check
docker kill $(docker ps -aq)
}

Expand Down
13 changes: 10 additions & 3 deletions scripts/umbrel-os/external-storage/mount
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ EXTERNAL_DOCKER_DIR="${MOUNT_POINT}/docker"
SWAP_DIR="/swap"
SWAP_FILE="${SWAP_DIR}/swapfile"

set_status="${UMBREL_ROOT}/scripts/umbrel-os/status-server/set-status"

check_root () {
if [[ $UID != 0 ]]; then
echo "This script must be run as root"
Expand Down Expand Up @@ -143,6 +145,7 @@ copy_docker_to_external_storage () {
}

main () {
$set_status mount started
echo "Running external storage mount script..."
check_root
check_dependencies sed wipefs parted mount sync umount
Expand All @@ -164,6 +167,7 @@ main () {
if [[ $retry_for_block_devices -gt 20 ]]; then
echo "No block devices found in 20 tries..."
echo "Exiting mount script without doing anything"
$set_status mount errored no-block-device
exit 1
fi

Expand All @@ -172,6 +176,7 @@ main () {
if [[ $no_of_block_devices -gt 1 ]]; then
echo "Multiple block devices found, only one drive is supported"
echo "Exiting mount script without doing anything"
$set_status mount errored multiple-block-devices
exit 1
fi

Expand All @@ -192,6 +197,7 @@ main () {
if [[ $retry_for_usb_devices -gt 10 ]]; then
echo "USB devices weren't registered after 10 tries..."
echo "Exiting mount script without doing anything"
$set_status mount errored rebinding-failed
exit 1
fi

Expand All @@ -206,16 +212,16 @@ main () {
mount_partition "${partition_path}"

echo "Checking if device contains an Umbrel install..."

if [[ -f "${EXTERNAL_UMBREL_ROOT}"/.umbrel ]]; then
echo "Yes, it contains an Umbrel install"
else
else
echo "No, it doesn't contain an Umbrel install"
echo "Unmounting partition..."
unmount_partition
setup_new_device $block_device $partition_path
fi

else
echo "No, it's not ext4"
setup_new_device $block_device $partition_path
Expand Down Expand Up @@ -266,6 +272,7 @@ main () {
${UMBREL_ROOT}/scripts/umbrel-os/external-storage/monitor ${block_device} ${MOUNT_POINT} &

echo "Mount script completed successfully!"
$set_status mount completed
}

main
6 changes: 6 additions & 0 deletions scripts/umbrel-os/external-storage/update-from-sdcard
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ UMBREL_ROOT="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../../..)"
SD_MOUNT_POINT="/sd-root"
SD_UMBREL_ROOT="${SD_MOUNT_POINT}${UMBREL_ROOT}"

set_status="${UMBREL_ROOT}/scripts/umbrel-os/status-server/set-status"

check_root () {
if [[ $UID != 0 ]]; then
echo "This script must be run as root"
Expand All @@ -31,12 +33,14 @@ check_semver_range () {
main () {
check_root
check_dependencies jq
$set_status sdcard-update started
echo "Checking if SD card Umbrel is newer than external storage..."
local external_version=$(cat "${UMBREL_ROOT}/info.json" | jq -r .version | cut -d "-" -f "1")
local sd_version=$(cat "${SD_UMBREL_ROOT}/info.json" | jq -r .version | cut -d "-" -f "1")

if ! check_semver_range ">${external_version}" "${sd_version}"; then
echo "No, SD version is not newer, exiting."
$set_status sdcard-update completed
exit 0
fi

Expand All @@ -48,11 +52,13 @@ main () {
echo "Checking if the external storage version \"${external_version}\" satisfies update requirement \"${update_requirement}\"..."
if ! check_semver_range "${update_requirement}" "${external_version}"; then
echo "No, we can't do an automatic update, exiting."
$set_status sdcard-update errored semver-mismatch
exit 0
fi

echo "Yes, it does, attempting an automatic update..."
"${UMBREL_ROOT}/scripts/update/update" --path "${SD_UMBREL_ROOT}"
$set_status sdcard-update completed
}

main
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Umbrel Status Server iptables Update
# Installed at /etc/systemd/system/umbrel-status-server-iptables-update.service

# This is needed because when Docker starts it appends its own iptables rules
# after ours. This means traffic on port 80 will never arrive at a Docker container
# because we always redirect it. We can remove the rule and then re-apply it so
# it gets appended after the Docker rule so port 80 will only continue to be
# routed to the status server until a Docker container listens on port 80.

[Unit]
Description=Status Server iptables Update
Wants=docker.service
After=docker.service

[Service]
Type=oneshot
ExecStart=/status-server/setup-iptables
User=root
Group=root
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=status server iptables

[Install]
WantedBy=multi-user.target
21 changes: 21 additions & 0 deletions scripts/umbrel-os/services/umbrel-status-server.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Umbrel Status Server
# Installed at /etc/systemd/system/umbrel-status-server.service

[Unit]
Description=Status Server
Before=umbrel-external-storage-sdcard-update.service
Before=umbrel-external-storage.service
Before=umbrel-startup.service

[Service]
Type=exec
ExecStartPre=/home/umbrel/umbrel/scripts/umbrel-os/status-server/setup
ExecStart=/status-server/status-server
User=root
Group=root
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=status server

[Install]
WantedBy=multi-user.target
31 changes: 31 additions & 0 deletions scripts/umbrel-os/status-server/set-status
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash

STATUS_FILE_PATH="/umbrel-status"

service_id="${1}"
status="${2}"
error_code="${3}"

source /etc/default/umbrel 2> /dev/null
if [[ -z "${UMBREL_OS:-}" ]]; then
echo "Skipping status update when not on Umbrel OS"
exit
fi

if [[ "${service_id}" == "" ]]; then
echo "Error: Missing ID"
exit 1
fi

if [[ "${status}" == "" ]]; then
echo "Error: Missing Status"
exit 1
fi

entry="${service_id}:${status}"

if [[ "${error_code}" != "" ]]; then
entry="${entry}:${error_code}"
fi

echo "${entry}" >> "${STATUS_FILE_PATH}"
24 changes: 24 additions & 0 deletions scripts/umbrel-os/status-server/setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

UMBREL_ROOT="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../../..)"
BIND_MOUNT_PATH="/status-server"
STATUS_FILE_PATH="/umbrel-status"

# Bind mount status server to new location so we always run on the SD card
echo "Bind mounting status server to ${BIND_MOUNT_PATH}..."
[[ ! -d "${BIND_MOUNT_PATH}" ]] && mkdir -p "${BIND_MOUNT_PATH}"
mount --bind "${UMBREL_ROOT}/scripts/umbrel-os/status-server/" "${BIND_MOUNT_PATH}"
sync
sleep 1

# Clear status file
echo "clearing status file..."
echo "" > "${STATUS_FILE_PATH}"

# Append iptables rule to forward port 80 to port 8000
# The status server runs on port 8000 but this rule will route all port 80
# HTTP traffic to it.
# When the Umbrel service has started Docker will overwrite this rule and
# instead forward port 80 to the Umbrel HTTP server container.
echo "Setting iptables rules..."
"${BIND_MOUNT_PATH}/setup-iptables"
33 changes: 33 additions & 0 deletions scripts/umbrel-os/status-server/setup-iptables
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash

set -euo pipefail

UMBREL_ROOT="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../../..)"

check_root () {
if [[ $UID != 0 ]]; then
echo "This script must be run as root"
exit 1
fi
}

main () {
check_root

# Remove and then re-append iptables rule
rule=(PREROUTING \
--table nat \
--proto tcp \
--dport 80 \
--jump REDIRECT \
--to-port 8000)
if iptables --delete ${rule[@]} 2> /dev/null; then
echo "Removed existing iptables entry."
else
echo "No existing iptables entry found."
fi
iptables --append ${rule[@]}
echo "Appended new iptables entry."
}

main
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 2fb71be

Please sign in to comment.