import files
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
##
|
||||
# APP
|
||||
|
||||
.PHONY: start-up
|
||||
start-up:
|
||||
@@ -0,0 +1,3 @@
|
||||
BUILD_APP_VARS ?= APP BRANCH COMMIT DEPLOY_SLACK_HOOK ENV VERSION
|
||||
COMPOSE_IGNORE_ORPHANS ?= false
|
||||
ENV_VARS += CONSUL_HTTP_TOKEN
|
||||
@@ -0,0 +1,46 @@
|
||||
##
|
||||
# BUILD
|
||||
|
||||
# target build: Build application docker images on local host
|
||||
.PHONY: build
|
||||
build: docker-compose-build ## Build application docker images
|
||||
|
||||
# target build@%: Build application docker images to deploy
|
||||
.PHONY: build@% app-build
|
||||
build@%: infra-base
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(eval docker_images += $(foreach service,$(SERVICES),$(if $(shell docker images -q $(DOCKER_REPOSITORY)/$(service):$(DOCKER_IMAGE_TAG) 2>/dev/null),$(service))))
|
||||
$(eval build_app := $(or $(filter $(DOCKER_BUILD_CACHE),false),$(filter-out $(docker_images),$(SERVICES))))
|
||||
$(if $(build_app),$(call make,app-build),$(if $(filter $(VERBOSE),true),$(foreach service,$(SERVICES),echo "docker image $(DOCKER_REPOSITORY)/$(service):$(DOCKER_IMAGE_TAG) has id $(shell docker images -q $(DOCKER_REPOSITORY)/$(service):$(DOCKER_IMAGE_TAG) 2>/dev/null)" &&) true))
|
||||
|
||||
# target build-env: Build .env file in docker $(SERVICE) to deploy
|
||||
.PHONY: build-env
|
||||
build-env: SERVICE ?= $(DOCKER_SERVICE)
|
||||
build-env: bootstrap
|
||||
$(call docker-compose-exec,$(SERVICE),rm -f .env && make .env ENV=$(ENV) && echo BUILD=true >> .env && echo BUILD_DATE='"\'"'$(shell date "+%d/%m/%Y %H:%M:%S %z" 2>/dev/null)'"\'"' >> .env && echo BUILD_STATUS='"\'"'$(shell git status -uno --porcelain 2>/dev/null)'"\'"' >> .env && echo DOCKER=false >> .env && $(foreach var,$(BUILD_APP_VARS),$(if $($(var)),sed -i '/^$(var)=/d' .env && echo $(var)='$($(var))' >> .env &&)) true)
|
||||
|
||||
# target build-rm: Empty build directory
|
||||
.PHONY: build-rm
|
||||
build-rm:
|
||||
$(call exec,rm -rf build && mkdir -p build)
|
||||
|
||||
# target build-$(SHARED): Create shared folder in docker $(SERVICE) to deploy
|
||||
.PHONY: build-$(SHARED)
|
||||
build-$(SHARED): SERVICE ?= $(DOCKER_SERVICE)
|
||||
build-$(SHARED): bootstrap
|
||||
$(call docker-compose-exec,$(SERVICE),mkdir -p /$(SHARED) && $(foreach folder,$(SHARED_FOLDERS),rm -rf $(folder) && mkdir -p $(dir $(folder)) && ln -s /$(SHARED)/$(notdir $(folder)) $(folder) &&) true)
|
||||
|
||||
# target rebuild: Rebuild application docker images on local host
|
||||
.PHONY: rebuild
|
||||
rebuild: docker-compose-rebuild ## Rebuild application dockers images
|
||||
|
||||
# target rebuild@%: Rebuild application docker images on local host
|
||||
.PHONY: rebuild@%
|
||||
rebuild@%: ## Rebuild application dockers images
|
||||
$(call make,build@$* DOCKER_BUILD_CACHE=false)
|
||||
|
||||
# target rebuild-images: Rebuild docker/* images
|
||||
.PHONY: rebuild-images
|
||||
rebuild-images: docker-rebuild-images ## Rebuild docker/* images
|
||||
@@ -0,0 +1,14 @@
|
||||
##
|
||||
# CLEAN
|
||||
|
||||
.PHONY: clean app-clean
|
||||
clean: app-clean docker-compose-down clean-env ## Clean application and docker images
|
||||
|
||||
# target clean@%: Clean deployed application and docker images
|
||||
.PHONY: clean@%
|
||||
clean@%:
|
||||
$(call make,docker-compose-down DOCKER_COMPOSE_DOWN_OPTIONS='--rmi all -v')
|
||||
|
||||
.PHONY: clean-env
|
||||
clean-env:
|
||||
rm -i .env || true
|
||||
@@ -0,0 +1,124 @@
|
||||
##
|
||||
# COMMON
|
||||
|
||||
.PHONY: bootstrap
|
||||
bootstrap: bootstrap-git bootstrap-docker ## Bootstrap application
|
||||
|
||||
.PHONY: boostrap-docker
|
||||
bootstrap-docker: docker-network-create
|
||||
$(if $(filter bootstrap-$(APP),$(MAKETARGETS)),$(call make,bootstrap-$(APP)))
|
||||
$(call make,docker-compose-up)
|
||||
|
||||
.PHONY: bootstrap-git
|
||||
bootstrap-git:
|
||||
ifneq ($(SUBREPO),)
|
||||
if ! git config remote.subrepo/$(SUBREPO).url > /dev/null ; \
|
||||
then git remote add subrepo/$(SUBREPO) $(GIT_REPOSITORY); \
|
||||
fi
|
||||
endif
|
||||
|
||||
.PHONY: config
|
||||
config: docker-compose-config ## View docker compose file
|
||||
|
||||
.PHONY: connect
|
||||
connect: docker-compose-connect ## Connect to docker $(SERVICE)
|
||||
|
||||
.PHONY: connect@%
|
||||
connect@%: SERVICE ?= $(DOCKER_SERVICE)
|
||||
connect@%: ## Connect to docker $(SERVICE) on first remote host
|
||||
$(call make,ssh-connect,../infra,APP SERVICE)
|
||||
|
||||
.PHONY: down
|
||||
down: docker-compose-down ## Remove application dockers
|
||||
|
||||
.PHONY: exec
|
||||
exec: ## Exec a command in docker $(SERVICE)
|
||||
ifneq (,$(filter $(ENV),$(ENV_DEPLOY)))
|
||||
$(call exec,$(ARGS))
|
||||
else
|
||||
$(call make,docker-compose-exec,,ARGS)
|
||||
endif
|
||||
|
||||
.PHONY: exec@%
|
||||
exec@%: SERVICE ?= $(DOCKER_SERVICE)
|
||||
exec@%: ## Exec a command in docker $(SERVICE) on all remote hosts
|
||||
$(call make,ssh-exec,../infra,APP ARGS SERVICE)
|
||||
|
||||
.PHONY: logs
|
||||
logs: docker-compose-logs ## Display application dockers logs
|
||||
|
||||
.PHONY: ps
|
||||
ps: docker-compose-ps ## List application dockers
|
||||
|
||||
.PHONY: recreate
|
||||
recreate: docker-compose-recreate start-up ## Recreate application dockers
|
||||
|
||||
.PHONY: reinstall
|
||||
reinstall: clean ## Reinstall application
|
||||
$(call make,.env)
|
||||
$(call make,install)
|
||||
|
||||
.PHONY: restart
|
||||
restart: docker-compose-restart start-up ## Restart application
|
||||
|
||||
.PHONY: run
|
||||
run: ## Run a command in a new docker
|
||||
ifneq (,$(filter $(ENV),$(ENV_DEPLOY)))
|
||||
$(call run,$(ARGS))
|
||||
else
|
||||
$(call make,docker-compose-run,,ARGS)
|
||||
endif
|
||||
|
||||
.PHONY: run@%
|
||||
run@%: SERVICE ?= $(DOCKER_SERVICE)
|
||||
run@%: ## Run a command on all remote hosts
|
||||
$(call make,ssh-run,../infra,APP ARGS)
|
||||
|
||||
.PHONY: scale
|
||||
scale: docker-compose-scale ## Scale application to NUM dockers
|
||||
|
||||
.PHONY: ssh@%
|
||||
ssh@%: ## Connect to first remote host
|
||||
$(call make,ssh,../infra,APP)
|
||||
|
||||
# target stack: Call docker-stack function with each value of $(STACK)
|
||||
.PHONY: stack
|
||||
stack:
|
||||
$(foreach stackz,$(STACK),$(call docker-stack,$(stackz)))
|
||||
|
||||
# target stack-%: Call docker-compose-* command on a given stack
|
||||
## ex: calling stack-base-up will fire the docker-compose-up target on the base stack
|
||||
## it splits $* on dashes and extracts stack from the beginning of $* and command
|
||||
## from the last part of $*
|
||||
.PHONY: stack-%
|
||||
stack-%:
|
||||
$(eval stack := $(subst -$(lastword $(subst -, ,$*)),,$*))
|
||||
$(eval command := $(lastword $(subst -, ,$*)))
|
||||
$(if $(findstring -,$*), \
|
||||
$(if $(filter $(command),$(filter-out %-%,$(patsubst docker-compose-%,%,$(filter docker-compose-%,$(MAKETARGETS))))), \
|
||||
$(call make,docker-compose-$(command) STACK="$(stack)" $(if $(filter node,$(stack)),COMPOSE_PROJECT_NAME=$(COMPOSE_PROJECT_NAME_INFRA_NODE)),,ARGS COMPOSE_IGNORE_ORPHANS SERVICE)))
|
||||
|
||||
.PHONY: start
|
||||
start: docker-compose-start ## Start application dockers
|
||||
|
||||
.PHONY: stop
|
||||
stop: docker-compose-stop ## Stop application dockers
|
||||
|
||||
.PHONY: tests app-tests
|
||||
tests: app-tests ## Test application
|
||||
|
||||
.PHONY: up
|
||||
up: docker-compose-up start-up ## Create application dockers
|
||||
|
||||
.PHONY: update app-update
|
||||
update: app-update ## Update application
|
||||
|
||||
# target %: Always fired target
|
||||
## this target is fired everytime make is runned to call the stack target and
|
||||
## update COMPOSE_FILE variable with all .yml files of the current project stack
|
||||
.PHONY: FORCE
|
||||
%: FORCE stack %-rule-exists ;
|
||||
|
||||
# target %-rule-exists: Print a warning message if $* target does not exists
|
||||
%-rule-exists:
|
||||
$(if $(filter $*,$(MAKECMDGOALS)),$(if $(filter-out $*,$(MAKETARGETS)),printf "${COLOR_BROWN}WARNING${COLOR_RESET}: ${COLOR_GREEN}target${COLOR_RESET} $* ${COLOR_GREEN}not available in app${COLOR_RESET} $(APP).\n" >&2))
|
||||
@@ -0,0 +1,34 @@
|
||||
CODEDEPLOY_APP_NAME ?= $(APP)
|
||||
CODEDEPLOY_DEPLOYMENT_GROUP ?= $(CODEDEPLOY_APP_NAME)_$(ENV)
|
||||
CODEDEPLOY_DEPLOYMENT_CONFIG ?= CodeDeployDefault.AllAtOnce
|
||||
CODEDEPLOY_DESCRIPTION ?= deploy $(ENV) $(APP) branch: $(BRANCH) commit: $(SUBREPO_COMMIT) tag: $(TAG) version: $(VERSION)
|
||||
CODEDEPLOY_GITHUB_REPO ?= $(patsubst ssh://git@github.com/%,%,$(GIT_REPOSITORY))
|
||||
CODEDEPLOY_GITHUB_COMMIT_ID ?= $(SUBREPO_COMMIT)
|
||||
DEPLOY ?= false
|
||||
DEPLOY_PING_TEXT ?= app: *$(APP)* branch: *$(BRANCH)* env: *$(ENV)* version: *$(VERSION)* container: *$(CONTAINER)* host: *$(HOST)*
|
||||
DEPLOY_SLACK_HOOK ?= https://hooks.slack.com/services/123456789/123456789/ABCDEFGHIJKLMNOPQRSTUVWX
|
||||
HASH ?= $(shell date +%s)
|
||||
SERVER_NAME ?= $(DOCKER_REGISTRY_USERNAME).$(ENV).$(APP)
|
||||
OXA_SERVER_NAME ?= web
|
||||
|
||||
ifeq ($(APP),marketplace)
|
||||
CODEDEPLOY_APP_NAME := front
|
||||
EC2_SERVER_NAME := front
|
||||
else ifeq ($(APP),medias)
|
||||
CODEDEPLOY_APP_NAME := apimedia
|
||||
EC2_SERVER_NAME := api
|
||||
else ifeq ($(APP),partners)
|
||||
CODEDEPLOY_APP_NAME := api
|
||||
EC2_SERVER_NAME := api
|
||||
else ifeq ($(APP),workers)
|
||||
CODEDEPLOY_APP_NAME := worker
|
||||
EC2_SERVER_NAME := worker
|
||||
endif
|
||||
ifeq ($(ENV), preprod)
|
||||
CODEDEPLOY_APP_NAME := $(CODEDEPLOY_APP_NAME)pp
|
||||
CODEDEPLOY_DEPLOYMENT_GROUP := $(CODEDEPLOY_APP_NAME)_preprod
|
||||
OXA_SERVER_NAME := $(EC2_SERVER_NAME)pp-0x
|
||||
else ifeq ($(ENV), prod)
|
||||
CODEDEPLOY_DEPLOYMENT_GROUP := $(CODEDEPLOY_APP_NAME)_prod
|
||||
OXA_SERVER_NAME := $(EC2_SERVER_NAME)-xx
|
||||
endif
|
||||
@@ -0,0 +1,154 @@
|
||||
CMDS += docker-compose-exec docker-run docker-run-%
|
||||
COMPOSE_FILE ?= $(wildcard docker/docker-compose.yml $(foreach file,$(patsubst docker/docker-compose.%,%,$(basename $(wildcard docker/docker-compose.*.yml))),$(if $(filter true,$(COMPOSE_FILE_$(file)) $(COMPOSE_FILE_$(call UPPERCASE,$(file)))),docker/docker-compose.$(file).yml)))
|
||||
COMPOSE_FILE_$(ENV) ?= true
|
||||
COMPOSE_FILE_DEBUG ?= $(DEBUG)
|
||||
COMPOSE_FILE_NFS ?= $(MOUNT_NFS)
|
||||
COMPOSE_FILE_SSH ?= true
|
||||
ifneq ($(SUBREPO),)
|
||||
COMPOSE_FILE_SUBREPO ?= true
|
||||
else
|
||||
COMPOSE_FILE_APP ?= true
|
||||
endif
|
||||
ifneq (,$(filter $(ENV),$(ENV_DEPLOY)))
|
||||
COMPOSE_FILE_TMPFS ?= false
|
||||
else
|
||||
COMPOSE_FILE_TMPFS ?= true
|
||||
endif
|
||||
COMPOSE_PROJECT_NAME ?= $(USER)_$(ENV)_$(APP)
|
||||
COMPOSE_SERVICE_NAME ?= $(subst _,-,$(COMPOSE_PROJECT_NAME))
|
||||
CONTEXT += COMPOSE_FILE COMPOSE_PROJECT_NAME DOCKER_IMAGE_TAG DOCKER_REPOSITORY DOCKER_SERVICE
|
||||
DOCKER_BUILD_ARGS ?= $(if $(filter $(DOCKER_BUILD_NO_CACHE),true),--pull --no-cache) $(foreach var,$(DOCKER_BUILD_VARS),$(if $($(var)),--build-arg $(var)='$($(var))'))
|
||||
DOCKER_BUILD_CACHE ?= true
|
||||
DOCKER_BUILD_NO_CACHE ?= false
|
||||
DOCKER_BUILD_TARGET ?= $(if $(filter $(ENV),$(DOCKER_BUILD_TARGETS)),$(ENV),$(DOCKER_BUILD_TARGET_DEFAULT))
|
||||
DOCKER_BUILD_TARGET_DEFAULT ?= local
|
||||
DOCKER_BUILD_TARGETS ?= local debug tests preprod prod
|
||||
DOCKER_BUILD_VARS ?= APP BRANCH DOCKER_GID DOCKER_REPOSITORY GID GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME TARGET UID USER VERSION
|
||||
DOCKER_COMPOSE_DOWN_OPTIONS ?=
|
||||
DOCKER_COMPOSE_UP_OPTIONS ?= -d
|
||||
DOCKER_GID ?= $(call getent-group,docker)
|
||||
DOCKER_IMAGE_TAG ?= $(if $(filter-out $(APP),infra),$(if $(filter $(ENV),$(ENV_DEPLOY)),$(VERSION),$(if $(DRONE_BUILD_NUMBER),$(DRONE_BUILD_NUMBER),latest)),latest)
|
||||
DOCKER_IMAGES ?= $(patsubst %/,%,$(patsubst docker/%,%,$(dir $(wildcard docker/*/Dockerfile))))
|
||||
DOCKER_PLUGIN ?= rexray/s3fs:latest
|
||||
DOCKER_PLUGIN_ARGS ?= $(foreach var,$(DOCKER_PLUGIN_VARS),$(if $(DOCKER_PLUGIN_$(var)),$(var)='$(DOCKER_PLUGIN_$(var))'))
|
||||
DOCKER_PLUGIN_OPTIONS ?= --grant-all-permissions
|
||||
DOCKER_PLUGIN_S3FS_ACCESSKEY ?= $(shell $(call conf,$(HOME)/.aws/credentials,$(or $(AWS_PROFILE),default),aws_access_key_id))
|
||||
DOCKER_PLUGIN_S3FS_OPTIONS ?= allow_other,nonempty,use_path_request_style,url=https://s3-eu-west-1.amazonaws.com
|
||||
DOCKER_PLUGIN_S3FS_SECRETKEY ?= $(shell $(call conf,$(HOME)/.aws/credentials,$(or $(AWS_PROFILE),default),aws_secret_access_key))
|
||||
DOCKER_PLUGIN_S3FS_REGION ?= eu-west-1
|
||||
DOCKER_PLUGIN_VARS ?= S3FS_ACCESSKEY S3FS_OPTIONS S3FS_SECRETKEY S3FS_REGION
|
||||
DOCKER_REGISTRY ?= registry
|
||||
DOCKER_REGISTRY_USERNAME ?= $(USER)
|
||||
DOCKER_REGISTRY_REPOSITORY ?= $(addsuffix /,$(DOCKER_REGISTRY))$(subst $(USER),$(DOCKER_REGISTRY_USERNAME),$(DOCKER_REPOSITORY))
|
||||
DOCKER_REPOSITORY ?= $(subst _,/,$(COMPOSE_PROJECT_NAME))
|
||||
DOCKER_SHELL ?= $(SHELL)
|
||||
ENV_VARS += COMPOSE_PROJECT_NAME COMPOSE_SERVICE_NAME DOCKER_BUILD_TARGET DOCKER_GID DOCKER_HOST_IFACE DOCKER_HOST_INET DOCKER_IMAGE_TAG DOCKER_REGISTRY DOCKER_REPOSITORY DOCKER_SHELL
|
||||
|
||||
# https://github.com/docker/libnetwork/pull/2348
|
||||
ifeq ($(HOST_SYSTEM), DARWIN)
|
||||
DOCKER_HOST_IFACE ?= $(shell docker run --rm -it --net=host alpine /sbin/ip -4 route list match 0/0 2>/dev/null |awk '{print $$5}' |awk '!seen[$$0]++' |head -1)
|
||||
DOCKER_HOST_INET ?= $(shell docker run --rm -it --net=host alpine /sbin/ip -4 addr show $(DOCKER_HOST_IFACE) 2>/dev/null |awk '$$1 == "inet" {sub(/\/.*/,"",$$2); print $$2}')
|
||||
DOCKER_INTERNAL_DOCKER_GATEWAY ?= $(shell docker run --rm -it alpine getent hosts gateway.docker.internal |awk '{print $$1}' |head -1)
|
||||
DOCKER_INTERNAL_DOCKER_HOST ?= $(shell docker run --rm -it alpine getent hosts host.docker.internal |awk '{print $$1}' |head -1)
|
||||
else
|
||||
DOCKER_HOST_IFACE ?= $(shell /sbin/ip -4 route list match 0/0 2>/dev/null |awk '{print $$5}' |awk '!seen[$$0]++' |head -1)
|
||||
DOCKER_HOST_INET ?= $(shell /sbin/ip -4 addr show $(DOCKER_HOST_IFACE) 2>/dev/null |awk '$$1 == "inet" {sub(/\/.*/,"",$$2); print $$2}')
|
||||
DOCKER_INTERNAL_DOCKER_GATEWAY ?= $(shell /sbin/ip -4 route list match 0/0 2>/dev/null |awk '{print $$3}' |awk '!seen[$$0]++' |head -1)
|
||||
DOCKER_INTERNAL_DOCKER_HOST ?= $(shell /sbin/ip addr show docker0 2>/dev/null |awk '$$1 == "inet" {sub(/\/.*/,"",$$2); print $$2}')
|
||||
endif
|
||||
|
||||
ifeq ($(DRONE), true)
|
||||
DOCKER_COMPOSE_DOWN_OPTIONS := --rmi all -v
|
||||
DOCKER_COMPOSE_UP_OPTIONS := -d --build
|
||||
DOCKER_BUILD_CACHE := false
|
||||
ENV_SUFFIX := $(DRONE_BUILD_NUMBER)
|
||||
ifneq ($(APP), infra)
|
||||
COMPOSE_PROJECT_NAME := $(USER)_$(ENV)$(ENV_SUFFIX)_$(APP)
|
||||
COMPOSE_SERVICE_NAME := $(subst _,-,$(COMPOSE_PROJECT_NAME))
|
||||
DOCKER_REPOSITORY := $(USER)/$(ENV)/$(APP)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(DOCKER), true)
|
||||
|
||||
define docker-compose
|
||||
$(call run,docker/compose:$(COMPOSE_VERSION) $(patsubst %,-f %,$(COMPOSE_FILE)) -p $(COMPOSE_PROJECT_NAME) $(1))
|
||||
endef
|
||||
define docker-compose-exec
|
||||
$(call run,docker/compose:$(COMPOSE_VERSION) $(patsubst %,-f %,$(COMPOSE_FILE)) -p $(COMPOSE_PROJECT_NAME) exec -T $(1) sh -c '$(2)')
|
||||
endef
|
||||
|
||||
else
|
||||
|
||||
SHELL := /bin/bash
|
||||
define docker-compose
|
||||
$(call run,docker-compose $(patsubst %,-f %,$(COMPOSE_FILE)) -p $(COMPOSE_PROJECT_NAME) $(1))
|
||||
endef
|
||||
define docker-compose-exec
|
||||
$(call run,docker-compose $(patsubst %,-f %,$(COMPOSE_FILE)) -p $(COMPOSE_PROJECT_NAME) exec -T $(1) sh -c '$(2)')
|
||||
endef
|
||||
|
||||
endif
|
||||
|
||||
define docker-build
|
||||
$(eval path := $(patsubst %/,%,$(1)))
|
||||
$(eval tag := $(or $(2),$(DOCKER_REPOSITORY)/$(lastword $(subst /, ,$(path))):$(DOCKER_IMAGE_TAG)))
|
||||
$(eval target := $(subst ",,$(subst ',,$(or $(3),$(DOCKER_BUILD_TARGET)))))
|
||||
$(eval image_id := $(shell docker images -q $(tag) 2>/dev/null))
|
||||
$(eval build_image := $(or $(filter $(DOCKER_BUILD_CACHE),false),$(if $(image_id),,true)))
|
||||
$(if $(build_image),$(ECHO) docker build $(DOCKER_BUILD_ARGS) --build-arg DOCKER_BUILD_DIR="$(path)" --tag $(tag) $(if $(target),--target $(target)) -f $(path)/Dockerfile .,$(if $(filter $(VERBOSE),true),echo "docker image $(tag) has id $(image_id)",true))
|
||||
endef
|
||||
define docker-commit
|
||||
$(eval service := $(or $(1),$(DOCKER_SERVICE)))
|
||||
$(eval container := $(or $(2),$(firstword $(shell $(call docker-compose,--log-level critical ps -q $(service))))))
|
||||
$(eval repository := $(or $(3),$(DOCKER_REPOSITORY)/$(service)))
|
||||
$(eval tag := $(or $(4),$(DOCKER_IMAGE_TAG)))
|
||||
$(if $(filter $(VERBOSE),true),echo docker commit $(container) $(repository):$(tag))
|
||||
$(ECHO) docker commit $(container) $(repository):$(tag)
|
||||
endef
|
||||
define docker-push
|
||||
$(eval service := $(or $(1),$(DOCKER_SERVICE)))
|
||||
$(eval name := $(or $(2),$(DOCKER_REGISTRY_REPOSITORY)/$(service)))
|
||||
$(eval tag := $(or $(3),$(DOCKER_IMAGE_TAG)))
|
||||
$(if $(filter $(VERBOSE),true),echo docker push $(name):$(tag))
|
||||
$(ECHO) docker push $(name):$(tag)
|
||||
endef
|
||||
##
|
||||
# docker-stack
|
||||
# docker-stack: if 1st arg is a variable and can be expand to values, it calls
|
||||
# itself again, once whith each value, else calls docker-stack-update function
|
||||
# 1st arg: stacks, extract it from stack_names:stack_versions
|
||||
# 2nd arg: versions, extract it from stack_names:stack_versions or 2nd arg
|
||||
define docker-stack
|
||||
$(eval stacks := $(firstword $(subst :, ,$(1))))
|
||||
$(eval versions := $(or $(if $(findstring :,$(1)),$(lastword $(subst :, ,$(1)))),$(2)))
|
||||
$(if $($(stacks)),$(foreach substack,$($(stacks)),$(call docker-stack,$(substack),$(if $(findstring :,$(1)),$(versions)))),$(call docker-stack-update,$(stacks),$(versions)))
|
||||
endef
|
||||
##
|
||||
# docker-stack-update
|
||||
# docker-stack-update: adds all .yml files of the stack to COMPOSE_FILE variable
|
||||
# and update the .env file with the .env.dist files of the stack
|
||||
# 1st arg: stack_path/stack_name:stack_version
|
||||
# stack: get stack_name:stack_version from 1st arg
|
||||
# name: get stack name from $(stack)
|
||||
# 2nd arg: stack version, or extract it from $(stack), default to latest
|
||||
# 3rd arg: stack path, or extract it from $(stack), default to stack/$(name)
|
||||
# add $(path)/$(name).yml, $(path)/$(name).$(ENV).yml and $(path)/$(name).$(version).yml to COMPOSE_FILE variable
|
||||
# if $(path)/.env.dist file exists, update .env file
|
||||
define docker-stack-update
|
||||
$(eval stack := $(patsubst %.yml,%,$(notdir $(1))))
|
||||
$(eval name := $(firstword $(subst :, ,$(stack))))
|
||||
$(eval version := $(or $(2),$(if $(findstring :,$(stack)),$(lastword $(subst :, ,$(stack))),latest)))
|
||||
$(eval path := $(patsubst %/,%,$(or $(3),$(if $(findstring /,$(1)),$(if $(wildcard stack/$(1) stack/$(1).yml),stack/$(if $(findstring .yml,$(1)),$(dir $(1)),$(if $(wildcard stack/$(1).yml),$(dir $(1)),$(1))),$(dir $(1)))),stack/$(name))))
|
||||
$(eval COMPOSE_FILE += $(wildcard $(path)/$(name).yml $(path)/$(name).$(ENV).yml $(path)/$(name).$(ENV).$(version).yml $(path)/$(name).$(version).yml))
|
||||
$(if $(wildcard $(path)/.env.dist),$(call .env,,$(path)/.env.dist,$(wildcard ../$(PARAMETERS)/$(ENV)/$(APP)/.env $(path)/.env.$(ENV) .env)))
|
||||
endef
|
||||
define docker-tag
|
||||
$(eval service := $(or $(1),$(DOCKER_SERVICE)))
|
||||
$(eval source := $(or $(2),$(DOCKER_REPOSITORY)/$(service)))
|
||||
$(eval source_tag := $(or $(3),$(DOCKER_IMAGE_TAG)))
|
||||
$(eval target := $(or $(4),$(DOCKER_REGISTRY_REPOSITORY)/$(service)))
|
||||
$(eval target_tag := $(or $(5),$(source_tag)))
|
||||
$(if $(filter $(VERBOSE),true),echo docker tag $(source):$(source_tag) $(target):$(target_tag))
|
||||
$(ECHO) docker tag $(source):$(source_tag) $(target):$(target_tag)
|
||||
endef
|
||||
@@ -0,0 +1,7 @@
|
||||
define install-parameters
|
||||
$(eval path:=$(or $(1),$(APP)))
|
||||
$(eval file:=$(or $(2),$(DOCKER_SERVICE)/parameters.yml))
|
||||
$(eval dest:=$(or $(3),app/config))
|
||||
$(eval env:=$(or $(4),$(ENV)))
|
||||
$(if $(wildcard $(dest)/$(file)),,$(if $(wildcard ../$(PARAMETERS)/$(env)/$(path)/$(file)),$(ECHO) cp -a ../$(PARAMETERS)/$(env)/$(path)/$(file) $(dest)))
|
||||
endef
|
||||
@@ -0,0 +1,4 @@
|
||||
ENV_VARS += NFS_CONFIG
|
||||
MOUNT_NFS ?= false
|
||||
NFS_CONFIG ?= addr=$(NFS_HOST),actimeo=3,intr,noacl,noatime,nocto,nodiratime,nolock,soft,rsize=32768,wsize=32768,tcp,rw,vers=3
|
||||
NFS_HOST ?= host.docker.internal
|
||||
@@ -0,0 +1,88 @@
|
||||
##########
|
||||
# DEPLOY #
|
||||
##########
|
||||
|
||||
.PHONY: deploy app-deploy
|
||||
# target deploy: Run post install hooks in the deployed application
|
||||
## Called by ansible after creation of the docker application on remote host
|
||||
deploy: app-deploy ## Run post install hooks in the deployed application
|
||||
|
||||
.PHONY: deploy@%
|
||||
# target deploy@%: Deploy application docker images
|
||||
## tag and push docker images to docker registry
|
||||
## run ansible-pull on hosts to pull docker images from the registry
|
||||
## tag and push docker images as latest to docker registry
|
||||
deploy@%: infra-base build@% ## Deploy application docker images
|
||||
$(call make,docker-login docker-tag docker-push)
|
||||
$(call make,infra-ansible-pull@$(ENV) ANSIBLE_DOCKER_IMAGE_TAG=$(VERSION) ANSIBLE_TAGS=aws,,APP AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY)
|
||||
$(call make,docker-tag-latest docker-push-latest)
|
||||
|
||||
.PHONY: deploy-aws-codedeploy-%
|
||||
deploy-aws-codedeploy-%:
|
||||
$(call exec,git fetch subrepo/$(SUBREPO))
|
||||
ifneq ($(wildcard ../infra),)
|
||||
$(call make,aws-codedeploy,../infra,CODEDEPLOY_APP_NAME CODEDEPLOY_DEPLOYMENT_CONFIG CODEDEPLOY_DEPLOYMENT_GROUP CODEDEPLOY_DESCRIPTION CODEDEPLOY_GITHUB_REPO CODEDEPLOY_GITHUB_COMMIT_ID)
|
||||
endif
|
||||
|
||||
.PHONY: deploy-assets-install
|
||||
deploy-assets-install:
|
||||
su -s /bin/sh www-data -c "php app/console --no-interaction assets:install --env=prod"
|
||||
su -s /bin/sh www-data -c "php app/console --no-interaction assetic:dump --env=prod"
|
||||
|
||||
.PHONY: deploy-cache-clear
|
||||
deploy-cache-clear:
|
||||
su -s /bin/sh www-data -c "php app/console --no-interaction cache:clear --env=prod"
|
||||
|
||||
.PHONY: deploy-cache-warmup
|
||||
deploy-cache-warmup:
|
||||
su -s /bin/sh www-data -c "php app/console --no-interaction cache:warmup --env=prod"
|
||||
|
||||
.PHONY: deploy-composer
|
||||
deploy-composer:
|
||||
su -s /bin/sh www-data -c "composer install --prefer-dist --optimize-autoloader --no-progress --no-interaction --no-dev"
|
||||
|
||||
.PHONY: deploy-doctrine-migrations-migrate
|
||||
deploy-doctrine-migrations-migrate:
|
||||
su -s /bin/sh www-data -c "php app/console --no-interaction doctrine:migrations:migrate"
|
||||
|
||||
.PHONY: deploy-npm
|
||||
deploy-npm: deploy-npm-install deploy-npm-run-build
|
||||
|
||||
.PHONY: deploy-npm-install
|
||||
deploy-npm-install:
|
||||
npm set progress=false
|
||||
npm install -s
|
||||
|
||||
.PHONY: deploy-npm-run-build
|
||||
deploy-npm-run-build:
|
||||
npm run build:prod
|
||||
|
||||
.PHONY: deploy-ping
|
||||
deploy-ping: deploy-ping-slack
|
||||
|
||||
.PHONY: deploy-ping-slack
|
||||
deploy-ping-slack:
|
||||
curl -X POST --data-urlencode 'payload={"text": "$(DEPLOY_PING_TEXT)"}' $(DEPLOY_SLACK_HOOK) ||:
|
||||
|
||||
.PHONY: deploy-supervisorctl-restart-all
|
||||
deploy-supervisorctl-restart-all:
|
||||
supervisorctl restart all
|
||||
|
||||
.PHONY: deploy-supervisorctl-start-all
|
||||
deploy-supervisorctl-start-all:
|
||||
supervisorctl start all
|
||||
|
||||
.PHONY: deploy-supervisorctl-stop-all
|
||||
deploy-supervisorctl-stop-all:
|
||||
supervisorctl stop all
|
||||
|
||||
.PHONY: deploy-yarn
|
||||
deploy-yarn: deploy-yarn-install
|
||||
|
||||
.PHONY: deploy-yarn-build
|
||||
deploy-yarn-build:
|
||||
yarn build:prod
|
||||
|
||||
.PHONY: deploy-yarn-install
|
||||
deploy-yarn-install:
|
||||
yarn install
|
||||
@@ -0,0 +1,211 @@
|
||||
##
|
||||
# DOCKER
|
||||
|
||||
.PHONY: docker-build
|
||||
docker-build: docker-images-infra
|
||||
$(foreach image,$(or $(SERVICE),$(DOCKER_IMAGES)),$(call make,docker-build-$(image)))
|
||||
|
||||
.PHONY: docker-build-%
|
||||
docker-build-%:
|
||||
if grep -q DOCKER_REPOSITORY docker/$*/Dockerfile 2>/dev/null; then $(eval DOCKER_BUILD_ARGS:=$(subst $(DOCKER_REPOSITORY),$(DOCKER_REPOSITORY_INFRA),$(DOCKER_BUILD_ARGS))) true; fi
|
||||
$(if $(wildcard docker/$*/Dockerfile),$(call docker-build,docker/$*))
|
||||
$(if $(findstring :,$*),$(eval DOCKERFILES := $(wildcard docker/$(subst :,/,$*)/Dockerfile)),$(eval DOCKERFILES := $(wildcard docker/$*/*/Dockerfile)))
|
||||
$(foreach dockerfile,$(DOCKERFILES),$(call docker-build,$(dir $(dockerfile)),$(DOCKER_REPOSITORY)/$(word 2,$(subst /, ,$(dir $(dockerfile)))):$(lastword $(subst /, ,$(dir $(dockerfile)))),"") && true)
|
||||
|
||||
.PHONY: docker-commit
|
||||
docker-commit:
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(foreach service,$(or $(SERVICE),$(SERVICES)),$(call docker-commit,$(service)))
|
||||
|
||||
.PHONY: docker-commit-%
|
||||
docker-commit-%:
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(foreach service,$(or $(SERVICE),$(SERVICES)),$(call docker-commit,$(service),,,$*))
|
||||
|
||||
.PHONY: docker-compose-build
|
||||
docker-compose-build: docker-images-infra
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(call docker-compose,build $(if $(filter $(DOCKER_BUILD_NO_CACHE),true),--pull --no-cache) $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE)))
|
||||
|
||||
.PHONY: docker-compose-config
|
||||
docker-compose-config:
|
||||
$(call docker-compose,config)
|
||||
|
||||
.PHONY: docker-compose-connect
|
||||
docker-compose-connect: SERVICE ?= $(DOCKER_SERVICE)
|
||||
docker-compose-connect:
|
||||
$(call docker-compose,exec $(SERVICE) $(DOCKER_SHELL)) || true
|
||||
|
||||
.PHONY: docker-compose-down
|
||||
docker-compose-down:
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(if $(filter $(SERVICE),$(SERVICES)),$(call docker-compose,rm -fs $(SERVICE)),$(call docker-compose,down $(DOCKER_COMPOSE_DOWN_OPTIONS)))
|
||||
|
||||
.PHONY: docker-compose-exec
|
||||
docker-compose-exec: SERVICE ?= $(DOCKER_SERVICE)
|
||||
docker-compose-exec:
|
||||
$(call docker-compose-exec,$(SERVICE),$(ARGS)) || true
|
||||
|
||||
.PHONY: docker-compose-logs
|
||||
docker-compose-logs:
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(call docker-compose,logs -f --tail=100 $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE))) || true
|
||||
|
||||
.PHONY: docker-compose-ps
|
||||
docker-compose-ps:
|
||||
$(call docker-compose,ps)
|
||||
|
||||
.PHONY: docker-compose-rebuild
|
||||
docker-compose-rebuild: docker-images-infra
|
||||
$(call make,docker-compose-build DOCKER_BUILD_NO_CACHE=true)
|
||||
|
||||
.PHONY: docker-compose-recreate
|
||||
docker-compose-recreate: docker-compose-rm docker-compose-up
|
||||
|
||||
.PHONY: docker-compose-restart
|
||||
docker-compose-restart:
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(call docker-compose,restart $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE)))
|
||||
|
||||
.PHONY: docker-compose-rm
|
||||
docker-compose-rm:
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(call docker-compose,rm -fs $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE)))
|
||||
|
||||
.PHONY: docker-compose-run
|
||||
docker-compose-run: SERVICE ?= $(DOCKER_SERVICE)
|
||||
docker-compose-run:
|
||||
$(call docker-compose,run $(SERVICE) $(ARGS))
|
||||
|
||||
.PHONY: docker-compose-scale
|
||||
docker-compose-scale: SERVICE ?= $(DOCKER_SERVICE)
|
||||
docker-compose-scale:
|
||||
$(call docker-compose,up $(DOCKER_COMPOSE_UP_OPTIONS) --scale $(SERVICE)=$(NUM))
|
||||
|
||||
.PHONY: docker-compose-start
|
||||
docker-compose-start:
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(call docker-compose,start $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE)))
|
||||
|
||||
.PHONY: docker-compose-stop
|
||||
docker-compose-stop:
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(call docker-compose,stop $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE)))
|
||||
|
||||
.PHONY: docker-compose-up
|
||||
docker-compose-up: docker-images-infra
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(call docker-compose,up $(DOCKER_COMPOSE_UP_OPTIONS) $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE)))
|
||||
|
||||
.PHONY: docker-images-infra
|
||||
docker-images-infra:
|
||||
$(foreach image,$(subst $(quote),,$(DOCKER_IMAGES_INFRA)),$(call make,infra-docker-build-$(image)))
|
||||
|
||||
.PHONY: docker-login
|
||||
docker-login: infra-aws-ecr-login
|
||||
|
||||
.PHONY: docker-network-create
|
||||
docker-network-create: docker-network-create-$(DOCKER_NETWORK)
|
||||
|
||||
.PHONY: docker-network-create-%
|
||||
docker-network-create-%:
|
||||
[ -n "$(shell docker network ls -q --filter name='^$*$$' 2>/dev/null)" ] \
|
||||
|| { echo -n "Creating docker network $* ... " && $(ECHO) docker network create $* >/dev/null 2>&1 && echo "done" || echo "ERROR"; }
|
||||
|
||||
.PHONY: docker-network-rm
|
||||
docker-network-rm: docker-network-rm-$(DOCKER_NETWORK)
|
||||
|
||||
.PHONY: docker-network-rm-%
|
||||
docker-network-rm-%:
|
||||
[ -z "$(shell docker network ls -q --filter name='^$*$$' 2>/dev/null)" ] \
|
||||
|| { echo -n "Removing docker network $* ... " && $(ECHO) docker network rm $* >/dev/null 2>&1 && echo "done" || echo "ERROR"; }
|
||||
|
||||
.PHONY: docker-plugin-install
|
||||
docker-plugin-install:
|
||||
$(eval docker_plugin_state := $(shell docker plugin ls | awk '$$2 == "$(DOCKER_PLUGIN)" {print $$NF}') )
|
||||
$(if $(docker_plugin_state),$(if $(filter $(docker_plugin_state),false),echo -n "Enabling docker plugin $(DOCKER_PLUGIN) ... " && $(ECHO) docker plugin enable $(DOCKER_PLUGIN) >/dev/null 2>&1 && echo "done" || echo "ERROR"),echo -n "Installing docker plugin $(DOCKER_PLUGIN) ... " && $(ECHO) docker plugin install $(DOCKER_PLUGIN_OPTIONS) $(DOCKER_PLUGIN) $(DOCKER_PLUGIN_ARGS) >/dev/null 2>&1 && echo "done" || echo "ERROR")
|
||||
|
||||
.PHONY: docker-push
|
||||
docker-push:
|
||||
ifneq ($(filter $(DEPLOY),true),)
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(foreach service,$(or $(SERVICE),$(SERVICES)),$(call docker-push,$(service)))
|
||||
else
|
||||
printf "${COLOR_BROWN}WARNING${COLOR_RESET}: ${COLOR_GREEN}target${COLOR_RESET} $@ ${COLOR_GREEN}not enabled in${COLOR_RESET} $(APP).\n" >&2
|
||||
endif
|
||||
|
||||
.PHONY: docker-push-%
|
||||
docker-push-%:
|
||||
ifneq ($(filter $(DEPLOY),true),)
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(foreach service,$(or $(SERVICE),$(SERVICES)),$(call docker-push,$(service),,$*))
|
||||
else
|
||||
printf "${COLOR_BROWN}WARNING${COLOR_RESET}: ${COLOR_GREEN}target${COLOR_RESET} $@ ${COLOR_GREEN}not enabled in${COLOR_RESET} $(APP).\n" >&2
|
||||
endif
|
||||
|
||||
.PHONY: docker-rebuild
|
||||
docker-rebuild:
|
||||
$(call make,docker-build DOCKER_BUILD_CACHE=false)
|
||||
|
||||
.PHONY: docker-rebuild-%
|
||||
docker-rebuild-%:
|
||||
$(call make,docker-build-$* DOCKER_BUILD_CACHE=false)
|
||||
|
||||
.PHONY: docker-run
|
||||
docker-run: SERVICE ?= $(DOCKER_SERVICE)
|
||||
docker-run:
|
||||
$(call make,docker-run-$(SERVICE),,ARGS)
|
||||
|
||||
.PHONY: docker-run-%
|
||||
docker-run-%: docker-build-%
|
||||
$(eval command := $(ARGS))
|
||||
$(eval path := $(patsubst %/,%,$*))
|
||||
$(eval image := $(DOCKER_REPOSITORY)/$(lastword $(subst /, ,$(path)))$(if $(findstring :,$*),,:$(DOCKER_IMAGE_TAG)))
|
||||
$(eval image_id := $(shell docker images -q $(image) 2>/dev/null))
|
||||
$(call docker-run,$(if $(image_id),$(image),$(path)),$(command))
|
||||
|
||||
.PHONY: docker-tag
|
||||
docker-tag:
|
||||
ifneq ($(filter $(DEPLOY),true),)
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(foreach service,$(or $(SERVICE),$(SERVICES)),$(call docker-tag,$(service)))
|
||||
else
|
||||
printf "${COLOR_BROWN}WARNING${COLOR_RESET}: ${COLOR_GREEN}target${COLOR_RESET} $@ ${COLOR_GREEN}not enabled in${COLOR_RESET} $(APP).\n" >&2
|
||||
endif
|
||||
|
||||
.PHONY: docker-tag-%
|
||||
docker-tag-%:
|
||||
ifneq ($(filter $(DEPLOY),true),)
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(foreach service,$(or $(SERVICE),$(SERVICES)),$(call docker-tag,$(service),,,,$*))
|
||||
else
|
||||
printf "${COLOR_BROWN}WARNING${COLOR_RESET}: ${COLOR_GREEN}target${COLOR_RESET} $@ ${COLOR_GREEN}not enabled in${COLOR_RESET} $(APP).\n" >&2
|
||||
endif
|
||||
@@ -0,0 +1,26 @@
|
||||
.PHONY: ansible
|
||||
ansible: docker-build-ansible
|
||||
ifneq ($(ARGS),)
|
||||
$(call ansible,$(ANSIBLE_ARGS) $(ARGS))
|
||||
else
|
||||
$(call make,ansible-run)
|
||||
endif
|
||||
|
||||
.PHONY: ansible-playbook
|
||||
ansible-playbook:
|
||||
$(call ansible-playbook,$(ANSIBLE_ARGS) $(ARGS))
|
||||
|
||||
.PHONY: ansible-pull
|
||||
ansible-pull:
|
||||
$(call ansible-pull,--url $(ANSIBLE_GIT_REPOSITORY) $(if $(ANSIBLE_GIT_KEY_FILE),--key-file $(ANSIBLE_GIT_KEY_FILE)) $(if $(ANSIBLE_GIT_VERSION),--checkout $(ANSIBLE_GIT_VERSION)) $(if $(ANSIBLE_GIT_DIRECTORY),--directory $(ANSIBLE_GIT_DIRECTORY)) $(if $(ANSIBLE_TAGS),--tags $(ANSIBLE_TAGS)) $(if $(ANSIBLE_EXTRA_VARS),--extra-vars '$(ANSIBLE_EXTRA_VARS)') $(if $(findstring true,$(FORCE)),--force) $(if $(findstring true,$(DRYRUN)),--check) --full $(if $(ANSIBLE_INVENTORY),--inventory $(ANSIBLE_INVENTORY)) $(ANSIBLE_PLAYBOOK))
|
||||
|
||||
.PHONY: ansible-pull@%
|
||||
ansible-pull@%: aws-ec2-get-PrivateIpAddress-$(SERVER_NAME)
|
||||
$(call ssh-exec,$(AWS_INSTANCE_IP),make ansible-pull ANSIBLE_DOCKER_IMAGE_TAG=$(ANSIBLE_DOCKER_IMAGE_TAG) ANSIBLE_TAGS=$(ANSIBLE_TAGS) FORCE=$(FORCE))
|
||||
|
||||
.PHONY: ansible-run
|
||||
ansible-run: base-ssh-add docker-build-ansible ansible-run-localhost
|
||||
|
||||
.PHONY: ansible-run-%
|
||||
ansible-run-%:
|
||||
$(call ansible-playbook,$(if $(ANSIBLE_TAGS),--tags $(ANSIBLE_TAGS)) $(if $(ANSIBLE_EXTRA_VARS),--extra-vars '$(patsubst target=localhost,target=$*,$(ANSIBLE_EXTRA_VARS))') $(if $(findstring true,$(DRYRUN)),--check) $(if $(ANSIBLE_INVENTORY),--inventory $(ANSIBLE_INVENTORY)) $(ANSIBLE_PLAYBOOK))
|
||||
@@ -0,0 +1,170 @@
|
||||
.PHONY: aws
|
||||
aws: docker-build-aws
|
||||
$(call aws,$(ARGS))
|
||||
|
||||
.PHONY: aws-codedeploy
|
||||
aws-codedeploy:
|
||||
$(call aws,deploy create-deployment \
|
||||
--application-name $(CODEDEPLOY_APP_NAME) \
|
||||
--deployment-config-name $(CODEDEPLOY_DEPLOYMENT_CONFIG) \
|
||||
--deployment-group-name $(CODEDEPLOY_DEPLOYMENT_GROUP) \
|
||||
--description "$(CODEDEPLOY_DESCRIPTION)" \
|
||||
--github-location repository=$(CODEDEPLOY_GITHUB_REPO)$(comma)commitId=$(CODEDEPLOY_GITHUB_COMMIT_ID))
|
||||
|
||||
.PHONY: aws-role-create-import-image
|
||||
aws-role-create-import-image: aws-iam-create-role-$(AWS_VM_IMPORT_ROLE_NAME) aws-iam-put-role-policy-$(AWS_VM_IMPORT_ROLE_NAME)
|
||||
|
||||
.PHONY: aws-ecr-login
|
||||
aws-ecr-login:
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval docker_login := $(shell $(call aws,ecr get-login --no-include-email --region $(AWS_DEFAULT_REGION))))
|
||||
$(eval DRYRUN_IGNORE := FALSE)
|
||||
$(ECHO) $(docker_login)
|
||||
|
||||
.PHONY: aws-iam-create-role-%
|
||||
aws-iam-create-role-%: base docker-build-aws
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval json := $(shell $(call exec,envsubst < aws/policies/$*-trust.json)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(call aws,iam create-role --role-name $* --assume-role-policy-document '$(json)')
|
||||
|
||||
.PHONY: aws-iam-put-role-policy-%
|
||||
aws-iam-put-role-policy-%: base docker-build-aws
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval json := $(shell $(call exec,envsubst < aws/policies/$*.json)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(call aws,iam put-role-policy --role-name $* --policy-name $* --policy-document '$(json)')
|
||||
|
||||
.PHONY: aws-s3-check-upload
|
||||
aws-s3-check-upload: docker-build-aws aws-s3api-head-object-query-etag
|
||||
$(eval upload := true)
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(if $(AWS_S3_KEY_ETAG),$(if $(filter $(AWS_S3_KEY_ETAG),"$(shell cat $(PACKER_ISO_INFO) |awk '$$1 == "etag:" {print $$2}' 2>/dev/null)"),$(eval upload := false)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
|
||||
.PHONY: aws-s3-cp
|
||||
aws-s3-cp: docker-build-aws $(PACKER_ISO_FILE) aws-s3-check-upload
|
||||
$(if $(filter $(upload),true),$(call aws,s3 cp $(PACKER_ISO_FILE) s3://$(AWS_S3_BUCKET)/$(AWS_S3_KEY)) $(call make,aws-s3-etag-save))
|
||||
|
||||
.PHONY: aws-s3-etag-save
|
||||
aws-s3-etag-save: docker-build-aws aws-s3api-head-object-query-etag
|
||||
echo "etag: $(AWS_S3_KEY_ETAG)" >> $(PACKER_ISO_INFO)
|
||||
|
||||
.PHONY: aws-s3api-head-object-query-etag
|
||||
aws-s3api-head-object-query-etag: docker-build-aws
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval AWS_S3_KEY_ETAG := $(shell $(call aws,s3api head-object --bucket $(AWS_S3_BUCKET) --key $(AWS_S3_KEY) --output text --query ETag) |grep -v 'operation: Not Found' 2>/dev/null))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
echo ETag: $(AWS_S3_KEY_ETAG)
|
||||
|
||||
.PHONY: aws-s3api-head-object-query-lastmodified
|
||||
aws-s3api-head-object-query-lastmodified: docker-build-aws
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval AWS_S3_KEY_DATE := $(shell $(call aws,s3api head-object --bucket $(AWS_S3_BUCKET) --key $(AWS_S3_KEY) --output text --query LastModified) |grep -v 'operation: Not Found' 2>/dev/null))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
echo LastModified: $(AWS_S3_KEY_DATE)
|
||||
|
||||
.PHONY: aws-ec2-import-snapshot
|
||||
aws-ec2-import-snapshot: base docker-build-aws aws-s3api-head-object-query-etag aws-s3api-head-object-query-lastmodified
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval json := $(shell $(call exec,envsubst < aws/import-snapshot.json)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(eval AWS_TASK_ID := $(shell $(call aws,ec2 import-snapshot --description '$(AWS_SNAP_DESCRIPTION)' --output text --query ImportTaskId --disk-container '$(json)')))
|
||||
echo ImportTaskId: $(AWS_TASK_ID)
|
||||
|
||||
.PHONY: aws-ec2-describe-import-snapshot-task-%
|
||||
aws-ec2-describe-import-snapshot-task-%: docker-build-aws
|
||||
$(call aws,ec2 describe-import-snapshot-tasks --import-task-ids $*)
|
||||
|
||||
.PHONY: aws-ec2-describe-import-snapshot-tasks
|
||||
aws-ec2-describe-import-snapshot-tasks: docker-build-aws
|
||||
$(call aws,ec2 describe-import-snapshot-tasks)
|
||||
|
||||
.PHONY: aws-ec2-describe-instance-PrivateIpAddress
|
||||
aws-ec2-describe-instance-PrivateIpAddress: docker-build-aws
|
||||
$(call aws,ec2 describe-instances --no-paginate --query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value$(comma)PrivateIpAddress]' --output text) |sed '$$!N;s/\r\n/ /' |awk 'BEGIN {printf "%-24s%s\r\n"$(comma)"PrivateIpAddress"$(comma)"Name"}; $$1 != "None" {printf "%-24s%s\n"$(comma)$$1$(comma)$$2}'
|
||||
|
||||
.PHONY: aws-ec2-describe-instance-PrivateIpAddress-%
|
||||
aws-ec2-describe-instance-PrivateIpAddress-%: docker-build-aws
|
||||
$(call aws,ec2 describe-instances --no-paginate --query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value$(comma)PrivateIpAddress]' --output text) |sed '$$!N;s/\r\n/ /' |awk 'BEGIN {printf "%-24s%s\r\n"$(comma)"PrivateIpAddress"$(comma)"Name"}; $$1 != "None" && $$2 ~ /$*/ {printf "%-24s%s\n"$(comma)$$1$(comma)$$2}'
|
||||
|
||||
.PHONY: aws-ec2-get-PrivateIpAddress
|
||||
aws-ec2-get-PrivateIpAddress: docker-build-aws
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval AWS_INSTANCE_IP := $(shell $(call aws,ec2 describe-instances --no-paginate --query 'Reservations[*].Instances[*].PrivateIpAddress' --output text) 2>/dev/null))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
echo PrivateIpAddress: $(AWS_INSTANCE_IP)
|
||||
|
||||
.PHONY: aws-ec2-get-PrivateIpAddress-%
|
||||
aws-ec2-get-PrivateIpAddress-%:
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval AWS_INSTANCE_IP := $(shell $(call aws,ec2 describe-instances --no-paginate --filter 'Name=tag:Name$(comma)Values=$**' --query 'Reservations[*].Instances[*].PrivateIpAddress' --output text) 2>/dev/null))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
echo PrivateIpAddress: $(AWS_INSTANCE_IP)
|
||||
|
||||
.PHONY: aws-ec2-get-snap-id-import-snapshot-task
|
||||
aws-ec2-get-snap-id-import-snapshot-task: aws-ec2-get-snap-id-import-snapshot-task-$(AWS_TASK_ID)
|
||||
|
||||
.PHONY: aws-ec2-get-snap-id-import-snapshot-task-%
|
||||
aws-ec2-get-snap-id-import-snapshot-task-%: docker-build-aws
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval AWS_SNAP_ID := $(shell $(call aws,ec2 describe-import-snapshot-tasks --import-task-ids $* --output text --query ImportSnapshotTasks[0].SnapshotTaskDetail.SnapshotId) 2>/dev/null))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
echo SnapshotId: $(AWS_SNAP_ID)
|
||||
|
||||
.PHONY: aws-ec2-get-snap-message-import-snapshot-task-%
|
||||
aws-ec2-get-snap-message-import-snapshot-task-%: docker-build-aws
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval AWS_SNAP_MESSAGE := $(shell $(call aws,ec2 describe-import-snapshot-tasks --import-task-ids $* --output text --query ImportSnapshotTasks[0].SnapshotTaskDetail.StatusMessage) 2>/dev/null))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
echo StatusMessage: $(AWS_SNAP_MESSAGE)
|
||||
|
||||
.PHONY: aws-ec2-get-snap-progress-import-snapshot-task-%
|
||||
aws-ec2-get-snap-progress-import-snapshot-task-%: docker-build-aws
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval AWS_SNAP_PROGRESS := $(shell $(call aws,ec2 describe-import-snapshot-tasks --import-task-ids $* --output text --query ImportSnapshotTasks[0].SnapshotTaskDetail.Progress) 2>/dev/null))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
echo Progress: $(AWS_SNAP_PROGRESS)
|
||||
|
||||
.PHONY: aws-ec2-get-snap-size-import-snapshot-task-%
|
||||
aws-ec2-get-snap-size-import-snapshot-task-%: docker-build-aws
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval AWS_SNAP_SIZE := $(shell $(call aws,ec2 describe-import-snapshot-tasks --import-task-ids $* --output text --query ImportSnapshotTasks[0].SnapshotTaskDetail.DiskImageSize) 2>/dev/null))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
echo DiskImageSize: $(AWS_SNAP_SIZE)
|
||||
|
||||
.PHONY: aws-ec2-get-snap-status-import-snapshot-task-%
|
||||
aws-ec2-get-snap-status-import-snapshot-task-%: docker-build-aws
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval AWS_SNAP_STATUS := $(shell $(call aws,ec2 describe-import-snapshot-tasks --import-task-ids $* --output text --query ImportSnapshotTasks[0].SnapshotTaskDetail.Status) 2>/dev/null))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
echo Status: $(AWS_SNAP_STATUS)
|
||||
|
||||
.PHONY: aws-ec2-wait-snap-completed-import-snapshot-task
|
||||
aws-ec2-wait-snap-completed-import-snapshot-task: aws-ec2-wait-snap-completed-import-snapshot-task-$(AWS_TASK_ID)
|
||||
|
||||
.PHONY: aws-ec2-wait-snap-completed-import-snapshot-task-%
|
||||
aws-ec2-wait-snap-completed-import-snapshot-task-%: docker-build-aws
|
||||
while [ `$(call aws,ec2 describe-import-snapshot-tasks --import-task-ids $* --output text --query ImportSnapshotTasks[0].SnapshotTaskDetail.Status)` != "completed$$(printf '\r')" ]; \
|
||||
do \
|
||||
count=$$(( $${count:-0}+1 )); \
|
||||
[ "$${count}" -eq 99 ] && exit 1; \
|
||||
sleep 10; \
|
||||
done
|
||||
|
||||
.PHONY: aws-ec2-wait-snapshot-%
|
||||
aws-ec2-wait-snapshot-%: docker-build-aws
|
||||
$(call aws,ec2 wait snapshot-completed --snapshot-ids $* --output text)
|
||||
|
||||
.PHONY: aws-ec2-register-image
|
||||
aws-ec2-register-image: base docker-build-aws aws-ec2-get-snap-id-import-snapshot-task
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval json := $(shell $(call exec,envsubst < aws/register-image-device-mappings.json)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(eval AWS_AMI_ID := $(shell $(call aws,ec2 register-image --name '$(AWS_AMI_NAME)' --description '$(AWS_AMI_DESCRIPTION)' --architecture x86_64 --root-device-name /dev/sda1 --virtualization-type hvm --block-device-mappings '$(json)') 2>/dev/null))
|
||||
echo ImageId: $(AWS_AMI_ID)
|
||||
|
||||
.PHONY: aws-ami
|
||||
aws-ami: aws-s3-cp aws-ec2-import-snapshot
|
||||
$(call make,aws-ec2-wait-snap-completed-import-snapshot-task,,AWS_TASK_ID)
|
||||
$(call make,aws-ec2-register-image,,AWS_TASK_ID)
|
||||
@@ -0,0 +1,10 @@
|
||||
##
|
||||
# BOOTSTRAP
|
||||
|
||||
.PHONY: bootstrap-infra
|
||||
bootstrap-infra: setup-sysctl
|
||||
ifeq ($(SETUP_NFSD),true)
|
||||
ifeq ($(HOST_SYSTEM),DARWIN)
|
||||
$(call setup-nfsd-osx)
|
||||
endif
|
||||
endif
|
||||
@@ -0,0 +1,18 @@
|
||||
##
|
||||
# CLEAN
|
||||
|
||||
.PHONY: clean-docker-%
|
||||
clean-docker-%:
|
||||
docker ps -a |awk '$$NF ~ /_$*/ && $$NF !~ /_infra_/ {print $$NF}' |while read docker; do docker rm -f $$docker; done
|
||||
|
||||
.PHONY: clean-elasticsearch-%
|
||||
clean-elasticsearch-%:
|
||||
docker ps |awk '$$NF ~ /infra_elasticsearch/' |sed 's/^.*:\([0-9]*\)->9200\/tcp.*$$/\1/' |while read port; do echo -e "DELETE /$* HTTP/1.0\n\n" |nc localhost $$port; done
|
||||
|
||||
.PHONY: clean-images-%
|
||||
clean-images-%:
|
||||
docker images |awk '$$1 ~ /\/$*/ && $$1 !~ /\/infra\// {print $$3}' |sort -u |while read image; do docker rmi -f $$image; done
|
||||
|
||||
.PHONY: clean-volumes-%
|
||||
clean-volumes-%:
|
||||
docker volume ls |awk '$$2 ~ /_$*/ && $$2 !~ /_infra_/ {print $$2}' |sort -u |while read volume; do docker volume rm $$volume; done
|
||||
@@ -0,0 +1,50 @@
|
||||
ANSIBLE_AWS_ACCESS_KEY_ID ?= $(AWS_ACCESS_KEY_ID)
|
||||
ANSIBLE_AWS_DEFAULT_OUTPUT ?= $(AWS_DEFAULT_OUTPUT)
|
||||
ANSIBLE_AWS_DEFAULT_REGION ?= $(AWS_DEFAULT_REGION)
|
||||
ANSIBLE_AWS_SECRET_ACCESS_KEY ?= $(AWS_SECRET_ACCESS_KEY)
|
||||
ANSIBLE_CONFIG ?= ansible/ansible.cfg
|
||||
ANSIBLE_DISKS_NFS_DISK ?= $(NFS_DISK)
|
||||
ANSIBLE_DISKS_NFS_OPTIONS ?= $(NFS_OPTIONS)
|
||||
ANSIBLE_DISKS_NFS_PATH ?= $(NFS_PATH)
|
||||
ANSIBLE_DOCKER_IMAGE_TAG ?= $(DOCKER_IMAGE_TAG)
|
||||
ANSIBLE_DOCKER_REGISTRY ?= $(DOCKER_REGISTRY)
|
||||
ANSIBLE_EXTRA_VARS ?= target=localhost
|
||||
ANSIBLE_GIT_DIRECTORY ?= /src/$(subst git@,,$(subst ssh://,,$(GIT_REPOSITORY)))
|
||||
ANSIBLE_GIT_KEY_FILE ?= ~$(ANSIBLE_USERNAME)/.ssh/$(notdir $(ANSIBLE_SSH_PRIVATE_KEY))
|
||||
ANSIBLE_GIT_REPOSITORY ?= $(GIT_REPOSITORY)
|
||||
ANSIBLE_GIT_VERSION ?= $(BRANCH)
|
||||
ANSIBLE_INVENTORY ?= ansible/inventories
|
||||
ANSIBLE_PLAYBOOK ?= ansible/playbook.yml
|
||||
ANSIBLE_SSH_PRIVATE_KEY ?= ~/.ssh/id_rsa
|
||||
ANSIBLE_SERVER_NAME ?= $(SERVER_NAME)
|
||||
ANSIBLE_USERNAME ?= root
|
||||
ANSIBLE_VERBOSE ?= -v
|
||||
CMDS += ansible ansible-playbook
|
||||
ENV_VARS += ANSIBLE_AWS_ACCESS_KEY_ID ANSIBLE_AWS_DEFAULT_OUTPUT ANSIBLE_AWS_DEFAULT_REGION ANSIBLE_AWS_SECRET_ACCESS_KEY ANSIBLE_CONFIG ANSIBLE_DISKS_NFS_DISK ANSIBLE_DISKS_NFS_OPTIONS ANSIBLE_DISKS_NFS_PATH ANSIBLE_DOCKER_IMAGE_TAG ANSIBLE_DOCKER_REGISTRY ANSIBLE_EXTRA_VARS ANSIBLE_GIT_DIRECTORY ANSIBLE_GIT_KEY_FILE ANSIBLE_GIT_REPOSITORY ANSIBLE_GIT_VERSION ANSIBLE_INVENTORY ANSIBLE_PLAYBOOK ANSIBLE_SSH_PRIVATE_KEY ANSIBLE_USERNAME ANSIBLE_VERBOSE
|
||||
|
||||
ifeq ($(DEBUG), true)
|
||||
ANSIBLE_VERBOSE := -vvvv
|
||||
endif
|
||||
|
||||
ifeq ($(DOCKER), true)
|
||||
define ansible
|
||||
$(call run,$(DOCKER_SSH_AUTH) -v ~/.aws:/home/$(USER)/.aws --add-host=host.docker.internal:$(DOCKER_INTERNAL_DOCKER_HOST) $(DOCKER_REPOSITORY)/ansible:$(DOCKER_IMAGE_TAG) $(ANSIBLE_ARGS) -i $(ANSIBLE_INVENTORY)/.host.docker.internal $(ANSIBLE_VERBOSE) $(1))
|
||||
endef
|
||||
define ansible-playbook
|
||||
$(call run,$(DOCKER_SSH_AUTH) -v ~/.aws:/home/$(USER)/.aws --add-host=host.docker.internal:$(DOCKER_INTERNAL_DOCKER_HOST) --entrypoint=ansible-playbook $(DOCKER_REPOSITORY)/ansible:$(DOCKER_IMAGE_TAG) $(ANSIBLE_ARGS) -i $(ANSIBLE_INVENTORY)/.host.docker.internal $(ANSIBLE_VERBOSE) $(1))
|
||||
endef
|
||||
define ansible-pull
|
||||
# TODO : run ansible in docker and target localhost outside docker
|
||||
IFS=$$'\n'; $(ECHO) env $(foreach var,$(ENV_VARS),$(if $($(var)),$(var)='$($(var))')) $(shell printenv |awk -F '=' 'NR == FNR { if($$1 !~ /^(\#|$$)/) { A[$$1]; next } } ($$1 in A)' .env.dist - 2>/dev/null) $$(cat $(ENV_FILE) 2>/dev/null |awk -F "=" '$$1 ~! /^\(#|$$\)/') ansible-pull $(ANSIBLE_ARGS) $(ANSIBLE_VERBOSE) $(1)
|
||||
endef
|
||||
else
|
||||
define ansible
|
||||
$(call run,ansible $(ANSIBLE_ARGS) $(ANSIBLE_VERBOSE) $(1))
|
||||
endef
|
||||
define ansible-playbook
|
||||
$(call run,ansible-playbook $(ANSIBLE_ARGS) $(ANSIBLE_VERBOSE) $(1))
|
||||
endef
|
||||
define ansible-pull
|
||||
$(call run,ansible-pull $(ANSIBLE_ARGS) $(ANSIBLE_VERBOSE) $(1))
|
||||
endef
|
||||
endif
|
||||
@@ -0,0 +1,23 @@
|
||||
AWS_ACCESS_KEY_ID ?= $(shell $(call conf,$(HOME)/.aws/credentials,$(or $(AWS_PROFILE),default),aws_access_key_id))
|
||||
AWS_AMI_DESCRIPTION ?= app: $(APP) branch: $(BRANCH) env: $(ENV) iso: $(AWS_S3_KEY) user: $(USER) version: $(VERSION)
|
||||
AWS_AMI_NAME ?= $(USER)/$(ENV)/$(APP)/ami/$(VERSION)/$(shell date +%Y%m%dT%H%M%S)
|
||||
AWS_DEFAULT_REGION ?= eu-west-1
|
||||
AWS_DEFAULT_OUTPUT ?= text
|
||||
AWS_INSTANCE_ID ?= $(shell timeout 0.1 curl -s http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null)
|
||||
AWS_VM_IMPORT_ROLE_NAME ?= vmimport
|
||||
AWS_S3_BUCKET ?= $(USER)-$(ENV)-config
|
||||
AWS_S3_KEY ?= $(PACKER_ISO_FILE)
|
||||
AWS_SECRET_ACCESS_KEY ?= $(shell $(call conf,$(HOME)/.aws/credentials,$(or $(AWS_PROFILE),default),aws_secret_access_key))
|
||||
AWS_SNAP_DESCRIPTION ?= iso: $(AWS_S3_KEY) env: $(ENV) app: $(APP) branch: $(BRANCH) version: $(VERSION) user: $(USER) etag: $(AWS_S3_KEY_ETAG) date: $(AWS_S3_KEY_DATE)
|
||||
CMDS += aws
|
||||
ENV_VARS += AWS_ACCESS_KEY_ID AWS_AMI_DESCRIPTION AWS_AMI_NAME AWS_DEFAULT_OUTPUT AWS_DEFAULT_REGION AWS_INSTANCE_ID AWS_PROFILE AWS_S3_BUCKET AWS_S3_KEY AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_SNAP_DESCRIPTION AWS_SNAP_ID
|
||||
|
||||
ifeq ($(DOCKER), true)
|
||||
define aws
|
||||
$(call run,$(DOCKER_SSH_AUTH) -v $$HOME/.aws:/root/.aws:ro anigeo/awscli:latest $(1))
|
||||
endef
|
||||
else
|
||||
define aws
|
||||
$(call run,aws $(1))
|
||||
endef
|
||||
endif
|
||||
@@ -0,0 +1,36 @@
|
||||
CMDS += openstack ssh-run terraform
|
||||
COMPOSE_IGNORE_ORPHANS ?= true
|
||||
CONTEXT += GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
|
||||
DOCKER_BUILD_VARS += SSH_BASTION_HOSTNAME SSH_BASTION_USERNAME SSH_PUBLIC_HOST_KEYS SSH_PRIVATE_IP_RANGE
|
||||
DOCKER_SERVICE ?= cli
|
||||
ELASTICSEARCH_HOST ?= elasticsearch
|
||||
ELASTICSEARCH_PORT ?= 9200
|
||||
ELASTICSEARCH_PROTOCOL ?= http
|
||||
ENV_VARS += COMPOSE_IGNORE_ORPHANS DOCKER_IMAGE_CLI DOCKER_IMAGE_SSH DOCKER_NAME_CLI DOCKER_NAME_SSH ELASTICSEARCH_HOST ELASTICSEARCH_PASSWORD ELASTICSEARCH_PORT ELASTICSEARCH_PROTOCOL ELASTICSEARCH_USERNAME GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME SETUP_SYSCTL_CONFIG SSH_BASTION_HOSTNAME SSH_BASTION_USERNAME SSH_PUBLIC_HOST_KEYS SSH_PRIVATE_IP_RANGE
|
||||
GIT_AUTHOR_EMAIL ?= $(shell git config user.email 2>/dev/null)
|
||||
GIT_AUTHOR_NAME ?= $(shell git config user.name 2>/dev/null)
|
||||
HOME ?= /home/$(USER)
|
||||
NFS_DISK ?= $(NFS_HOST):/$(SHARED)
|
||||
NFS_OPTIONS ?= rw,rsize=8192,wsize=8192,bg,hard,intr,nfsvers=3,noatime,nodiratime,actimeo=3
|
||||
NFS_PATH ?= /srv/$(subst :,,$(NFS_DISK))
|
||||
SETUP_NFSD ?= false
|
||||
SETUP_NFSD_OSX_CONFIG ?= nfs.server.bonjour=0 nfs.server.mount.regular_files=1 nfs.server.mount.require_resv_port=0 nfs.server.nfsd_threads=16 nfs.server.async=1
|
||||
SETUP_SYSCTL ?= false
|
||||
SETUP_SYSCTL_CONFIG ?= vm.max_map_count=262144 vm.overcommit_memory=1 fs.file-max=8388608 net.core.somaxconn=1024
|
||||
SHELL ?= /bin/sh
|
||||
SSH_BASTION_HOSTNAME ?=
|
||||
SSH_BASTION_USERNAME ?=
|
||||
SSH_PUBLIC_HOST_KEYS ?= $(SSH_REMOTE_HOSTS) $(SSH_BASTION_HOSTNAME)
|
||||
SSH_PRIVATE_IP_RANGE ?= 10.10.*
|
||||
SSH_REMOTE_HOSTS ?= github.com gitlab.com
|
||||
STACK ?= base logs services
|
||||
|
||||
define setup-nfsd-osx
|
||||
$(eval dir:=$(or $(1),$(MONOREPO_DIR)))
|
||||
$(eval uid:=$(or $(2),$(UID)))
|
||||
$(eval gid:=$(or $(3),$(GID)))
|
||||
grep "$(dir)" /etc/exports >/dev/null 2>&1 || echo "$(dir) -alldirs -mapall=$(uid):$(gid) localhost" |sudo tee -a /etc/exports >/dev/null
|
||||
$(foreach config,$(SETUP_NFSD_OSX_CONFIG),grep "$(config)" /etc/nfs.conf >/dev/null 2>&1 || echo "$(config)" |sudo tee -a /etc/nfs.conf >/dev/null &&) true
|
||||
nfsd status >/dev/null || sudo nfsd enable
|
||||
showmount -e localhost |grep "$(dir)" >/dev/null 2>&1 || sudo nfsd restart
|
||||
endef
|
||||
@@ -0,0 +1,17 @@
|
||||
ENV_VARS += OS_AUTH_URL OS_TENANT_ID OS_TENANT_NAME OS_USERNAME OS_PASSWORD OS_REGION_NAME OS_USER_DOMAIN_NAME OS_PROJECT_DOMAIN_NAME
|
||||
ifeq ($(DEBUG), true)
|
||||
OPENSTACK_ARGS += --debug
|
||||
endif
|
||||
ifeq ($(ENV), local)
|
||||
OPENSTACK_ARGS += -v
|
||||
endif
|
||||
|
||||
ifeq ($(DOCKER), true)
|
||||
define openstack
|
||||
$(call run,$(DOCKER_SSH_AUTH) $(DOCKER_REPOSITORY)/openstack:$(DOCKER_IMAGE_TAG) $(1))
|
||||
endef
|
||||
else
|
||||
define openstack
|
||||
$(call run,openstack $(1))
|
||||
endef
|
||||
endif
|
||||
@@ -0,0 +1,6 @@
|
||||
PACKER_ALPINE_ARCH ?= x86_64
|
||||
PACKER_ALPINE_RELEASE ?= 3.12.0
|
||||
PACKER_BUILD_VARS += alpine_arch alpine_release alpine_version
|
||||
alpine_arch ?= $(PACKER_ALPINE_ARCH)
|
||||
alpine_release ?= $(PACKER_ALPINE_RELEASE)
|
||||
alpine_version ?= $(subst $(eval) ,.,$(wordlist 1, 2, $(subst ., ,$(alpine_release))))
|
||||
@@ -0,0 +1,4 @@
|
||||
PACKER_BUILD_VARS += ansible_extra_vars ansible_user ansible_verbose
|
||||
ansible_extra_vars ?= $(patsubst target=%,target=default,$(ANSIBLE_EXTRA_VARS))
|
||||
ansible_user ?= $(ANSIBLE_USERNAME)
|
||||
ansible_verbose ?= $(ANSIBLE_VERBOSE)
|
||||
@@ -0,0 +1,126 @@
|
||||
CMDS += packer
|
||||
ENV_VARS += PACKER_CACHE_DIR PACKER_KEY_INTERVAL PACKER_LOG
|
||||
KVM_GID ?= $(call getent-group,kvm)
|
||||
PACKER_ARCH ?= $(PACKER_ALPINE_ARCH)
|
||||
PACKER_BOOT_WAIT ?= 11s
|
||||
PACKER_BUILD_ARGS ?= -on-error=cleanup $(foreach var,$(PACKER_BUILD_VARS),$(if $($(var)),-var $(var)='$($(var))'))
|
||||
PACKER_BUILD_VARS += accelerator boot_wait hostname iso_name iso_size output password qemuargs ssh_wait_timeout template username
|
||||
PACKER_CACHE_DIR ?= build/cache
|
||||
PACKER_HOSTNAME ?= $(PACKER_TEMPLATE)
|
||||
PACKER_ISO_DATE ?= $(shell stat -c %y $(PACKER_ISO_FILE) 2>/dev/null)
|
||||
PACKER_ISO_FILES ?= $(wildcard build/iso/*/*/*.iso)
|
||||
PACKER_ISO_FILE = $(PACKER_OUTPUT)/$(PACKER_ISO_NAME).iso
|
||||
PACKER_ISO_INFO = $(PACKER_OUTPUT)/$(PACKER_ISO_NAME).nfo
|
||||
PACKER_ISO_NAME = $(PACKER_TEMPLATE)-$(PACKER_RELEASE)-$(PACKER_ARCH)
|
||||
PACKER_ISO_SIZE ?= 1024
|
||||
PACKER_KEY_INTERVAL ?= 10ms
|
||||
PACKER_LOG ?= 1
|
||||
PACKER_OUTPUT ?= build/iso/$(ENV)/$(PACKER_TEMPLATE)/$(PACKER_RELEASE)-$(PACKER_ARCH)
|
||||
PACKER_PASSWORD ?= $(PACKER_TEMPLATE)
|
||||
PACKER_QEMU_ACCELERATOR ?= kvm
|
||||
PACKER_QEMU_ARCH ?= $(PACKER_ARCH)
|
||||
PACKER_QEMU_ARGS ?= -machine type=pc,accel=$(PACKER_QEMU_ACCELERATOR) -device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x7 -object rng-random,filename=/dev/urandom,id=rng0
|
||||
PACKER_RELEASE ?= $(PACKER_ALPINE_RELEASE)
|
||||
PACKER_SSH_ADDRESS ?= $(if $(ssh_bind_address),$(ssh_bind_address),0.0.0.0)
|
||||
PACKER_SSH_PORT ?= $(if $(ssh_port_max),$(ssh_port_max),2222)
|
||||
PACKER_SSH_WAIT_TIMEOUT ?= 42s
|
||||
PACKER_TEMPLATES ?= $(wildcard packer/*/*.json)
|
||||
PACKER_TEMPLATE ?= alpine
|
||||
PACKER_USERNAME ?= root
|
||||
PACKER_VNC_PORT ?= $(if $(vnc_port_max),$(vnc_port_max),5900)
|
||||
PACKER_VNC_ADDRESS ?= $(if $(vnc_bind_address),$(vnc_bind_address),0.0.0.0)
|
||||
ifeq ($(DEBUG), true)
|
||||
PACKER_BUILD_ARGS += -debug
|
||||
endif
|
||||
ifeq ($(FORCE), true)
|
||||
PACKER_BUILD_ARGS += -force
|
||||
endif
|
||||
ifeq ($(ENV), local)
|
||||
PACKER_BUILD_ARGS += -var ssh_port_max=$(PACKER_SSH_PORT) -var vnc_port_max=$(PACKER_VNC_PORT) -var vnc_bind_address=$(PACKER_VNC_ADDRESS)
|
||||
endif
|
||||
|
||||
accelerator ?= $(PACKER_QEMU_ACCELERATOR)
|
||||
boot_wait ?= $(PACKER_BOOT_WAIT)
|
||||
hostname ?= $(PACKER_HOSTNAME)
|
||||
iso_name ?= $(PACKER_ISO_NAME)
|
||||
iso_size ?= $(PACKER_ISO_SIZE)
|
||||
output ?= $(PACKER_OUTPUT)
|
||||
password ?= $(PACKER_PASSWORD)
|
||||
qemuargs ?= $(call arrays_of_dquoted_args, $(PACKER_QEMU_ARGS))
|
||||
ssh_wait_timeout ?= $(PACKER_SSH_WAIT_TIMEOUT)
|
||||
template ?= $(PACKER_TEMPLATE)
|
||||
username ?= $(PACKER_USERNAME)
|
||||
|
||||
ifneq ($(filter $(ENV),$(ENV_DEPLOY)),)
|
||||
ifeq ($(password), $(template))
|
||||
password := $(or $(shell pwgen -csy -r\' 64 1 2>/dev/null),$(shell date +%s | shasum -a 256 2>/dev/null | base64 | head -c 64))
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HOST_SYSTEM),DARWIN)
|
||||
ifneq ($(DOCKER), true)
|
||||
PACKER_QEMU_ACCELERATOR := hvf
|
||||
else
|
||||
PACKER_QEMU_ACCELERATOR := tcg
|
||||
PACKER_QEMU_ARGS += -cpu max,vendor=GenuineIntel,vmware-cpuid-freq=on,+invtsc,+aes,+vmx
|
||||
endif
|
||||
else ifeq ($(HOST_SYSTEM),LINUX)
|
||||
DOCKER_RUN_OPTIONS_PACKER := $(if $(KVM_GID),--group-add $(KVM_GID)) --device /dev/kvm
|
||||
else ifeq ($(HOST_SYSTEM),WINDOWS)
|
||||
PACKER_QEMU_ACCELERATOR := hax
|
||||
endif
|
||||
|
||||
ifeq ($(DOCKER), true)
|
||||
|
||||
# packer ansible provisionner needs:
|
||||
## empty local ssh agent (ssh-add -D)
|
||||
## ANSIBLE_SSH_PRIVATE_KEY set to a key giving access to ANSIBLE_GIT_REPOSITORY without password
|
||||
## ANSIBLE_AWS_ACCESS_KEY_ID and ANSIBLE_AWS_SECRET_ACCESS_KEY
|
||||
define packer
|
||||
$(call run,$(DOCKER_RUN_OPTIONS_PACKER) $(DOCKER_SSH_AUTH) -p $(PACKER_SSH_PORT):$(PACKER_SSH_PORT) -p $(PACKER_VNC_PORT):$(PACKER_VNC_PORT) $(DOCKER_REPOSITORY)/packer:$(DOCKER_IMAGE_TAG) $(1))
|
||||
endef
|
||||
define packer-qemu
|
||||
echo Running $(1)
|
||||
$(call run,$(DOCKER_RUN_OPTIONS_PACKER) -p $(PACKER_SSH_PORT):$(PACKER_SSH_PORT) -p $(PACKER_VNC_PORT):$(PACKER_VNC_PORT) --entrypoint=qemu-system-$(PACKER_QEMU_ARCH) $(DOCKER_REPOSITORY)/packer:$(DOCKER_IMAGE_TAG) $(PACKER_QEMU_ARGS) -m 512m -drive file=$(1)$(comma)format=raw -net nic$(comma)model=virtio -net user$(comma)hostfwd=tcp:$(PACKER_SSH_ADDRESS):$(PACKER_SSH_PORT)-:22 -vnc $(PACKER_VNC_ADDRESS):$(subst 590,,$(PACKER_VNC_PORT)))
|
||||
endef
|
||||
|
||||
else
|
||||
|
||||
define packer
|
||||
$(call run,packer $(1))
|
||||
endef
|
||||
define packer-qemu
|
||||
echo Running $(1)
|
||||
$(call run,qemu-system-$(PACKER_QEMU_ARCH) $(PACKER_QEMU_ARGS) -m 512m -drive file=$(1)$(comma)format=raw -net nic$(comma)model=virtio -net user$(comma)hostfwd=tcp:$(PACKER_SSH_ADDRESS):$(PACKER_SSH_PORT)-:22 -vnc $(PACKER_VNC_ADDRESS):$(subst 590,,$(PACKER_VNC_PORT)))
|
||||
endef
|
||||
|
||||
endif
|
||||
|
||||
define packer-build
|
||||
$(eval PACKER_TEMPLATE := $(notdir $(basename $(1))))
|
||||
echo Building $(PACKER_ISO_FILE)
|
||||
$(call packer,build $(PACKER_BUILD_ARGS) $(1))
|
||||
echo 'aws_id: $(ANSIBLE_AWS_ACCESS_KEY_ID)' > $(PACKER_ISO_INFO)
|
||||
echo 'aws_key: $(ANSIBLE_AWS_SECRET_ACCESS_KEY)' >> $(PACKER_ISO_INFO)
|
||||
echo 'aws_region: $(ANSIBLE_AWS_DEFAULT_REGION)' >> $(PACKER_ISO_INFO)
|
||||
echo 'docker_image_tag: $(ANSIBLE_DOCKER_IMAGE_TAG)' >> $(PACKER_ISO_INFO)
|
||||
echo 'docker_registry: $(ANSIBLE_DOCKER_REGISTRY)' >> $(PACKER_ISO_INFO)
|
||||
echo 'env: $(ENV)' >> $(PACKER_ISO_INFO)
|
||||
echo 'file: $(PACKER_ISO_FILE)' >> $(PACKER_ISO_INFO)
|
||||
echo 'git_branch: $(ANSIBLE_GIT_VERSION)' >> $(PACKER_ISO_INFO)
|
||||
echo 'git_repository: $(ANSIBLE_GIT_REPOSITORY)' >> $(PACKER_ISO_INFO)
|
||||
echo 'git_version: $(VERSION)' >> $(PACKER_ISO_INFO)
|
||||
echo 'host: $(hostname)' >> $(PACKER_ISO_INFO)
|
||||
echo 'link: s3://$(AWS_S3_BUCKET)/$(AWS_S3_KEY)' >> $(PACKER_ISO_INFO)
|
||||
echo 'name: $(iso_name)' >> $(PACKER_ISO_INFO)
|
||||
echo 'nfs_disk: $(ANSIBLE_DISKS_NFS_DISK)' >> $(PACKER_ISO_INFO)
|
||||
echo 'nfs_path: $(ANSIBLE_DISKS_NFS_PATH)' >> $(PACKER_ISO_INFO)
|
||||
echo 'pass: $(password)' >> $(PACKER_ISO_INFO)
|
||||
echo 'size: $(iso_size)' >> $(PACKER_ISO_INFO)
|
||||
echo 'ssh_key: $(ANSIBLE_SSH_PRIVATE_KEY)' >> $(PACKER_ISO_INFO)
|
||||
echo 'user: $(username)' >> $(PACKER_ISO_INFO)
|
||||
endef
|
||||
|
||||
define arrays_of_dquoted_args
|
||||
[ $(subst $(dquote) $(dquote),$(dquote)$(comma) $(dquote),$(subst $(dquote) $(dquote)-,$(dquote) ]$(comma) [ $(dquote)-,$(patsubst %,$(dquote)%$(dquote),$1))) ]
|
||||
endef
|
||||
@@ -0,0 +1,14 @@
|
||||
define ssh-connect
|
||||
$(eval hosts := $(1))
|
||||
$(eval command := $(2))
|
||||
$(eval user := $(or $(3),root))
|
||||
$(eval DOCKER_EXEC_OPTIONS := -it)
|
||||
$(foreach host,$(hosts),$(call exec,ssh -t -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $(user)@$(host) "$(command)") ||) true
|
||||
endef
|
||||
|
||||
define ssh-exec
|
||||
$(eval hosts := $(1))
|
||||
$(eval command := $(2))
|
||||
$(eval user := $(or $(3),root))
|
||||
$(foreach host,$(hosts),$(call exec,ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $(user)@$(host) "$(command)") &&) true
|
||||
endef
|
||||
@@ -0,0 +1,21 @@
|
||||
CMDS += terraform
|
||||
|
||||
ifeq ($(DOCKER), true)
|
||||
|
||||
# packer ansible provisionner needs:
|
||||
## empty local ssh agent (ssh-add -D)
|
||||
## ANSIBLE_SSH_PRIVATE_KEY set to a key giving access to ANSIBLE_GIT_REPOSITORY without password
|
||||
## ANSIBLE_AWS_ACCESS_KEY_ID and ANSIBLE_AWS_SECRET_ACCESS_KEY
|
||||
define terraform
|
||||
$(call run,hashicorp/terraform:light $(1))
|
||||
endef
|
||||
|
||||
else
|
||||
|
||||
define terraform
|
||||
$(call run,terraform $(1))
|
||||
endef
|
||||
|
||||
endif
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
##
|
||||
# INFRA
|
||||
|
||||
.PHONY: setup-sysctl
|
||||
setup-sysctl:
|
||||
ifeq ($(SETUP_SYSCTL),true)
|
||||
$(call docker-run,--privileged alpine:latest,/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled ||:' >/dev/null)
|
||||
$(foreach config,$(SETUP_SYSCTL_CONFIG),$(call docker-run,--privileged alpine:latest,sysctl -q -w $(config)) &&) true
|
||||
endif
|
||||
|
||||
.PHONY: start-up
|
||||
start-up: base-ssh-add
|
||||
@@ -0,0 +1,7 @@
|
||||
.PHONY: openstack
|
||||
openstack: docker-build-openstack
|
||||
$(call openstack,$(ARGS))
|
||||
|
||||
.PHONY: openstack-image-create
|
||||
openstack-image-create: $(PACKER_ISO_FILE) docker-build-openstack
|
||||
$(call openstack,$(OPENSTACK_ARGS) image create --disk-format raw --container-format bare --file $(PACKER_ISO_FILE) "$(PACKER_ISO_NAME)")
|
||||
@@ -0,0 +1,36 @@
|
||||
.PHONY: packer
|
||||
packer:
|
||||
$(call packer,$(ARGS))
|
||||
|
||||
$(PACKER_ISO_FILE):
|
||||
$(eval FORCE := true)
|
||||
$(call make,packer-build,,FORCE)
|
||||
|
||||
.PHONY: packer-build
|
||||
packer-build: packer-build-$(PACKER_TEMPLATE) ## Build default packer template
|
||||
|
||||
.PHONY: packer-build-templates
|
||||
packer-build-templates: $(PACKER_TEMPLATES) ## Build all packer templates
|
||||
|
||||
.PHONY: $(PACKER_TEMPLATES)
|
||||
ifeq ($(HOST_SYSTEM),DARWIN)
|
||||
$(PACKER_TEMPLATES): DOCKER ?= false
|
||||
endif
|
||||
$(PACKER_TEMPLATES):
|
||||
$(call packer-build,$@)
|
||||
|
||||
.PHONY: packer-build-%
|
||||
packer-build-%: docker-build-packer
|
||||
$(if $(wildcard packer/*/$*.json),\
|
||||
$(call packer-build,$(wildcard packer/*/$*.json)))
|
||||
|
||||
.PHONY: packer-qemu
|
||||
packer-qemu: packer-qemu-$(PACKER_ISO_NAME) ## Launch iso image in qemu
|
||||
|
||||
.PHONY: packer-qemu-%
|
||||
ifeq ($(HOST_SYSTEM),DARWIN)
|
||||
packer-qemu-%: DOCKER ?= false
|
||||
endif
|
||||
packer-qemu-%: docker-build-packer ## Run iso image in qemu
|
||||
$(if $(wildcard $(PACKER_OUTPUT)/$*.iso),\
|
||||
$(call packer-qemu,$(wildcard $(PACKER_OUTPUT)/$*.iso)))
|
||||
@@ -0,0 +1,18 @@
|
||||
##
|
||||
# SSH
|
||||
|
||||
.PHONY: ssh
|
||||
ssh: aws-ec2-get-PrivateIpAddress-$(SERVER_NAME)
|
||||
$(call ssh-connect,$(AWS_INSTANCE_IP),$(SHELL))
|
||||
|
||||
.PHONY: ssh-connect
|
||||
ssh-connect: aws-ec2-get-PrivateIpAddress-$(SERVER_NAME)
|
||||
$(call ssh-connect,$(AWS_INSTANCE_IP),make connect $(if $(SERVICE),SERVICE=$(SERVICE)))
|
||||
|
||||
.PHONY: ssh-exec
|
||||
ssh-exec: aws-ec2-get-PrivateIpAddress-$(SERVER_NAME)
|
||||
$(call ssh-exec,$(AWS_INSTANCE_IP),make exec $(if $(SERVICE),SERVICE=$(SERVICE)) $(if $(ARGS),ARGS='\''"$(ARGS)"'\''))
|
||||
|
||||
.PHONY: ssh-run
|
||||
ssh-run: aws-ec2-get-PrivateIpAddress-$(SERVER_NAME)
|
||||
$(call ssh-exec,$(AWS_INSTANCE_IP),make run $(if $(SERVICE),SERVICE=$(SERVICE)) $(if $(ARGS),ARGS='\''"$(ARGS)"'\''))
|
||||
@@ -0,0 +1,4 @@
|
||||
.PHONY: terraform
|
||||
terraform:
|
||||
$(call terraform,$(ARGS))
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
##
|
||||
# INSTALL
|
||||
|
||||
.PHONY: install app-install
|
||||
install: app-install ## Install application
|
||||
|
||||
.PHONY: install-mysql-database-%
|
||||
install-mysql-database-%: infra-base
|
||||
$(call exec,mysql -h mysql -u root -proot $* -e "use $*" >/dev/null 2>&1 || mysql -h mysql -u root -proot mysql -e "create database $* character set utf8 collate utf8_unicode_ci;")
|
||||
$(call exec,mysql -h mysql -u $* -p$* $* -e "use $*" >/dev/null 2>&1 || mysql -h mysql -u root -proot mysql -e "grant all privileges on $*.* to '\''$*'\''@'\''%'\'' identified by '\''$*'\''; flush privileges;")
|
||||
$(call exec,[ $$(mysql -h mysql -u $* -p$* $* -e "show tables" 2>/dev/null |wc -l) -eq 0 ] && [ -f "${APP_DIR}/$*.mysql.gz" ] && gzip -cd "${APP_DIR}/$*.mysql.gz" |mysql -h mysql -u root -proot $* || true)
|
||||
|
||||
.PHONY: install-pgsql-database-%
|
||||
install-pgsql-database-%: infra-base
|
||||
$(call exec,PGPASSWORD=$* psql -h postgres -U $* template1 -c "\q" >/dev/null 2>&1 || PGPASSWORD=postgres psql -h postgres -U postgres -c "create user $* with createdb password '\''$*'\'';")
|
||||
$(call exec,PGPASSWORD=$* psql -h postgres -U $* -d $* -c "" >/dev/null 2>&1 || PGPASSWORD=postgres psql -h postgres -U postgres -c "create database $* owner $* ;")
|
||||
$(call exec,[ $$(PGPASSWORD=$* psql -h postgres -U $* -d $* -c "\d" 2>/dev/null |wc -l) -eq 0 ] && [ -f "${APP_DIR}/$*.pgsql.gz" ] && gzip -cd "${APP_DIR}/$*.pgsql.gz" |PGPASSWORD="postgres" psql -h postgres -U postgres -d $* || true)
|
||||
$(call exec,[ $$(PGPASSWORD=$* psql -h postgres -U $* -d $* -c "\d" 2>/dev/null |wc -l) -eq 0 ] && [ -f "${APP_DIR}/$*.pgsql" ] && PGPASSWORD="postgres" psql -h postgres -U postgres -c "ALTER ROLE $* WITH SUPERUSER" && PGPASSWORD="postgres" pg_restore -h postgres --no-owner --role=$* -U postgres -d $* ${APP_DIR}/$*.pgsql && PGPASSWORD="postgres" psql -h postgres -U postgres -c "ALTER ROLE $* WITH NOSUPERUSER" || true)
|
||||
|
||||
.PHONY: install-infra
|
||||
install-infra: infra-install
|
||||
|
||||
.PHONY: install-parameters
|
||||
install-parameters:
|
||||
$(call install-parameters)
|
||||
|
||||
.PHONY: install-parameters-%
|
||||
install-parameters-%:
|
||||
$(call install-parameters,$*)
|
||||
@@ -0,0 +1,9 @@
|
||||
##
|
||||
# CLEAN
|
||||
|
||||
.PHONY: clean-js-app
|
||||
clean-js-app: clean-js-assets-deps
|
||||
|
||||
.PHONY: clean-js-assets-deps
|
||||
clean-js-assets-deps: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -Rf node_modules/*)
|
||||
@@ -0,0 +1,21 @@
|
||||
##
|
||||
# DEV
|
||||
|
||||
## Build assets
|
||||
.PHONY: dev-assets
|
||||
dev-assets: ## Build assets
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn build:dev:watch)
|
||||
|
||||
.PHONY: dev-outdated
|
||||
dev-outdated:
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn outdated)
|
||||
|
||||
# compile webpack assets (REACT)
|
||||
.PHONY: dev-webpack-compile
|
||||
dev-webpack-compile: bootstrap ## Compile dev assets
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn encore dev)
|
||||
|
||||
# watch webpack assets updates (REACT)
|
||||
.PHONY: dev-webpack-watch
|
||||
dev-webpack-watch: bootstrap ## Watch dev assets update
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn encore dev --watch)
|
||||
@@ -0,0 +1,22 @@
|
||||
##
|
||||
# INSTALL
|
||||
|
||||
.PHONY: install-bower
|
||||
install-bower: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),npm install bower --allow-root)
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),./node_modules/bower/bin/bower install --allow-root)
|
||||
|
||||
.PHONY: install-npm
|
||||
install-npm: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),npm install)
|
||||
|
||||
.PHONY: install-npm-run-build
|
||||
install-npm-run-build: install-npm-run-build-$(SYMFONY_ENV)
|
||||
|
||||
.PHONY: install-npm-run-build-%
|
||||
install-npm-run-build-%: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),npm run build:$*)
|
||||
|
||||
.PHONY: install-yarn
|
||||
install-yarn: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn install)
|
||||
@@ -0,0 +1,17 @@
|
||||
##
|
||||
# TEST
|
||||
|
||||
.PHONY: test-assets
|
||||
test-assets: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn test)
|
||||
|
||||
## Run functional tests (make test-func TEST="S01-U1-find-product")
|
||||
.PHONY: test-func-js
|
||||
test-func-js: bootstrap ## Run functional tests (js)
|
||||
ifdef TEST
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn test:func -- --test tests/Functional/specs/$(TEST).js --env $(TESTENV))
|
||||
else ifdef TESTSUITE
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn test:func -- --tag $(TESTSUITE) --env $(TESTENV))
|
||||
else
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn test:func -- --env $(TESTENV))
|
||||
endif
|
||||
@@ -0,0 +1,6 @@
|
||||
##
|
||||
# UPDATE
|
||||
|
||||
.PHONY: update-npm
|
||||
update-npm: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),npm upgrade)
|
||||
@@ -0,0 +1,23 @@
|
||||
##
|
||||
# CACHE
|
||||
|
||||
## Clear symfony cache
|
||||
.PHONY: cache-clear
|
||||
cache-clear: cache-clear-dev cache-clear-prod
|
||||
|
||||
.PHONY: cache-clear-%
|
||||
cache-clear-%: bootstrap ## Clear symfony cache
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),app/console cache:clear --env=$*)
|
||||
|
||||
.PHONY: cache-rm
|
||||
cache-rm: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -Rf app/cache/* app/logs/*)
|
||||
$(if $(filter $(ENV),$(ENV_DEPLOY)),$(call docker-compose-exec,$(DOCKER_SERVICE),chown www-data app/cache/ app/logs/))
|
||||
|
||||
.PHONY: cache-warmup
|
||||
cache-warmup: cache-warmup-$(SYMFONY_ENV)
|
||||
$(if $(filter $(ENV),$(ENV_DEPLOY)),$(call docker-compose-exec,$(DOCKER_SERVICE),chown -R www-data app/cache/ app/logs/))
|
||||
|
||||
.PHONY: cache-warmup-%
|
||||
cache-warmup-%: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),app/console cache:warmup --env=$*)
|
||||
@@ -0,0 +1,12 @@
|
||||
##
|
||||
# CLEAN
|
||||
|
||||
.PHONY: clean-php-app
|
||||
clean-php-app: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf app/bootstrap.php.cache)
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf app/cache/* app/cach~)
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf app/logs/*)
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf var/cache/* var/cach~)
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf var/logs/*)
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf vendor/*)
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf node_modules/*)
|
||||
@@ -0,0 +1,24 @@
|
||||
COMPOSER_ARGS ?= --optimize-autoloader
|
||||
COMPOSER_MEMORY_LIMIT ?= -1
|
||||
CONTEXT += COMPOSER_ARGS
|
||||
|
||||
ifeq ($(SYMFONY_ENV), prod)
|
||||
COMPOSER_ARGS += --classmap-authoritative --prefer-dist --no-dev --no-interaction
|
||||
endif
|
||||
ifeq ($(DRONE), true)
|
||||
COMPOSER_ARGS += --no-progress
|
||||
endif
|
||||
|
||||
define composer
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),COMPOSER_MEMORY_LIMIT=$(COMPOSER_MEMORY_LIMIT) SYMFONY_ENV=$(SYMFONY_ENV) composer $(1) $(COMPOSER_ARGS))
|
||||
endef
|
||||
|
||||
define composer-require-vendor-binary
|
||||
$(eval vendor:=$(1))
|
||||
$(eval binary:=$(or $(2),$(lastword $(subst /, ,$(vendor)))))
|
||||
$(eval version:=$(or $(addprefix :,$(3)),$(shell awk '/'$(subst /,\\/,$(vendor))'/ {gsub("[\",]","",$$2); print ":"$$2}' composer.json 2>/dev/null)))
|
||||
$(eval DRYRUN_IGNORE := true)
|
||||
$(eval COMPOSER_REQUIRE := $(shell $(call docker-compose-exec,$(DOCKER_SERVICE),[ -f vendor/$(vendor)/$(binary) ] || echo true)))
|
||||
$(eval DRYRUN_IGNORE := false)
|
||||
$(if $(COMPOSER_REQUIRE),$(call docker-compose-exec,$(DOCKER_SERVICE),mkdir -p vendor/$(vendor) && cd /tmp && COMPOSER_MEMORY_LIMIT=$(COMPOSER_MEMORY_LIMIT) SYMFONY_ENV=$(SYMFONY_ENV) composer require "$(vendor)$(version)" --prefer-source --no-interaction --dev && cd - && ln -s /tmp/vendor/$(vendor)/$(binary) vendor/$(vendor)/$(binary)))
|
||||
endef
|
||||
@@ -0,0 +1,8 @@
|
||||
BUILD_APP_VARS += SYMFONY_ENV
|
||||
DOCKER_SERVICE ?= php
|
||||
|
||||
ifneq (,$(filter $(ENV),$(ENV_DEPLOY)))
|
||||
SYMFONY_ENV ?= prod
|
||||
else
|
||||
SYMFONY_ENV ?= dev
|
||||
endif
|
||||
@@ -0,0 +1,10 @@
|
||||
##
|
||||
# DEV
|
||||
|
||||
.PHONY: dev-phpcs
|
||||
dev-phpcs: bootstrap install-phpcs
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpcs --standard=PSR2 --colors -p ./src)
|
||||
|
||||
.PHONY: dev-phpcbf
|
||||
dev-phpcbf: bootstrap install-phpcbf
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpcbf ./src/ --ignore=*.js)
|
||||
@@ -0,0 +1,43 @@
|
||||
##
|
||||
# INSTALL
|
||||
|
||||
.PHONY: install-assets
|
||||
install-assets: install-assets-$(SYMFONY_ENV)
|
||||
|
||||
.PHONY: install-assets-%
|
||||
install-assets-%: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),app/console assetic:dump --env=$*)
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),app/console assets:install --env=$*)
|
||||
$(if $(filter $(ENV),$(ENV_DEPLOY)),$(call docker-compose-exec,$(DOCKER_SERVICE),chown -R www-data web/bundles/ web/css/ web/js/))
|
||||
|
||||
.PHONY: install-codecept
|
||||
install-codecept: bootstrap install-phpunit vendor/codeception/codeception/codecept
|
||||
|
||||
vendor/codeception/codeception/codecept:
|
||||
$(call composer-require-vendor-binary,codeception/codeception,codecept)
|
||||
|
||||
.PHONY: install-composer
|
||||
install-composer: bootstrap
|
||||
$(call composer,install)
|
||||
|
||||
.PHONY: install-doctrine-schema-update
|
||||
install-doctrine-schema-update: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),php app/console doctrine:schema:update --force)
|
||||
|
||||
.PHONY: install-phpcbf
|
||||
install-phpcbf: bootstrap vendor/squizlabs/php_codesniffer/bin/phpcbf
|
||||
|
||||
vendor/squizlabs/php_codesniffer/bin/phpcbf:
|
||||
$(call composer-require-vendor-binary,squizlabs/php_codesniffer,bin/phpcbf)
|
||||
|
||||
.PHONY: install-phpcs
|
||||
install-phpcs: bootstrap vendor/squizlabs/php_codesniffer/bin/phpcs
|
||||
|
||||
vendor/squizlabs/php_codesniffer/bin/phpcs:
|
||||
$(call composer-require-vendor-binary,squizlabs/php_codesniffer,bin/phpcs)
|
||||
|
||||
.PHONY: install-phpunit
|
||||
install-phpunit: bootstrap vendor/phpunit/phpunit/phpunit
|
||||
|
||||
vendor/phpunit/phpunit/phpunit:
|
||||
$(call composer-require-vendor-binary,phpunit/phpunit)
|
||||
@@ -0,0 +1,52 @@
|
||||
##
|
||||
# TEST
|
||||
|
||||
## Run unit tests
|
||||
.PHONY: test
|
||||
test: test-unit ## Run unit tests
|
||||
|
||||
## Run codeception tests
|
||||
.PHONY: test-codeception-%
|
||||
test-codeception-%: bootstrap install-codecept ## Run codeception tests
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/codecept run $*)
|
||||
|
||||
## Run old unit tests with code coverage
|
||||
.PHONY: test-coverage
|
||||
test-coverage: bootstrap install-phpunit ## Run code coverage
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpunit --testsuite unit --coverage-text)
|
||||
|
||||
## Run codeception tests with coverage
|
||||
.PHONY: test-coverage-codeception-%
|
||||
test-coverage-codeception-%: bootstrap install-codecept ## Run codeception tests with coverage
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/codecept run $* --coverage --coverage-html)
|
||||
|
||||
## Run phpunit functional tests
|
||||
.PHONY: test-func
|
||||
test-func: bootstrap install-phpunit ## Run functional tests
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpunit --testsuite functional)
|
||||
|
||||
## Loop unit tests
|
||||
.PHONY: test-loop
|
||||
test-loop: bootstrap install-phpunit ## Loop unit tests
|
||||
while true; \
|
||||
do $(MAKE) test; \
|
||||
read continue; \
|
||||
done;
|
||||
|
||||
## Run search tests
|
||||
.PHONY: test-search
|
||||
test-search: bootstrap install-phpunit ## Run search tests
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpunit --testsuite search)
|
||||
|
||||
.PHONY: test-templates
|
||||
test-templates: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),php app/console lint:twig @UIBundle)
|
||||
|
||||
## Run old unit tests
|
||||
.PHONY: test-unit
|
||||
test-unit: bootstrap install-phpunit ## Run unit tests
|
||||
ifdef FILTER
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpunit --testsuite unit --filter $(FILTER))
|
||||
else
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpunit --testsuite unit)
|
||||
endif
|
||||
@@ -0,0 +1,6 @@
|
||||
##
|
||||
# UPDATE
|
||||
|
||||
.PHONY: update-database
|
||||
update-database: bootstrap
|
||||
$(call docker-compose-exec,$(DOCKER_SERVICE),app/console --no-interaction doctrine:migration:migrate)
|
||||
Reference in New Issue
Block a user