Skip to content
Snippets Groups Projects
Makefile 5.3 KiB
Newer Older
# Set dir of Makefile to a variable to use later
MAKEPATH := $(abspath $(lastword $(MAKEFILE_LIST)))
BASEDIR := $(notdir $(patsubst %/,%,$(dir $(MAKEPATH))))

COMPOSE_FILES := $(wildcard *.yml)
COMPOSE_FILE_ARGS := $(foreach yml,$(COMPOSE_FILES),-f $(yml))

ATTACH_COMPOSE_FILE_ARGS := $(foreach yml,$(filter-out tango.yml,$(COMPOSE_FILES)),-f $(yml))

# If the first make argument is "start" or "stop"...
ifeq (start,$(firstword $(MAKECMDGOALS)))
  SERVICE_TARGET = true
else ifeq (stop,$(firstword $(MAKECMDGOALS)))
  SERVICE_TARGET = true
else ifeq (attach,$(firstword $(MAKECMDGOALS)))
  SERVICE_TARGET = true
ifndef NETWORK_MODE
$(error NETWORK_MODE must specify the network to attach to, e.g., make NETWORK_MODE=tangonet-powersupply ...)
endif
ifndef TANGO_HOST
Thomas Juerges's avatar
Thomas Juerges committed
$(error TANGO_HOST must specify the Tango database device, e.g., make TANGO_HOST=powersupply-databaseds:10000 ...)
endif
endif
ifdef SERVICE_TARGET
  # .. then use the rest as arguments for the make target
  SERVICE := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
  # ...and turn them into do-nothing targets
  $(eval $(SERVICE):;@:)
endif

#
# Never use the network=host mode when running CI jobs, and add extra
# distinguishing identifiers to the network name and container names to
# prevent collisions with jobs from the same project running at the same
# time.
#
ifneq ($(CI_JOB_ID),)
NETWORK_MODE := tangonet-$(CI_JOB_ID)
CONTAINER_NAME_PREFIX := $(CI_JOB_ID)-
else
CONTAINER_NAME_PREFIX :=
$(info Network mode cannot be host for the archiver! It won't work unless you set the env var CI_JOB_ID=local)
endif

ifeq ($(OS),Windows_NT)
    $(error Sorry, Windows is not supported yet)
else
	UNAME_S := $(shell uname -s)
	ifeq ($(UNAME_S),Linux)
		DISPLAY ?= :0.0
		NETWORK_MODE ?= host
		XAUTHORITY_MOUNT := /tmp/.X11-unix:/tmp/.X11-unix
		XAUTHORITY ?= /hosthome/.Xauthority
		# /bin/sh (=dash) does not evaluate 'docker network' conditionals correctly
		SHELL := /bin/bash
	endif
	ifeq ($(UNAME_S),Darwin)
		IF_INTERFACE := $(shell scutil --nwi | grep 'Network interfaces:' | cut -d' ' -f3)
		IP_ADDRESS := $(shell scutil --nwi | grep 'address' | cut -d':' -f2 | tr -d ' ' | head -n1)
		DISPLAY := $(IP_ADDRESS):0
		# Make sure that Darwin, especially from macOS Catalina on,
		# allows X access from our Docker containers.
		ADD_TO_XHOST := $(shell xhost +$(IP_ADDRESS))
		# network_mode = host doesn't work on MacOS, so fix to the internal network
		NETWORK_MODE ?= tangonet
		XAUTHORITY_MOUNT := $(HOME)/.Xauthority:/hosthome/.Xauthority:ro
		XAUTHORITY := /hosthome/.Xauthority
	endif
endif

#
# When running in network=host mode, point devices at a port on the host
# machine rather than at the container.
#
ifeq ($(NETWORK_MODE),host)
	TANGO_HOST := $(shell hostname):10000
	MYSQL_HOST := $(shell hostname):3306
else
	TANGO_HOST := $(CONTAINER_NAME_PREFIX)databaseds:10000
	MYSQL_HOST := $(CONTAINER_NAME_PREFIX)tangodb:3306
endif

DOCKER_COMPOSE_ARGS := DISPLAY=$(DISPLAY) XAUTHORITY=$(XAUTHORITY) TANGO_HOST=$(TANGO_HOST) \
		NETWORK_MODE=$(NETWORK_MODE) XAUTHORITY_MOUNT=$(XAUTHORITY_MOUNT) TANGO_SKA_CONTAINER_MOUNT=$(TANGO_SKA_CONTAINER_MOUNT) TANGO_LOFAR_CONTAINER_MOUNT=$(TANGO_LOFAR_CONTAINER_MOUNT) TANGO_LOFAR_CONTAINER_DIR=${TANGO_LOFAR_CONTAINER_DIR} MYSQL_HOST=$(MYSQL_HOST) \
		CONTAINER_NAME_PREFIX=$(CONTAINER_NAME_PREFIX) COMPOSE_IGNORE_ORPHANS=true CONTAINER_EXECUTION_UID=$(shell id -u)


.PHONY: up down minimal start stop status clean pull help
.DEFAULT_GOAL := help

pull: ## pull the images from the Docker hub
	$(DOCKER_COMPOSE_ARGS) docker-compose $(COMPOSE_FILE_ARGS) pull

build: ## rebuild images
	# docker-compose does not support build dependencies, so manage those here
	$(DOCKER_COMPOSE_ARGS) docker-compose -f lofar-device-base.yml build
	$(DOCKER_COMPOSE_ARGS) docker-compose $(COMPOSE_FILE_ARGS) build

up: minimal  ## start the base TANGO system and prepare all services
	$(DOCKER_COMPOSE_ARGS) docker-compose $(COMPOSE_FILE_ARGS) up --no-start

down:  ## stop all services and tear down the system
	$(DOCKER_COMPOSE_ARGS) docker-compose $(COMPOSE_FILE_ARGS) down
ifneq ($(NETWORK_MODE),host)
	docker network inspect $(NETWORK_MODE) &> /dev/null && ([ $$? -eq 0 ] && docker network rm $(NETWORK_MODE)) || true
endif

minimal: ## start the base TANGO system
ifneq ($(NETWORK_MODE),host)
	docker network inspect $(NETWORK_MODE) &> /dev/null || ([ $$? -ne 0 ] && docker network create $(NETWORK_MODE))
endif
	$(DOCKER_COMPOSE_ARGS) docker-compose -f tango.yml up -d

start: up ## start a service (usage: make start <servicename>)
	if [ $(UNAME_S) = Linux ]; then chmod a+r ~/.Xauthority; fi
	$(DOCKER_COMPOSE_ARGS) docker-compose $(COMPOSE_FILE_ARGS) start $(SERVICE)

stop:  ## stop a service (usage: make stop <servicename>)
	$(DOCKER_COMPOSE_ARGS) docker-compose $(COMPOSE_FILE_ARGS) stop $(SERVICE)

attach:  ## attach a service to an existing Tango network
	$(DOCKER_COMPOSE_ARGS) docker-compose $(ATTACH_COMPOSE_FILE_ARGS) up -d $(SERVICE)

status:  ## show the container status
	$(DOCKER_COMPOSE_ARGS) docker-compose $(COMPOSE_FILE_ARGS) ps

images:  ## show the container images
	$(DOCKER_COMPOSE_ARGS) docker-compose $(COMPOSE_FILE_ARGS) images

clean: down  ## clear all TANGO database entries
	docker volume rm $(BASEDIR)_tangodb

help:   ## show this help.
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'