Ctrl K
ComunidadGuías…

Makefile

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
SHELL := /bin/bash

# Read the last active assignment using the dotenv forms supported by
# compose.sh. Every topology decision below comes from `.env`, so caller or
# command-line variables cannot select different files than the containers use.
define read_env_value
$(strip $(shell awk -v target='$(1)' '$$0 ~ ("^[[:space:]]*(export[[:space:]]+)?" target "[[:space:]]*=") { value=$$0; sub("^[[:space:]]*(export[[:space:]]+)?" target "[[:space:]]*=[[:space:]]*", "", value); sub(/[[:space:]]+\#.*$$/, "", value); gsub(/^[[:space:]"'\'']+|[[:space:]"'\'']+$$/, "", value); result=tolower(value) } END { print result }' .env 2>/dev/null))
endef

override CONFIG_MODE := $(call read_env_value,MODE)
override CONFIG_BUNDLED_DB := $(or $(call read_env_value,OMLORIX_USE_BUNDLED_DB),true)
override CONFIG_BUNDLED_REDIS := $(or $(call read_env_value,OMLORIX_USE_BUNDLED_REDIS),true)
override CONFIG_REDIS_ENABLED := $(or $(call read_env_value,REDIS_ENABLED),true)
override CONFIG_PGBOUNCER := $(or $(call read_env_value,OMLORIX_USE_PGBOUNCER),false)
override CONFIG_BUNDLED_STORAGE := $(or $(call read_env_value,OMLORIX_USE_BUNDLED_STORAGE),false)
override CONFIG_OTEL_ENABLED := $(or $(call read_env_value,OTEL_ENABLED),false)

TRUE_VALUES := true 1 yes on
override CONFIG_BUNDLED_DB_ACTIVE := $(if $(filter $(TRUE_VALUES),$(CONFIG_BUNDLED_DB)),true,false)
override CONFIG_BUNDLED_REDIS_ACTIVE := $(if $(filter $(TRUE_VALUES),$(CONFIG_BUNDLED_REDIS)),true,false)
override CONFIG_REDIS_ACTIVE := $(if $(filter $(TRUE_VALUES),$(CONFIG_REDIS_ENABLED)),true,false)
override CONFIG_PGBOUNCER_ACTIVE := $(if $(filter $(TRUE_VALUES),$(CONFIG_PGBOUNCER)),true,false)
override CONFIG_BUNDLED_STORAGE_ACTIVE := $(if $(filter $(TRUE_VALUES),$(CONFIG_BUNDLED_STORAGE)),true,false)
override CONFIG_OTEL_ACTIVE := $(if $(filter $(TRUE_VALUES),$(CONFIG_OTEL_ENABLED)),true,false)
override HOST_OS := $(shell uname -s 2>/dev/null)

ifeq ($(CONFIG_OTEL_ACTIVE),true)
COMPOSE_OBSERVABILITY := -f docker-compose.observability.yml
ifeq ($(HOST_OS),Linux)
COMPOSE_OBSERVABILITY += -f docker-compose.observability-linux.yml
endif
else
COMPOSE_OBSERVABILITY :=
endif

# Base Compose command
COMPOSE_BASE := ./script/compose.sh

# Source checkout stack: production topology with locally built application images.
COMPOSE_DEV_PORTS := -f docker-compose.dev-ports.yml
COMPOSE_SOURCE_FILES := -f docker-compose.server.yml -f docker-compose.source-build.yml -f docker-compose.frontend-port.yml $(COMPOSE_OBSERVABILITY)

# Managed cloud stack (external DB/Redis)
COMPOSE_MANAGED_CLOUD_FILES := -f docker-compose.managed-cloud.yml $(COMPOSE_OBSERVABILITY)

BUILD ?= true
ifneq ($(filter true 1 yes on,$(BUILD)),)
COMPOSE_BUILD_FLAG := --build
else
COMPOSE_BUILD_FLAG :=
endif
DEFAULT_GOAL := help
FILES_MIGRATE_ARGS ?=
BACKUP_CREATE_ARGS ?=
BACKUP_VERIFY_ARGS ?=
BACKUP_TARGET ?= empty

# Select one Compose topology for the entire invocation. Keeping this decision
# at parse time prevents `up`, `down`, logs, migrations, and backup operations
# from accidentally targeting different stacks.
CURRENT_COMPOSE_FILES := $(COMPOSE_SOURCE_FILES)

# Match the Launcher and standalone CLI: use managed cloud only when every
# stateful dependency is external (or Redis is disabled) and no bundled proxy
# or storage service requires the server topology.
CONFIG_MANAGED_CLOUD := false
ifeq ($(CONFIG_BUNDLED_DB_ACTIVE),false)
ifeq ($(CONFIG_REDIS_ACTIVE),false)
CONFIG_MANAGED_CLOUD := true
else ifeq ($(CONFIG_BUNDLED_REDIS_ACTIVE),false)
CONFIG_MANAGED_CLOUD := true
endif
endif
ifneq ($(filter true,$(CONFIG_PGBOUNCER_ACTIVE) $(CONFIG_BUNDLED_STORAGE_ACTIVE)),)
CONFIG_MANAGED_CLOUD := false
endif

ifeq ($(CONFIG_MANAGED_CLOUD),true)
CURRENT_COMPOSE_FILES := $(COMPOSE_MANAGED_CLOUD_FILES)
endif

# Development host-port overrides are valid for local stacks, but managed cloud
# intentionally has no bundled Postgres or Redis services to expose.
ifneq ($(filter dev,$(CONFIG_MODE)),)
ifeq ($(CONFIG_MANAGED_CLOUD),true)
else
CURRENT_COMPOSE_FILES := $(CURRENT_COMPOSE_FILES) $(COMPOSE_DEV_PORTS)
endif
endif

CURRENT_COMPOSE := $(COMPOSE_BASE) $(CURRENT_COMPOSE_FILES)

.PHONY: help setup up down restart logs ps update migrate source-probe files-migrate files-migrate-local backup-create backup-verify backup-restore

help:
	@echo "Available targets:"
	@echo "  setup         Run setup.sh to prepare config files"
	@echo "  up            Start the app stack (use env vars for configuration)"
	@echo "  down          Stop containers but keep data volumes"
	@echo "  restart       Restart all services"
	@echo "  logs          Follow logs for all services"
	@echo "  ps            Show container status"
	@echo "  migrate       Take the stack offline, then run one-shot DB migrations (main + audit)"
	@echo "  source-probe   Run storage provider connectivity probe"
	@echo "  files-migrate Migrate files and generated artifacts between storage providers"
	@echo "  files-migrate-local Migrate local files/artifacts to the configured provider"
	@echo "  backup-create  Create a full instance backup"
	@echo "  backup-verify Verify a backup"
	@echo "  backup-restore Verify and restore a full instance backup"
	@echo "  update         Pull latest changes from git"
	@echo ""
	@echo "Stack configuration (edit .env):"
	@echo "  MODE=dev|production              Select the application mode"
	@echo "  OMLORIX_USE_PGBOUNCER=true        Route database traffic through PgBouncer"
	@echo "  OMLORIX_USE_BUNDLED_STORAGE=true  Use the bundled MinIO storage service"
	@echo "  REDIS_ENABLED=false              Keep automation workers disabled"
	@echo "  OTEL_ENABLED=true                Include the observability stack"
	@echo "  Fully external DB/Redis/storage  Selects managed cloud automatically"
	@echo ""
	@echo "Make invocation option:"
	@echo "  BUILD=false  Skip image rebuilds"
	@echo ""
	@echo "Restore examples:"
	@echo "  make backup-restore BACKUP_SOURCE=<container-visible-uri>"
	@echo "  make backup-restore BACKUP_JOB_ID=<id>"
	@echo "  make backup-restore BACKUP_SOURCE=<uri> BACKUP_TARGET=in_place BACKUP_CONFIRM=RESTORE-IN-PLACE"

setup:
ifeq ($(filter setup,$(MAKECMDGOALS)),setup)
	@./setup.sh
else
	@./setup.sh > /dev/null
endif

up: setup
	@# compose.sh derives every service profile and host override from .env.
	@# Remove every current and orphaned database writer before a potentially new
	@# migration image runs. Data volumes remain intact.
	@$(CURRENT_COMPOSE) down --remove-orphans
	@$(CURRENT_COMPOSE) rm -sf migrate
	@$(CURRENT_COMPOSE) up -d $(COMPOSE_BUILD_FLAG) --force-recreate migrate
	@$(CURRENT_COMPOSE) up -d $(COMPOSE_BUILD_FLAG) || { \
		status=$$?; \
		echo ""; \
		echo "up failed. Showing recent migrate logs:"; \
		$(CURRENT_COMPOSE) logs --no-color --tail=120 migrate || true; \
		echo ""; \
		echo "Tip: run 'make ps' and '$(CURRENT_COMPOSE) logs -f migrate' for more details."; \
		exit $$status; \
	}

down:
	$(CURRENT_COMPOSE) down --remove-orphans

restart: down up

logs:
	$(CURRENT_COMPOSE) logs -f

ps:
	$(CURRENT_COMPOSE) ps

update:
	git pull --rebase --autostash

migrate:
	@# The database gates intentionally reject pre-fence application writers.
	@# Leave application services stopped after this operator-only migration;
	@# `make up` performs the same drain and then starts the complete stack.
	$(CURRENT_COMPOSE) down --remove-orphans
	$(CURRENT_COMPOSE) run --rm $(COMPOSE_BUILD_FLAG) migrate

source-probe:
	$(CURRENT_COMPOSE) run --rm fastapi python -m app.files.cli storage-probe

files-migrate:
	$(CURRENT_COMPOSE) run --rm fastapi python -m app.files.cli migrate-files $(FILES_MIGRATE_ARGS)

files-migrate-local:
	$(CURRENT_COMPOSE) run --rm fastapi python -m app.files.cli migrate-local-files $(FILES_MIGRATE_ARGS)

backup-create:
	$(CURRENT_COMPOSE) run --rm fastapi python -m app.backups.cli create $(if $(BACKUP_DESTINATION),--destination "$(BACKUP_DESTINATION)",) $(BACKUP_CREATE_ARGS)

backup-verify:
	@if [ -z "$(BACKUP_JOB_ID)" ] && [ -z "$(BACKUP_SOURCE)" ]; then \
		echo "Usage: make backup-verify BACKUP_JOB_ID=<id> | BACKUP_SOURCE=<uri>"; \
		exit 1; \
	fi
	$(CURRENT_COMPOSE) run --rm fastapi python -m app.backups.cli verify $(if $(BACKUP_JOB_ID),--job-id "$(BACKUP_JOB_ID)",) $(if $(BACKUP_SOURCE),--source "$(BACKUP_SOURCE)",) $(BACKUP_VERIFY_ARGS)

backup-restore:
	@./script/coordinated-backup-restore.sh $(CURRENT_COMPOSE_FILES) -- \
		$(if $(BACKUP_SOURCE),--source "$(BACKUP_SOURCE)",) \
		$(if $(BACKUP_JOB_ID),--job-id "$(BACKUP_JOB_ID)",) \
		--target "$(BACKUP_TARGET)" \
		$(if $(BACKUP_CONFIRM),--confirm "$(BACKUP_CONFIRM)",)