diff --git a/Makefile b/Makefile index 9d8e771e17..39a01c68d0 100644 --- a/Makefile +++ b/Makefile @@ -2,89 +2,39 @@ SHELL := /bin/bash .SHELLFLAGS := -euo pipefail -c -VENV_BASE ?= $(if $(VIRTUAL_ENV),$(dir $(VIRTUAL_ENV)),/opt/venvs) -VENV_NAME ?= infinito -VENV_FALLBACK := $(VENV_BASE)/$(VENV_NAME) -VENV := $(if $(VIRTUAL_ENV),$(VIRTUAL_ENV),$(VENV_FALLBACK)) +# ------------------------------------------------------------ +# SPOT: Global environment is defined in scripts/meta/env.sh +# ------------------------------------------------------------ +ENV_SH ?= $(CURDIR)/scripts/meta/env.sh +export ENV_SH -PYTHON := $(VENV)/bin/python -PIP := $(PYTHON) -m pip -export PYTHON -export PIP - -# Ensure repo root is importable (so module_utils/, filter_plugins/ etc. work) -PYTHONPATH ?= . -export PYTHONPATH - -ifdef NIX_CONFIG -export NIX_CONFIG -endif - -# Ensure TEST_DEPLOY_TYPE is available for the default inventory dir. -TEST_DEPLOY_TYPE ?= server -export TEST_DEPLOY_TYPE - -# --- Test filtering (unittest discover) --- -TEST_PATTERN ?= test*.py -export TEST_PATTERN - -# Distro -INFINITO_DISTRO ?= arch -INFINITO_CONTAINER ?= infinito_nexus_$(INFINITO_DISTRO) -export INFINITO_DISTRO -export INFINITO_CONTAINER - -# Detirmene Environment -RUNNING_ON_ACT ?= false -RUNNING_ON_GITHUB ?= false - -ifeq ($(GITHUB_ACTIONS),true) - RUNNING_ON_GITHUB = true - ifeq ($(ACT),true) - RUNNING_ON_ACT = true - RUNNING_ON_GITHUB = false - endif -endif -export RUNNING_ON_ACT RUNNING_ON_GITHUB - -INVENTORY_DIR ?= $(shell \ - RUNNING_ON_ACT="$(RUNNING_ON_ACT)" \ - RUNNING_ON_GITHUB="$(RUNNING_ON_GITHUB)" \ - HOME="$(HOME)" \ - bash scripts/inventory/resolve.sh \ -) -export INVENTORY_DIR - -# Overwrite defaults -ifeq ($(RUNNING_ON_GITHUB),true) - # -------- Real GitHub Actions CI -------- - INFINITO_PULL_POLICY ?= always - INFINITO_IMAGE_TAG ?= latest - INFINITO_IMAGE ?= ghcr.io/$(GITHUB_REPOSITORY_OWNER)/infinito-$(INFINITO_DISTRO):$(INFINITO_IMAGE_TAG) - INFINITO_NO_BUILD ?= 1 - INFINITO_DOCKER_VOLUME ?= /mnt/docker - INFINITO_DOCKER_MOUNT ?= /var/lib/docker - export INFINITO_DOCKER_VOLUME INFINITO_DOCKER_MOUNT - export INFINITO_IMAGE_TAG - export INFINITO_NO_BUILD - export INFINITO_PULL_POLICY - export INFINITO_IMAGE - INFINITO_COMPILE ?= 0 +# For non-interactive bash, BASH_ENV is sourced before executing the command. +# This makes env.sh apply automatically to *all* Make recipes. +ifneq ("$(wildcard $(ENV_SH))","") +export BASH_ENV := $(ENV_SH) else - INFINITO_COMPILE ?= 1 +$(error Missing env file: $(ENV_SH)) endif -export INFINITO_COMPILE .PHONY: \ setup setup-clean install install-ansible install-venv install-python \ - test test-lint test-unit test-integration test-deploy test-deploy-app\ - clean down \ + test test-lint test-unit test-integration test-deploy test-deploy-app \ + clean clean-sudo down \ list tree mig dockerignore \ print-python lint-ansible \ - dns-setup dns-remove + dns-setup dns-remove \ + dev-environment-bootstrap dev-environment-teardown \ + apparmor-teardown apparmor-restore \ + trust-ca \ + docker-restart docker-up docker-down docker-stop \ + build build-missing build-no-cache build-no-cache-all \ + ci-deploy-discover ci-deploy-app ci-discover-output \ + test-act-all test-act-app \ + test-local-reset test-local-run-all test-local-cleanup test-local-web-purge \ + test-local-rapid test-local-rapid-fresh test-local-full \ + format bootstrap setup-development dev-environment-bootstrap: apparmor-teardown dns-setup - dev-environment-teardown: apparmor-restore dns-remove dns-setup: @@ -93,8 +43,6 @@ dns-setup: dns-remove: @bash scripts/dns/remove.sh -.PHONY: apparmor-teardown apparmor-restore - apparmor-teardown: @echo "==> AppArmor: full teardown (local dev)" @sudo bash scripts/administration/apparmor/teardown.sh @@ -103,13 +51,9 @@ apparmor-restore: @echo "==> AppArmor: restore profiles" @sudo bash scripts/administration/apparmor/restore.sh - -.PHONY: trust-ca - trust-ca: @bash scripts/administration/trust_ca.sh - clean: @echo "Removing ignored git files" @if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then \ @@ -121,7 +65,7 @@ clean: clean-sudo: @echo "Removing ignored git files with sudo" - sudo git clean -fdX; \ + sudo git clean -fdX; docker-restart: @$(PYTHON) -m cli.deploy.development restart --distro "$(INFINITO_DISTRO)" @@ -137,11 +81,11 @@ docker-stop: list: @echo "Generating the roles list" - $(PYTHON) -m cli.build.roles_list + @$(PYTHON) -m cli.build.roles_list tree: @echo "Generating Tree" - $(PYTHON) -m cli.build.tree -D 2 + @$(PYTHON) -m cli.build.tree -D 2 mig: list tree @echo "Creating meta data for meta infinity graph" @@ -204,7 +148,6 @@ format: ruff check . --fix # --- Tests (separated) --- - test: test-lint test-unit test-integration lint-ansible test-deploy @echo "✅ Full test (setup + tests) executed." @@ -245,57 +188,35 @@ ci-discover-output: echo "apps_json=$$apps" test-act-all: - @TEST_DEPLOY_TYPE="$(TEST_DEPLOY_TYPE)" \ - INFINITO_DISTRO="$(INFINITO_DISTRO)" \ - bash scripts/tests/deploy/act/all.sh + @bash scripts/tests/deploy/act/all.sh test-act-app: - @APP="$(APP)" \ - TEST_DEPLOY_TYPE="$(TEST_DEPLOY_TYPE)" \ - INFINITO_DISTRO="$(INFINITO_DISTRO)" \ - bash scripts/tests/deploy/act/app.sh + @bash scripts/tests/deploy/act/app.sh test-local-reset: - @TEST_DEPLOY_TYPE="$(TEST_DEPLOY_TYPE)" \ - INFINITO_DISTRO="$(INFINITO_DISTRO)" \ - PYTHON=python3 \ + @PYTHON=python3 \ bash scripts/tests/deploy/local/reset.sh test-local-run-all: - @TEST_DEPLOY_TYPE="$(TEST_DEPLOY_TYPE)" \ - INFINITO_DISTRO="$(INFINITO_DISTRO)" \ - DEBUG="$(DEBUG)" \ - LIMIT_HOST="$(LIMIT_HOST)" \ - INVENTORY_DIR="$(INVENTORY_DIR)" \ - bash scripts/tests/deploy/local/run-all.sh + @bash scripts/tests/deploy/local/run-all.sh test-local-cleanup: - @APP="$(APP)" \ - INFINITO_CONTAINER="$(INFINITO_CONTAINER)" \ - bash scripts/tests/deploy/local/cleanup.sh + @bash scripts/tests/deploy/local/cleanup.sh test-local-web-purge: - INFINITO_CONTAINER="$(INFINITO_CONTAINER)" \ - bash scripts/tests/deploy/local/purge_web.sh + @bash scripts/tests/deploy/local/purge_web.sh test-local-rapid: - @APP="$(APP)" \ - TEST_DEPLOY_TYPE="$(TEST_DEPLOY_TYPE)" \ - INFINITO_CONTAINER="$(INFINITO_CONTAINER)" \ - DEBUG=true \ + @DEBUG=true \ bash scripts/tests/deploy/local/rapid.sh test-local-rapid-fresh: test-local-cleanup test-local-rapid test-local-full: @echo "=== local full deploy (type=$(TEST_DEPLOY_TYPE), distro=$(INFINITO_DISTRO)) ===" - @TEST_DEPLOY_TYPE="$(TEST_DEPLOY_TYPE)" \ - INFINITO_DISTRO="$(INFINITO_DISTRO)" \ - bash scripts/tests/deploy/local/all.sh + @bash scripts/tests/deploy/local/all.sh # Backwards compatible target (kept) lint-ansible: @echo "📑 Checking Ansible syntax…" ansible-playbook -i localhost, -c local $(foreach f,$(wildcard group_vars/all/*.yml),-e @$(f)) playbook.yml --syntax-check - - diff --git a/scripts/meta/env.sh b/scripts/meta/env.sh new file mode 100644 index 0000000000..f5174d37d7 --- /dev/null +++ b/scripts/meta/env.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +# +# scripts/meta/env.sh +# +# This file is meant to be sourced automatically (e.g. via BASH_ENV from Makefile) +# or manually: +# source scripts/meta/env.sh +# +# It defines and exports Infinito runtime env vars with sensible defaults. +# It is safe to run under: set -euo pipefail (including `-u`). + +set -euo pipefail + +# Prevent double-loading +if [[ "${INFINITO_ENV_LOADED:-}" == "1" ]]; then + return 0 +fi +export INFINITO_ENV_LOADED="1" + +# ------------------------------------------------------------ +# Helpers +# ------------------------------------------------------------ +_is_true() { [[ "${1:-}" == "1" || "${1:-}" == "true" ]]; } + +# ------------------------------------------------------------ +# Venv / Python (safe under "set -u") +# ------------------------------------------------------------ +_virtual_env="${VIRTUAL_ENV:-}" + +if [[ -n "${_virtual_env}" ]]; then + : "${VENV_BASE:=${VENV_BASE:-$(dirname "${_virtual_env}")/}}" +else + : "${VENV_BASE:=${VENV_BASE:-/opt/venvs}}" +fi + +: "${VENV_NAME:=infinito}" +: "${VENV_FALLBACK:=${VENV_BASE%/}/${VENV_NAME}}" +: "${VENV:=${_virtual_env:-$VENV_FALLBACK}}" + +_default_python="${VENV%/}/bin/python" +if [[ -x "${_default_python}" ]]; then + : "${PYTHON:=${_default_python}}" +else + : "${PYTHON:=python3}" +fi + +: "${PIP:=${PYTHON} -m pip}" + +export VENV_BASE VENV_NAME VENV_FALLBACK VENV +export PYTHON PIP + +# Ensure repo root is importable (so module_utils/, filter_plugins/ etc. work) +: "${PYTHONPATH:=.}" +export PYTHONPATH + +# ------------------------------------------------------------ +# CI detection +# ------------------------------------------------------------ +: "${RUNNING_ON_ACT:=false}" +: "${RUNNING_ON_GITHUB:=false}" + +if [[ "${GITHUB_ACTIONS:-}" == "true" ]]; then + RUNNING_ON_GITHUB="true" + if [[ "${ACT:-}" == "true" ]]; then + RUNNING_ON_ACT="true" + RUNNING_ON_GITHUB="false" + fi +fi + +export RUNNING_ON_ACT RUNNING_ON_GITHUB + +# ------------------------------------------------------------ +# Defaults +# ------------------------------------------------------------ +: "${TEST_DEPLOY_TYPE:=server}" +export TEST_DEPLOY_TYPE + +: "${TEST_PATTERN:=test*.py}" +export TEST_PATTERN + +: "${INFINITO_DISTRO:=arch}" +: "${INFINITO_CONTAINER:=infinito_nexus_${INFINITO_DISTRO}}" +export INFINITO_DISTRO INFINITO_CONTAINER + +# Common distro list (used by build-no-cache-all) +: "${DISTROS:=arch debian ubuntu fedora centos}" +export DISTROS + +# ------------------------------------------------------------ +# Inventory dir (needs resolve script) +# ------------------------------------------------------------ +if [[ -z "${INVENTORY_DIR:-}" ]]; then + INVENTORY_DIR="$( + RUNNING_ON_ACT="${RUNNING_ON_ACT}" \ + RUNNING_ON_GITHUB="${RUNNING_ON_GITHUB}" \ + HOME="${HOME:-}" \ + bash scripts/inventory/resolve.sh + )" +fi +export INVENTORY_DIR + +# ------------------------------------------------------------ +# GitHub CI overrides +# ------------------------------------------------------------ +if [[ "${RUNNING_ON_GITHUB}" == "true" ]]; then + : "${INFINITO_PULL_POLICY:=always}" + : "${INFINITO_IMAGE_TAG:=latest}" + + # Owner can come from GitHub Actions or be provided explicitly (fallback). + _owner="${GITHUB_REPOSITORY_OWNER:-${OWNER:-}}" + : "${INFINITO_IMAGE:=ghcr.io/${_owner}/infinito-${INFINITO_DISTRO}:${INFINITO_IMAGE_TAG}}" + + : "${INFINITO_NO_BUILD:=1}" + : "${INFINITO_DOCKER_VOLUME:=/mnt/docker}" + : "${INFINITO_DOCKER_MOUNT:=/var/lib/docker}" + : "${INFINITO_COMPILE:=0}" + + export INFINITO_PULL_POLICY INFINITO_IMAGE_TAG INFINITO_IMAGE INFINITO_NO_BUILD + export INFINITO_DOCKER_VOLUME INFINITO_DOCKER_MOUNT + export INFINITO_COMPILE +else + : "${INFINITO_COMPILE:=1}" + export INFINITO_COMPILE +fi + +# NIX_CONFIG is optional; export if set +if [[ -n "${NIX_CONFIG:-}" ]]; then + export NIX_CONFIG +fi