diff --git a/bin/upgrade_containers.sh b/bin/upgrade_containers.sh index 94103502d..73db74bf4 100755 --- a/bin/upgrade_containers.sh +++ b/bin/upgrade_containers.sh @@ -8,9 +8,15 @@ export MY_IP=$(ip -4 route get 8.8.8.8 | awk {'print $7'} | tr -d '\n') TOTAL_MEMORY_KB=$(grep MemTotal /proc/meminfo | awk {'print $2'}) export VIEWER_MEMORY_LIMIT_KB=$(echo "$TOTAL_MEMORY_KB" \* 0.8 | bc) export SHM_SIZE_KB="$(echo "$TOTAL_MEMORY_KB" \* 0.3 | bc | cut -d'.' -f1)" - export GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) +MODE="${MODE:-pull}" +if [[ ! "$MODE" =~ ^(pull|build)$ ]]; then + echo "Invalid mode: $MODE" + echo "Usage: MODE=(pull|build) $0" + exit 1 +fi + if [ -z "$DOCKER_TAG" ]; then export DOCKER_TAG="latest" fi @@ -52,7 +58,7 @@ fi sudo -E docker compose \ -f /home/${USER}/screenly/docker-compose.yml \ - pull + ${MODE} if [ -f /var/run/reboot-required ]; then exit 0 diff --git a/docs/developer-documentation.md b/docs/developer-documentation.md index 8c312450a..d129e50c2 100644 --- a/docs/developer-documentation.md +++ b/docs/developer-documentation.md @@ -58,73 +58,16 @@ To stop the development server, run the following: docker compose -f docker-compose.dev.yml down ``` -## Building containers locally +## Building containers on the Raspberry Pi -### Dependencies - -#### `buildx` - -> [!IMPORTANT] -> Make sure that you have `buildx` installed and that you have run -> `docker buildx create --use` before you run the image build script. - -#### Poetry - -We have switched from using Bash to [Poetry](https://python-poetry.org/) for building the Docker images. -Make sure that you have Python 3.11 and Poetry installed on your machine. - -> [!TIP] -> You can install Poetry by running the following script: -> ```bash -> ./bin/install_poetry.sh -> ``` -> -> After running the script, you can add the following to your `~/.bashrc` or similar file: -> -> ```bash -> # Add `pyenv` to the load path. -> export PYENV_ROOT="$HOME/.pyenv" -> [[ -d $PYENV_ROOT/bin ]] && \ -> export PATH="$PYENV_ROOT/bin:$PATH" -> eval "$(pyenv init -)" -> -> # Add `poetry to the load path. -> export PATH="$HOME/.local/bin:$PATH" -> -> poetry install --only=docker-image-builder -> ``` -> -> You can either restart your terminal or run `source ~/.bashrc` to start using Poetry. - -### Building only specific services - -Say that you would only like to build the `anthias-server` and `anthias-viewer` -services. Just run the following: - -```bash -$ poetry run python tools/image_builder \ - --service anthias-server \ - --service anthias-viewer -``` - -### Generating only Dockerfiles - -If you'd like to just generate the Dockerfiles from the templates provided -inside the `docker/` directory, run the following: - -```bash -$ poetry run python tools/image_builder \ - --dockerfiles-only -``` - -### Disabling cache mounts - -If you'd like to disable cache mounts in the generated Dockerfiles, run the -following: +> [!NOTE] +> Make sure that you have Docker installed on the device before proceeding. ```bash -$ poetry run python tools/image_builder \ - --disable-cache-mounts +$ ENVIRONMENT=production \ + ./bin/generate_dev_mode_dockerfiles.sh +$ MODE=build \ + ./bin/upgrade_containers.sh ``` ## Testing diff --git a/host_agent.py b/host_agent.py index 5278d09b5..b1d4fde72 100755 --- a/host_agent.py +++ b/host_agent.py @@ -12,6 +12,13 @@ import os import redis import subprocess +import requests +from tenacity import ( + Retrying, + RetryError, + stop_after_attempt, + wait_fixed, +) REDIS_ARGS = dict(host="127.0.0.1", port=6379, db=0) @@ -40,8 +47,26 @@ def get_ip_addresses(): def set_ip_addresses(): rdb = redis.Redis(**REDIS_ARGS) - ip_addresses = get_ip_addresses() + rdb.set('ip_addresses_ready', 'false') + + try: + for attempt in Retrying( + stop=stop_after_attempt(10), + wait=wait_fixed(1), + ): + with attempt: + response = requests.get('https://1.1.1.1') + response.raise_for_status() + except RetryError: + logging.warning( + 'Unable to connect to the Internet. ' + 'Proceeding with the current IP addresses available.' + ) + + rdb.set('ip_addresses_ready', 'true') + + ip_addresses = get_ip_addresses() rdb.set('ip_addresses', json.dumps(ip_addresses)) diff --git a/lib/utils.py b/lib/utils.py index e0e0f8a2a..229ca0af4 100644 --- a/lib/utils.py +++ b/lib/utils.py @@ -21,6 +21,12 @@ from platform import machine from settings import settings, ZmqPublisher from subprocess import check_output, call +from tenacity import ( + Retrying, + RetryError, + stop_after_attempt, + wait_fixed, +) from threading import Thread from time import sleep from urllib.parse import urlparse @@ -148,6 +154,28 @@ def get_node_ip(): sleep(1) r.publish('hostcmd', 'set_ip_addresses') + + try: + for attempt in Retrying( + stop=stop_after_attempt(20), + wait=wait_fixed(1), + ): + environment = getenv('ENVIRONMENT', None) + if environment in ['development', 'test']: + break + + with attempt: + ip_addresses_ready = r.get('ip_addresses_ready') or 'false' + if json.loads(ip_addresses_ready): + break + else: + raise Exception( + 'Internet connection is not available.') + except RetryError: + logging.warning( + 'Internet connection is not available. ' + ) + ip_addresses = r.get('ip_addresses') if ip_addresses: diff --git a/requirements/requirements.host.txt b/requirements/requirements.host.txt index f4599f590..40a77c162 100644 --- a/requirements/requirements.host.txt +++ b/requirements/requirements.host.txt @@ -4,3 +4,5 @@ ansible-core==2.15.9 docker==6.0.0 netifaces2==0.0.22 redis==4.3.4 +requests[security]==2.32.3 +tenacity==9.0.0