84b185be39
Phase A - Stability: - Engine.Start(): recovers orphaned jobs (running/queued/waking_up) after crash - Engine.Stop(): graceful shutdown - cancels all in-flight jobs and waits - Queue keyed by jobID (not syncPairID): cancel now targets exact job - Local rsync uses jobCtx (context.Background() replaced) - Migrations wrapped in transactions; checksums stored Phase B - Security: - admin/admin default removed: SYNCSERVER_ADMIN_PASSWORD required on first run - Path validation: rejects .., leading -, null bytes in sync pair paths - Rsync flags allowlist: dangerous flags blocked (--rsync-path, -e, --files-from) - Shell concat in RunRemote replaced with proper sh -c escaping - knownhosts: replaced custom parser with golang.org/x/crypto/ssh/knownhosts - RequireAdmin wired: machine CRUD, SSH key ops, settings require admin role - deploy-keys: uses authorized_keys only (no private key upload) - Hardcoded /var/lib/syncserver/ssh paths replaced with cfg.SSHDir() Phase C - Operational: - /readyz health check: DB query + SSH dir accessibility - /metrics endpoint: Prometheus text format (jobs, queue, machines) - Event struct JSON tags: job_id, machine_id, type (snake_case) - EventBus broadcast: fanned out to all subscribers - SQLite VACUUM INTO backup: scheduled before cleanup if BackupDir set - Filesystem job log cleanup: removes .log files for purged jobs - Backup retention: old backups auto-purged Phase D - Frontend: - Schedules page: REST API + full CRUD UI for cron schedules - Dashboard: cancel button for running/queued jobs - JobDetail: server-side log download via API - Settings: displays data_dir from server - 404 page: proper NotFound component Phase E - Tests: - auth_test.go: JWT, bcrypt, middleware, seed (18 tests) - models_test.go: Job, Machine, SyncPair, Schedule repos (18 tests) - go test -race: no data races found
53 lines
2.8 KiB
Makefile
53 lines
2.8 KiB
Makefile
BINARY=syncserver
|
|
VERSION?=1.0.53
|
|
GO?=go
|
|
LDFLAGS=-s -w -X main.version=$(VERSION) -X main.commit=$(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
|
BUILD_FLAGS=CGO_ENABLED=0
|
|
|
|
.PHONY: build build-all build-go frontend run package clean tidy test deploy
|
|
|
|
frontend:
|
|
cd web && npm install && npm run build
|
|
|
|
build: frontend
|
|
cp -R web/dist internal/webui/dist
|
|
$(BUILD_FLAGS) $(GO) build -ldflags "$(LDFLAGS)" -o bin/$(BINARY) ./cmd/server
|
|
|
|
# build-go builds the binary without rebuilding the frontend (dist must exist).
|
|
build-go:
|
|
$(BUILD_FLAGS) $(GO) build -ldflags "$(LDFLAGS)" -o bin/$(BINARY) ./cmd/server
|
|
|
|
build-all: frontend
|
|
cp -R web/dist internal/webui/dist
|
|
$(BUILD_FLAGS) GOOS=linux GOARCH=amd64 $(GO) build -ldflags "$(LDFLAGS)" -o bin/$(BINARY)-linux-amd64 ./cmd/server
|
|
$(BUILD_FLAGS) GOOS=linux GOARCH=arm64 $(GO) build -ldflags "$(LDFLAGS)" -o bin/$(BINARY)-linux-arm64 ./cmd/server
|
|
|
|
run: build
|
|
SYNCSERVER_ADMIN_USER=admin SYNCSERVER_ADMIN_PASSWORD=secret \
|
|
SYNCSERVER_DATA_DIR=.data \
|
|
./bin/$(BINARY) --addr :8080
|
|
|
|
package: build-all
|
|
@mkdir -p dist/deb/usr/bin dist/deb/etc/syncserver dist/deb/lib/systemd/system dist/deb/DEBIAN
|
|
cp bin/$(BINARY)-linux-amd64 dist/deb/usr/bin/$(BINARY)
|
|
cp etc/syncserver/config.yaml dist/deb/etc/syncserver/config.yaml
|
|
cp lib/systemd/system/$(BINARY).service dist/deb/lib/systemd/system/$(BINARY).service
|
|
printf 'Package: $(BINARY)\nVersion: $(VERSION)\nSection: net\nPriority: optional\nArchitecture: amd64\nDepends: rsync, openssh-client, ca-certificates\nMaintainer: SyncServer\nDescription: File sync orchestrator with Wake-on-LAN and web UI\n' > dist/deb/DEBIAN/control
|
|
printf '#!/bin/sh\nset -e\nSVC=$(BINARY)\nid $$SVC >/dev/null 2>&1 || useradd --system --no-create-home --shell /usr/sbin/nologin $$SVC\ninstall -d -o $$SVC -g $$SVC -m 0750 /var/lib/$$SVC/data\ninstall -d -o $$SVC -g $$SVC -m 0750 /var/lib/$$SVC/ssh\ninstall -d -o $$SVC -g $$SVC -m 0750 /var/lib/$$SVC/logs\ninstall -d -o root -g root -m 0755 /etc/$$SVC\n[ ! -f /etc/$$SVC/config.yaml ] && cp /etc/$$SVC/config.yaml /etc/$$SVC/config.yaml.new || true\nsystemctl daemon-reload 2>/dev/null || true\nsystemctl enable $$SVC.service 2>/dev/null || true\nsystemctl try-restart $$SVC.service 2>/dev/null || true\nif ! systemctl is-active --quiet $$SVC.service 2>/dev/null; then\n\tsystemctl start $$SVC.service 2>/dev/null || true\nfi\n' > dist/deb/DEBIAN/postinst
|
|
chmod 0755 dist/deb/DEBIAN/postinst
|
|
printf '#!/bin/sh\nset -e\nsystemctl stop $(BINARY).service 2>/dev/null || true\nsystemctl disable $(BINARY).service 2>/dev/null || true\n' > dist/deb/DEBIAN/prerm
|
|
chmod 0755 dist/deb/DEBIAN/prerm
|
|
dpkg-deb --build dist/deb dist/$(BINARY)_$(VERSION)_amd64.deb
|
|
|
|
clean:
|
|
rm -rf bin dist .data web/node_modules web/dist internal/webui/dist
|
|
|
|
tidy:
|
|
$(GO) mod tidy
|
|
|
|
test:
|
|
$(GO) test ./...
|
|
|
|
deploy:
|
|
./scripts/deploy.sh
|