Skip to content

Instantly share code, notes, and snippets.

@paulomach
Last active February 21, 2023 17:13
Show Gist options
  • Save paulomach/5aaab6a9b1d06cb29150b816e704fd4b to your computer and use it in GitHub Desktop.
Save paulomach/5aaab6a9b1d06cb29150b816e704fd4b to your computer and use it in GitHub Desktop.
Makefile for k8s/vm charms

There's some mysql specifics, but it's mostly generic

help: ## show help message
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m\033[0m\n"} /^[$$()% a-zA-Z_-]+:.*?##/ { printf "  \033[36m%-25s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

SHELL    := /bin/bash
unit     := 0
app      := $(shell yq '.name' metadata.yaml)
scale    := 3
substrate:= $(shell grep -q k8s metadata.yaml && echo "k8s" || echo "lxd")


ifeq ($(substrate),k8s)
mysqlsh  := mysqlsh
else
mysqlsh  := mysql-shell.mysqlsh
endif

## functions
model    = $(shell juju models --format=yaml|yq '.current-model')
workload = $(shell cat metadata.yaml | yq '.containers | keys' -o t)

build: ## pack the charm
ifeq ($(substrate),k8s)
	charmcraft pack
else
	charmcraft pack --bases-index 1
endif

deploy-local: ## deploy local file with given `scale` (default=3)
ifeq ($(substrate),k8s)
	$(eval res_name := $(shell cat metadata.yaml | yq '.containers.*.resource'))
	$(eval res_val  := $(shell cat metadata.yaml | yq ".resources.$(res_name).upstream-source"))
	juju deploy ./*.charm --trust --series=jammy --resource $(res_name)=$(res_val) -n $(scale)
else
	juju deploy ./*.charm -n $(scale)
endif

refresh: ## refresh using local file
	juju refresh --path ./*.charm $(app)

wait-remove: ## wait for app removel
	while true; do juju status|grep -q $(app) || break; sleep 0.5; done

remove: ## remove app
	juju remove-application --force $(app)

make resolve: ## resolve all units in error
	juju resolve --all

redeploy: remove build wait-remove deploy-local ## remove, build, deploy

test-jl: ## test debug log
	$(eval test_model := $(shell juju models |grep test-| awk '{ print $$1 }'))
	juju model-config logging-config="<root>=WARNING;unit=DEBUG" -m $(test_model)
	juju debug-log -m $(test_model)

test-js: ## test status
	watch -n 1 -c juju status \
	--color --relations \
	-m $$(juju models |grep test-| awk '{ print $$1 }')

clean_cache: ## clean __pycache__'s
	find . -name __pycache__ -type d -exec rm -rf {} +;

clean: clean_cache ## clean __pycache__, tox and charmcraft project
	charmcraft clean
	rm -rf .tox .coverage
	rm -f *.charm

venv: ## make dev venv
	python -m venv venv
	source venv/bin/activate && \
	pip install black pytest-operator mysql-connector-python tox -rrequirements.txt

debug-hook: ## run debug hook
	juju debug-hook $(app)/$(unit)

ssh: ## [VM] ssh into `app`/`unit`
	juju ssh $(app)/$(unit) sudo -i

ssh-workload-container: ## [K8S] ssh into `app`/`unit` workload container
	$(eval wl:=$(call workload))
	$(eval model_name:=$(call model))
	microk8s.kubectl exec -n $(model_name) -it $(app)-$(unit) --container $(wl)  -- /bin/bash

ssh-charm-container: ## [K8S] ssh into `app`/`unit` charm container
	$(eval model_name:=$(call model))
	microk8s.kubectl exec -n $(model_name) -it $(app)-$(unit) -- /bin/bash

prune-pvcs: ## [K8S] prune dangling pvcs
	$(eval model_name:=$(call model))
	for i in $$(microk8s.kubectl get pvc -n $(model_name)|grep database| cut -d\  -f1 ); \
		do microk8s.kubectl delete pvc/$${i} -n $(model_name); \
	done

status: ## run get-cluster-status
	juju run-action $(app)/leader get-cluster-status --wait

status-update-fast: ## set status update to 30s
	juju model-config update-status-hook-interval=30s

status-update-slow: ## set status update to 5m
	juju model-config update-status-hook-interval=5m

status-update-very-slow: ## set status update to 60m
	juju model-config update-status-hook-interval=60m

debug-log-level: ## set debug log level for `model` (default=current)
	$(eval model_name:=$(call model))
	juju model-config logging-config="<root>=WARNING;unit=DEBUG" -m $(model_name)

info-log-level: ## set info log level for `model` (default=current)
	$(eval model_name:=$(call model))
	juju model-config logging-config="<root>=WARNING;unit=INFO" -m $(model_name)

mysqlsh: ## spawn mysqlsh from within a `unit` using serverconfig user
	$(eval pass := $(shell juju show-unit $(app)/$(unit) \
		|yq '.*.relation-info[]| select(.endpoint =="database-peers") |.application-data.server-config-password'))
ifeq ($(substrate),k8s)
	$(eval wl:=$(call workload))
	juju ssh --container $(wl) $(app)/$(unit) $(mysqlsh) --sql serverconfig:$(pass)@localhost
else
	$(eval ip   := $(shell juju show-unit $(app)/$(unit) \
		|yq '.*.relation-info[]| select(.endpoint =="database-peers") |.local-unit.data.private-address'))
	juju ssh $(app)/$(unit) $(mysqlsh) serverconfig:$(pass)@$(ip)
endif

charmcraft-token: ## generate charmhub auth token (edge channel)
	charmcraft login --export mysql.auth \
		--charm=$(app) \ 
		--channel=latest/edge \
		--ttl 31536000

charmcraft-upload: ## charm upload
	charmcraft upload *.charm

charmcraft-publish: ## charm publish `rev` to edge
	charmcraft release $(app) --revision=$(rev) --channel=latest/edge

charmcraft-lib-publish: ## lib publish
	charmcraft publish-lib

download-charm-file: ## download charm file from edge
	juju download $(app) --channel=latest/edge --filepath $(app)-downloaded.charm

charmcraft-publish-branch: ## publish to a branch
	charmcraft upload ./*.charm --release=latest/edge/$(branch)

sync: ## sync with remote `host`
	$(eval host := $(shell aws-ip))
	rsync . -acv --exclude=.git --exclude=.tox \
	--exclude=.mypy_cache --exclude=.vscode \
	--exclude=*.charm --exclude=__pycache__ \
	--exclude=.github --exclude=.gitignore \
	--exclude=venv \
	--exclude=.ruff_cache \
	--exclude=Makefile \
	ubuntu@$(host):~/synced/$(app)

update-libs: ## update charm-libs
	charmcraft fetch-lib charms.rolling_ops.v0.rollingops
	charmcraft fetch-lib charms.tls_certificates_interface.v1.tls_certificates
	charmcraft fetch-lib charms.data_platform_libs.v0.database_provides
	charmcraft fetch-lib charms.operator_libs_linux.v0.apt
	charmcraft fetch-lib charms.operator_libs_linux.v0.systemd
	charmcraft fetch-lib charms.operator_libs_linux.v1.snap

tls-deploy: ## deploy tls-certificates-operator charm
	juju deploy tls-certificates-operator --channel=latest/edge --config generate-self-signed-certificates=true --config ca-common-name="My CA"

unit-data: ## show `unit` peer data
	juju show-unit $(app)/$(unit)|yq '.*.relation-info[]|select(.endpoint=="database-peers")|.local-unit'

kube-config: ## [K8S] write kube config
	microk8s.config > ~/.kube/config

mysql-log-tail: ## tails mysqld log at given `unit`
ifeq ($(substrate),k8s)		
	$(eval wl :=$(call workload))
	juju ssh --container $(wl) $(app)/$(unit) sudo tail -f /var/log/mysql/error.log -n 200
else
	juju ssh $(app)/$(unit) sudo tail -f /var/log/mysql/error.log -n 200
endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment