-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
333 lines (294 loc) · 11.9 KB
/
Makefile
File metadata and controls
333 lines (294 loc) · 11.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
.SHELL := /bin/bash
# .ONESHELL:
ifneq (,$(wildcard ./.env))
include .env
export
endif
.PHONY: _help
_help:
@printf "\nUsage: make <command>, valid commands:\n\n"
@awk 'BEGIN {FS = ":.*?##H "}; \
/##H/ && !/@awk.*?##H/ { \
target=$$1; doc=$$2; \
category="General"; \
if (doc ~ /^@/) { \
category=substr(doc, 2, index(doc, " ")-2); \
doc=substr(doc, index(doc, " ")+1); \
} \
if (length(target) > max) max = length(target); \
targets[NR] = target; docs[NR] = doc; cats[NR] = category; \
} \
END { \
last_cat = ""; \
for (i = 1; i <= NR; i++) { \
if (cats[i] != "") { \
if (cats[i] != last_cat) { \
printf "\n\033[1;36m%s Commands:\033[0m\n", cats[i]; \
last_cat = cats[i]; \
} \
printf " \033[1;34m%-*s\033[0m %s\n", max, targets[i], docs[i]; \
} \
} \
print ""; \
}' $(MAKEFILE_LIST)
.PHONY: check-vars
check-vars: ##H @General Check active configuration variables (Auto-detected)
@printf "\033[1;36m--- Makefile Variables ---\033[0m\n"
@printf "\033[1;34m%-25s\033[0m : %s\n" "ENV" "$(ENV)"
@printf "\033[1;34m%-25s\033[0m : %s\n" "VPS" "$(VPS)"
@printf "\n\033[1;36m--- etc/nutra.env Variables ---\033[0m\n"
@if [ -f etc/nutra.env ]; then \
set -a && source etc/nutra.env 2>/dev/null && set +a; \
vars=$$(sed -n 's/^\s*\([A-Z0-9_]\+\)=.*/\1/p' etc/nutra.env | sort | uniq); \
for var in $$vars; do \
val="$${!var}"; \
if [[ "$$var" =~ (PASSWORD|TOKEN|KEY|SECRET|DESC) ]]; then \
val="******"; \
fi; \
printf "\033[1;32m%-25s\033[0m : %s\n" "$$var" "$$val"; \
done \
else \
echo "etc/nutra.env not found."; \
fi
VPS_HOST ?= dev.nutra.tk
VPS_USER ?= gg
VPS := $(VPS_USER)@$(VPS_HOST)
# Logic:
# 1. Default ENV to dev.
# 2. Allow user to override ENV=prod.
# 3. Set VPS_HOST based on ENV.
ENV ?= dev
ifeq ($(ENV),prod)
VPS_HOST := $(VPS_HOST_PROD)
else
VPS_HOST := $(VPS_HOST_DEV)
endif
VPS := $(VPS_USER)@$(VPS_HOST)
BACKUP_DIR := $(HOME)/.backups/rocksdb_backups
.PHONY: stage/vps
stage/vps: ##H @Remote Stage all configuration files on the remote VPS
@echo "Staging files on $(VPS_HOST) (ENV=$(ENV))..."
ENV=$(ENV) python3 scripts/gen_services_map.py
# Tar files and stream to remote
tar cz \
etc/nginx/conf.d/*.conf \
etc/nginx/snippets/*.conf \
etc/nutra.env \
etc/nginx/conf.d/$(ENV)/*.conf \
etc/systemd/system/*.service \
etc/fail2ban \
etc/conduwuit/*.toml \
etc/matrix-conduit/*.toml \
etc/matrix-synapse/**/*.yaml \
etc/gitweb.conf \
opt/stalwart/etc/*.toml \
scripts/gitweb-simplefrontend \
scripts/deploy.sh \
scripts/gen_services_map.py \
scripts/collect_stats.sh \
etc/systemd/system/*.timer \
opt/api/src/api.py \
opt/api/src/collect_stats.py \
scripts/homepage.html | \
ssh $(VPS) "rm -rf ~/.nginx-ops/staging \
&& mkdir -p ~/.nginx-ops/staging \
&& tar xz -C ~/.nginx-ops/staging"
.PHONY: stage/nginx
stage/nginx: stage/vps
.PHONY: deploy/vps
deploy/vps: ##H @Remote Deploy staged files to remote VPS
deploy/vps: stage/vps
@echo "Logging deployment..."
@echo "$(shell date '+%Y-%m-%d %H:%M:%S') [$(ENV)] User: $(USER) \
Commit: $(shell git describe --always --dirty) - $(shell git log -1 --format='%s')" >> deployment.log
@echo "Connecting to $(VPS_HOST)..."
ssh -t $(VPS) "bash ~/.nginx-ops/staging/scripts/deploy.sh test $(ENV) && \
bash ~/.nginx-ops/staging/scripts/deploy.sh $(ENV)"
.PHONY: deploy/nginx
deploy/nginx: ##H @Remote Deploy Nginx configuration only
deploy/nginx: stage/nginx
@echo "Logging deployment..."
@echo "$(shell date '+%Y-%m-%d %H:%M:%S') [$(ENV)] User: $(USER) (Nginx Only) \
Commit: $(shell git describe --always --dirty) - $(shell git log -1 --format='%s')" >> deployment.log
ssh -t $(VPS) "bash ~/.nginx-ops/staging/scripts/deploy.sh diff $(ENV)"
@read -p "Deploy? [Yes/no] " ans && [[ $${ans:-no} =~ ^[Yy](es)?$$ ]]
echo "Connecting to $(VPS_HOST)..."
ssh -t $(VPS) "bash ~/.nginx-ops/staging/scripts/deploy.sh test $(ENV) && \
bash ~/.nginx-ops/staging/scripts/deploy.sh $(ENV) --nginx-only"
.PHONY: certbot/nginx
certbot/nginx: ##H @Remote Run certbot on remote VPS
@echo "Running certbot on $(VPS_HOST)..."
ssh -t $(VPS) "sudo certbot --nginx"
.PHONY: certbot/expand
certbot/expand: ##H @Remote Consolidate SSL certs (Fixes split certs)
@echo "Expanding certificate to cover all subdomains..."
ssh -t $(VPS) "sudo certbot certonly --nginx --cert-name dev.nutra.tk \
-d dev.nutra.tk \
-d api.dev.nutra.tk \
-d api-dev.nutra.tk \
-d chat.nutra.tk \
-d git.nutra.tk \
-d mail.nutra.tk \
-d matrix.nutra.tk \
-d www.dev.nutra.tk \
-d element.nutra.tk \
-d cinny.nutra.tk \
--expand && sudo systemctl reload nginx"
# Application Deployment
.PHONY: build/website
build/website: ##H @Local Build the static website
$(MAKE) -C opt/my-website build
.PHONY: deploy/website
deploy/website: ##H @Remote Deploy the static website
$(MAKE) -C opt/my-website deploy VPS="$(VPS)"
# Direct Local Deployment (No Staging)
.PHONY: run/api
run/api: ##H @Local Run the API server locally with dev bypass
@echo "Starting API on port 5000..."
@set -a && source etc/nutra.env && set +a && \
export CAPTCHA_BYPASS_TOKEN="dev_token" && \
export RESUME_PATH="$(PWD)/opt/api/assets/dummy_resume.pdf" && \
python3 opt/api/api.py
.PHONY: diff/local
diff/local: ##H @Local Show diff against system config
ifdef SUDO_USER
@echo "Checking diff locally as $(SUDO_USER)..."
su -P $(SUDO_USER) -c "bash scripts/deploy.sh diff $(ENV)"
else
@echo "Checking diff locally..."
bash scripts/deploy.sh diff $(ENV)
endif
.PHONY: test/local
test/local: ##H @Local Test current configuration
@echo "Testing locally..."
bash scripts/deploy.sh test $(ENV)
.PHONY: deploy/local
deploy/local: ##H Deploy Nginx and Gitweb configuration (local)
ifdef SUDO_USER
@echo "Deploying locally as $(SUDO_USER)..."
@# We need to run the entire script as the SUDO_USER to ensure they can sudo inside it
su -P $(SUDO_USER) -c "bash scripts/deploy.sh $(ENV)"
else
@echo "Deploying locally..."
@echo "$(shell date '+%Y-%m-%d %H:%M:%S') [$(ENV)] User: $(USER) \
Commit: $(shell git describe --always --dirty) - $(shell git log -1 --format='%s')" >> deployment.log
bash scripts/deploy.sh $(ENV)
endif
.PHONY: certbot/local
certbot/local: ##H @Local Run certbot locally (supports SUDO_USER)
ifdef SUDO_USER
@echo "Running certbot locally as $(SUDO_USER)..."
su -P $(SUDO_USER) -c "sudo certbot --nginx"
else
@echo "Running certbot locally..."
sudo certbot --nginx
endif
.PHONY: certbot/list-certs
certbot/list-certs: ##H @Local List managed certificates (supports SUDO_USER)
ifdef SUDO_USER
@echo "Listing certificates as $(SUDO_USER)..."
su -P $(SUDO_USER) -c "sudo certbot certificates"
else
@echo "Listing certificates..."
sudo certbot certificates
endif
# ----------------- Safe Migration -----------------
.PHONY: backup/conduwuit
backup/conduwuit: ##H @Remote Safe Backup: Stop -> Stream to $(BACKUP_DIR) -> Start
@echo "\033[1;33m[!] WARNING: This will temporarily STOP Matrix services to backup the DB.\033[0m"
@read -p "Are you sure? [y/N] " ans && [ $${ans:-N} = y ]
@mkdir -p $(BACKUP_DIR)
@echo "1. Stopping services on $(VPS_HOST)..."
@ssh -t $(VPS) "sudo systemctl stop continuwuity conduwuit || true"
@echo "2. Streaming backup to $(BACKUP_DIR)/conduwuit_$$(date +%s).tar.gz ..."
@ssh $(VPS) "sudo tar cz -C /var/lib continuwuity" > $(BACKUP_DIR)/conduwuit_$$(date +%s).tar.gz
@echo " Backup complete."
@echo "3. Restarting services..."
@ssh -t $(VPS) "sudo systemctl start continuwuity || sudo systemctl start conduwuit || true"
@echo "\033[1;32mBackup Complete!\033[0m"
.PHONY: run/conduwuit-local
run/conduwuit-local: ##H @Local Run Conduwuit locally using latest backup
@echo "Finding latest backup in $(BACKUP_DIR)..."
$(eval LATEST_BACKUP := $(shell ls -t $(BACKUP_DIR)/conduwuit_*.tar.gz | head -1))
@if [ -z "$(LATEST_BACKUP)" ]; then echo "No backup found!"; exit 1; fi
@echo "Using: $(LATEST_BACKUP)"
@mkdir -p /tmp/conduwuit-test-db
@rm -rf /tmp/conduwuit-test-db/*
@echo "Extracting to /tmp/conduwuit-test-db..."
@tar xf "$(LATEST_BACKUP)" -C /tmp/conduwuit-test-db
@echo "Generate temp config..."
@cp etc/conduwuit/conduwuit.toml /tmp/conduwuit-local.toml
@sed -i 's|database_path = .*|database_path = "/tmp/conduwuit-test-db/continuwuity/"|' /tmp/conduwuit-local.toml
@sed -i 's|server_name = .*|server_name = "localhost"|' /tmp/conduwuit-local.toml
@echo "Starting continuwuity..."
@continuwuity --config /tmp/conduwuit-local.toml
.PHONY: migrate/conduwuit
migrate/conduwuit: ##H @Remote Safe Migration: Stop -> Backup -> Deploy -> Start
@echo "\033[1;33m[!] WARNING: This will stop Matrix services, backup DB locally, and deploy.\033[0m"
@read -p "Are you sure? [y/N] " ans && [ $${ans:-N} = y ]
@mkdir -p $(BACKUP_DIR)
@echo "1. Stopping services on $(VPS_HOST)..."
@ssh -t $(VPS) "sudo systemctl stop continuwuity conduwuit || true"
@echo "2. Streaming backup to $(BACKUP_DIR)/conduwuit_$$(date +%s).tar.gz ..."
@ssh $(VPS) "sudo tar cz -C /var/lib continuwuity" > $(BACKUP_DIR)/conduwuit_$$(date +%s).tar.gz
@echo " Backup complete."
@echo "3. Deploying new configuration..."
@$(MAKE) deploy/vps ENV=$(ENV)
@echo "4. Starting new service and disabling old..."
@ssh -t $(VPS) "sudo systemctl start conduwuit && sudo systemctl disable continuwuity --now || true"
@echo "\033[1;32mMigration Complete!\033[0m"
# ----------------- Git Repo Management -----------------
.PHONY: git/init
git/init: ##H @Remote Initialize new bare repo (usage: make git/init NAME=projects/new [DESC="..."])
@python3 scripts/manage_repos.py --remote $(VPS) init $(if $(NAME),--name "$(NAME)") $(if $(DESC),--desc "$(DESC)") $(if $(OWNER),--owner "$(OWNER)") --auto-remote
.PHONY: git/add
git/add: ##H @Remote Clone a repository (usage: make git/add URL=... [NAME=...] [DESC=...])
ifndef URL
$(error URL is undefined. Usage: make git/add URL=https://github.com/foo/bar.git)
endif
@python3 scripts/manage_repos.py --remote $(VPS) add $(URL) $(if $(NAME),--name "$(NAME)") $(if $(DESC),--desc "$(DESC)") $(if $(OWNER),--owner "$(OWNER)")
.PHONY: git/rename
git/rename: ##H @Remote Rename a repository (usage: make git/rename OLD=... NEW=...)
ifndef OLD
$(error OLD is undefined. Usage: make git/rename OLD=projects/old NEW=projects/new)
endif
ifndef NEW
$(error NEW is undefined.)
endif
@python3 scripts/manage_repos.py --remote $(VPS) rename $(OLD) $(NEW)
.PHONY: git/update
git/update: ##H @Remote Update repo metadata (usage: make git/update NAME=... [DESC=...] [OWNER=...])
ifndef NAME
$(error NAME is undefined. usage: make git/update NAME=projects/foo ...)
endif
@python3 scripts/manage_repos.py --remote $(VPS) update $(NAME) $(if $(DESC),--desc "$(DESC)") $(if $(OWNER),--owner "$(OWNER)")
.PHONY: git/list
git/list: ##H @Local List tracked repositories
@python3 scripts/manage_repos.py list
.PHONY: git/install-hooks
git/install-hooks: ##H @Remote Install post-receive hook on VPS
@echo "Installing post-receive hook to $(VPS)..."
@if [ -z "$(REPO)" ]; then \
echo "Error: REPO is required (e.g. 'nutratech/vps-root.git' or '/home/git/repos/...')"; \
exit 1; \
fi
@ssh $(VPS) 'target="$(REPO)"; \
if [[ "$$target" != /* ]]; then target="/srv/git/$$target"; fi; \
echo "Target Repo: $$target"; \
if [ ! -d "$$target" ]; then echo "Error: Repository directory not found!"; exit 1; fi; \
mkdir -p "$$target/hooks"; \
cat > "$$target/hooks/post-receive"' < scripts/post-receive.sh
@ssh $(VPS) 'target="$(REPO)"; \
if [[ "$$target" != /* ]]; then target="/srv/git/$$target"; fi; \
chmod +x "$$target/hooks/post-receive" || true'
@echo "Hook installed."
.PHONY: git/sync
git/sync: ##H @Local Sync remote repositories to local JSON
@python3 scripts/manage_repos.py --remote $(VPS) sync
.PHONY: format
format: ##H @Local Format python and shell scripts
git ls-files '*.conf' ':!etc/fail2ban' | xargs nginxfmt
git ls-files '*.py' | xargs black
git ls-files '*.sh' | xargs shfmt -l -w
cd opt/api && make format
cd opt/my-website && make format