# SysDeck - Makefile # Author: Jeremy Anderson (https://dcos.net) # # v0.3.0 AI GATEWAY EDITION: two distributions in one tree — # / the cockpit edition: 27 standalone Cockpit plugins + shared bridge # /web the SysDeck Web Edition (Next.js console, 29 bridge modules) # /klanker-gate — the Frosty Deno LLM gateway, vendored + pre-integrated # (by TykoDev, https://github.com/TykoDev/klanker-gate, # Apache-2.0 — not SysDeck code; own version 0.9.0, with # arch/ packaging for Arch Linux) # /web/mini-services/fester — Fester, vendored + pre-integrated (own version 0.2.1) # Each plugin ships to /usr/share/cockpit/sysdeck-/ and appears as # its own sidebar entry in Cockpit. The Python bridge helpers stay at # /usr/lib/sysdeck/bridge/ (called via cockpit.spawn). # # Targets: # make install - install all 27 plugins + bridge + scripts + firewall templates # make uninstall - remove all 27 plugins + bridge + scripts # make check - validate all manifests against cockpit-podman pattern, # syntax-check JS/Python/shell sources, run unit tests # make plugins - verify plugins/ + shared/ match the generator catalog # make clean - remove build artifacts # make dist - build the source tarball (runs check first) # make distcheck - extract the tarball into a clean dir and run check inside # make fester-start - run the vendored fester service on :3010 (bun) # make web-install - install + migrate the web edition (bun + prisma) # make web-dev - start fester (background) + the web console on :3000 # make master - build the master tarball (cockpit + web + fester) # # Distro support: Arch Linux, Debian/Ubuntu, Fedora/RHEL/CentOS. PACKAGE := sysdeck VERSION := 0.4.6 LIB_DIR := $(DESTDIR)/usr/lib/$(PACKAGE) PYTHON_DIR := $(LIB_DIR)/bridge SHARE_DIR := $(DESTDIR)/usr/share/$(PACKAGE) # Firewall templates (pre-built nftables rulesets the operator selects # from the panel — applied via the org.sysdeck.firewall.modify polkit # action). Seven topologies ship; operators can drop more in. FIREWALL_TEMPLATES_DIR := $(SHARE_DIR)/firewall/templates # Python bridge helpers (called via `python3 -m sysdeck.bridge.`). PY_FILES := $(wildcard bridge/*.py bridge/modules/*.py) # Unit tests. TEST_FILES := $(wildcard tests/*.py) # Documentation. DOC_FILES := $(wildcard docs/*.md) # AppStream metainfo + PolKit policy. METAINFO_FILE := packaging/sysdeck.metainfo.xml POLKIT_FILE := packaging/polkit/org.sysdeck.policy # Diagnostic + smoke-test scripts. DIAGNOSE_SCRIPT := sysdeck-diagnose.sh SMOKE_TEST_SCRIPT := cockpit-smoke-test.sh UNINSTALL_SCRIPT := sysdeck-uninstall.sh # Generator script (regenerates plugins/ and shared/). GENERATOR := scripts/generate-plugins.py .PHONY: install uninstall check clean dist distcheck plugins fester-start web-install web-dev master install-branding uninstall-branding # ─── plugins: verify the tree against the generator catalog ───────── # The shipped plugins/ and shared/ assets are hand-maintained source; # the generator VERIFIES catalog <-> disk consistency and never writes. # (--force exists only to bootstrap a tree with missing plugin dirs.) plugins: @echo ">>> Verifying plugins/ and shared/ against the catalog in $(GENERATOR)" python3 $(GENERATOR) # ─── install: 27 visible plugins + shared/ + bridge + scripts + metainfo ──── install: @echo ">>> Installing $(PACKAGE) $(VERSION): 27 standalone Cockpit plugins" # Each plugin: /usr/share/cockpit/sysdeck-/{manifest.json,index.html,.js} @for plugin in plugins/sysdeck-*; do \ [ -d "$$plugin" ] || continue; \ name=$$(basename "$$plugin"); \ destdir=$(DESTDIR)/usr/share/cockpit/$$name; \ install -d "$$destdir"; \ for f in $$plugin/manifest.json $$plugin/index.html $$plugin/*.js; do \ [ -f "$$f" ] || continue; \ install -m 0644 "$$f" "$$destdir/$$(basename $$f)"; \ done; \ echo " installed $$name"; \ done # Shared bridge + CSS + manifest: /usr/share/cockpit/sysdeck-common/ # The manifest.json is REQUIRED — without it, cockpit doesn't register # sysdeck-common as a package, and every URL like # /cockpit/@localhost/sysdeck-common/bridge.js returns 404. # Verified from cockpit's pkg/static/manifest.json (just `{}`). install -d $(DESTDIR)/usr/share/cockpit/sysdeck-common install -m 0644 shared/manifest.json $(DESTDIR)/usr/share/cockpit/sysdeck-common/manifest.json install -m 0644 shared/bridge.js $(DESTDIR)/usr/share/cockpit/sysdeck-common/bridge.js install -m 0644 shared/sysdeck.css $(DESTDIR)/usr/share/cockpit/sysdeck-common/sysdeck.css # v0.3.0: the web-edition skin (midnight/teal design of the Next.js # console) — every plugin index.html links it after base sysdeck.css. # Remove the file to revert plugin pages to the classic 0.1.x skin. install -m 0644 shared/sysdeck-web.css $(DESTDIR)/usr/share/cockpit/sysdeck-common/sysdeck-web.css # Python bridge helpers: /usr/lib/sysdeck/bridge/ # v0.0.27: install each helper as an executable script (0755, not 0644) # so they can be invoked by absolute path: # python3 /usr/lib/sysdeck/bridge/glances.py snapshot # No PYTHONPATH or symlink needed — the JS calls them directly. # Each helper has a `if __name__ == "__main__": sys.exit(main(sys.argv[1:]))` guard. install -d $(PYTHON_DIR) @for f in $(PY_FILES); do \ rel=$$(echo $$f | sed 's|^bridge/||'); \ install -d $$(dirname $(PYTHON_DIR)/$$rel); \ install -m 0755 $$f $(PYTHON_DIR)/$$rel; \ done # Unit tests: /usr/lib/sysdeck/tests/ install -d $(LIB_DIR)/tests @for f in $(TEST_FILES); do \ rel=$$(echo $$f | sed 's|^tests/||'); \ install -m 0644 $$f $(LIB_DIR)/tests/$$rel; \ done # Documentation: /usr/share/doc/sysdeck/ install -d $(DESTDIR)/usr/share/doc/$(PACKAGE) @for f in $(DOC_FILES); do \ install -m 0644 $$f $(DESTDIR)/usr/share/doc/$(PACKAGE)/$$(basename $$f); \ done install -m 0644 README.md $(DESTDIR)/usr/share/doc/$(PACKAGE)/README.md install -m 0644 QUICKSTART.md $(DESTDIR)/usr/share/doc/$(PACKAGE)/QUICKSTART.md install -m 0644 LICENSE $(DESTDIR)/usr/share/doc/$(PACKAGE)/LICENSE # Diagnostic + smoke-test scripts: /usr/share/sysdeck/ install -d $(DESTDIR)/usr/share/$(PACKAGE) install -m 0755 $(DIAGNOSE_SCRIPT) $(DESTDIR)/usr/share/$(PACKAGE)/$(DIAGNOSE_SCRIPT) install -m 0755 $(SMOKE_TEST_SCRIPT) $(DESTDIR)/usr/share/$(PACKAGE)/$(SMOKE_TEST_SCRIPT) install -m 0755 $(UNINSTALL_SCRIPT) $(DESTDIR)/usr/share/$(PACKAGE)/$(UNINSTALL_SCRIPT) # v0.0.31: firewall templates — pre-built nftables rulesets the # operator selects from the Firewall panel. The bridge firewall.py # `templates` and `apply-template` subcommands read this directory. # Templates are executable (0755) because they are invoked by the # bridge via `bash