From a84fafc9fbf1818ea36adadf1d3f9e6c8f33c187 Mon Sep 17 00:00:00 2001 From: Michael Freeman Date: Mon, 24 Feb 2025 12:02:33 -0600 Subject: [PATCH] added back embed stuff --- Makefile | 40 ++++++ pkg/cloud/api/server.go | 43 ++++--- pkg/cloud/api/static_serve_container.go | 10 ++ pkg/cloud/api/static_serve_non_container.go | 10 ++ scripts/setup-build-env.sh | 94 ++++++++++++++ scripts/setup-deb-cloud.sh | 130 ++++++++++++-------- 6 files changed, 256 insertions(+), 71 deletions(-) create mode 100644 pkg/cloud/api/static_serve_container.go create mode 100644 pkg/cloud/api/static_serve_non_container.go create mode 100644 scripts/setup-build-env.sh diff --git a/Makefile b/Makefile index 82dd1d0..fdd7fa8 100644 --- a/Makefile +++ b/Makefile @@ -81,6 +81,7 @@ clean: ## Clean up build artifacts @echo "$(COLOR_BOLD)Cleaning up build artifacts$(COLOR_RESET)" @rm -f cover.*.profile cover.html @rm -rf bin/ + @rm -rf serviceradar-*_* release-artifacts/ .PHONY: build build: ## Build all binaries @@ -134,6 +135,45 @@ container-push: kodata-prep ## Build and push container images with ko ./cmd/checkers/dusk \ ./cmd/checkers/snmp +# Build Debian packages +.PHONY: deb-agent +deb-agent: build-web ## Build the agent Debian package + @echo "$(COLOR_BOLD)Building agent Debian package$(COLOR_RESET)" + @./scripts/setup-deb-agent.sh + +.PHONY: deb-poller +deb-poller: build-web ## Build the poller Debian package + @echo "$(COLOR_BOLD)Building poller Debian package$(COLOR_RESET)" + @./scripts/setup-deb-poller.sh + +.PHONY: deb-cloud +deb-cloud: build-web ## Build the cloud Debian package (standard) + @echo "$(COLOR_BOLD)Building cloud Debian package$(COLOR_RESET)" + @VERSION=$(VERSION) ./scripts/setup-deb-cloud.sh + +.PHONY: deb-cloud-container +deb-cloud-container: build-web ## Build the cloud Debian package with container support + @echo "$(COLOR_BOLD)Building cloud Debian package with container support$(COLOR_RESET)" + @VERSION=$(VERSION) BUILD_TAGS=containers ./scripts/setup-deb-cloud.sh + +.PHONY: deb-dusk +deb-dusk: ## Build the Dusk checker Debian package + @echo "$(COLOR_BOLD)Building Dusk checker Debian package$(COLOR_RESET)" + @./scripts/setup-deb-dusk-checker.sh + +.PHONY: deb-snmp +deb-snmp: ## Build the SNMP checker Debian package + @echo "$(COLOR_BOLD)Building SNMP checker Debian package$(COLOR_RESET)" + @./scripts/setup-deb-snmp-checker.sh + +.PHONY: deb-all +deb-all: deb-agent deb-poller deb-cloud deb-dusk deb-snmp ## Build all Debian packages + @echo "$(COLOR_BOLD)All Debian packages built$(COLOR_RESET)" + +.PHONY: deb-all-container +deb-all-container: deb-agent deb-poller deb-cloud-container deb-dusk deb-snmp ## Build all Debian packages with container support for cloud + @echo "$(COLOR_BOLD)All Debian packages built (with container support for cloud)$(COLOR_RESET)" + # Docusaurus commands .PHONY: docs-start docs-start: ## Start Docusaurus development server diff --git a/pkg/cloud/api/server.go b/pkg/cloud/api/server.go index f26a041..4079265 100644 --- a/pkg/cloud/api/server.go +++ b/pkg/cloud/api/server.go @@ -3,18 +3,16 @@ package api import ( + "embed" "encoding/json" + "io/fs" "log" "net/http" - "os" - "path/filepath" - "strings" "sync" "time" "github.com/gorilla/mux" "github.com/mfreeman451/serviceradar/pkg/checker/snmp" - "github.com/mfreeman451/serviceradar/pkg/cloud/api/web" "github.com/mfreeman451/serviceradar/pkg/db" srHttp "github.com/mfreeman451/serviceradar/pkg/http" "github.com/mfreeman451/serviceradar/pkg/metrics" @@ -101,6 +99,22 @@ func WithDB(db db.Service) func(server *APIServer) { } } +//go:embed web/dist/* +var webContent embed.FS + +// setupStaticFileServing configures static file serving for the embedded web files. +func (s *APIServer) setupStaticFileServing() { + // Setting up static file serving using the embedded FS + // This is used for non-containerized builds + fsys, err := fs.Sub(webContent, "web/dist") + if err != nil { + log.Printf("Error setting up static file serving: %v", err) + return + } + + s.router.PathPrefix("/").Handler(http.FileServer(http.FS(fsys))) +} + func (s *APIServer) setupRoutes() { // Add CORS middleware s.router.Use(srHttp.CommonMiddleware) @@ -123,24 +137,9 @@ func (s *APIServer) setupRoutes() { // SNMP endpoints s.router.HandleFunc("/api/nodes/{id}/snmp", s.getSNMPData).Methods("GET") - // Configure static file serving - staticFilesPath := web.GetStaticFilesPath() - fileServer := http.FileServer(http.Dir(staticFilesPath)) - - s.router.PathPrefix("/").HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Check if file exists - path := filepath.Join(staticFilesPath, r.URL.Path) - _, err := os.Stat(path) - - // If file doesn't exist or is a directory (and not root), serve index.html - if os.IsNotExist(err) || (r.URL.Path != "/" && strings.HasSuffix(r.URL.Path, "/")) { - http.ServeFile(w, r, filepath.Join(staticFilesPath, "index.html")) - return - } - - // Otherwise serve the requested file - fileServer.ServeHTTP(w, r) - }) + // Configure static file serving based on build tags + // This is managed via build tags in a separate file + s.configureStaticServing() } // getSNMPData retrieves SNMP data for a specific node. diff --git a/pkg/cloud/api/static_serve_container.go b/pkg/cloud/api/static_serve_container.go new file mode 100644 index 0000000..af42cc1 --- /dev/null +++ b/pkg/cloud/api/static_serve_container.go @@ -0,0 +1,10 @@ +//go:build containers +// +build containers + +package api + +// configureStaticServing sets up static file serving for container mode +func (s *APIServer) configureStaticServing() { + // Use Ko's approach for containers + s.setupContainerStaticFileServing() +} diff --git a/pkg/cloud/api/static_serve_non_container.go b/pkg/cloud/api/static_serve_non_container.go new file mode 100644 index 0000000..44e9b1a --- /dev/null +++ b/pkg/cloud/api/static_serve_non_container.go @@ -0,0 +1,10 @@ +//go:build !containers +// +build !containers + +package api + +// configureStaticServing sets up static file serving for non-container mode. +func (s *APIServer) configureStaticServing() { + // Use embedded FS for regular builds + s.setupStaticFileServing() +} diff --git a/scripts/setup-build-env.sh b/scripts/setup-build-env.sh new file mode 100644 index 0000000..aac635a --- /dev/null +++ b/scripts/setup-build-env.sh @@ -0,0 +1,94 @@ +#!/bin/bash +# setup-build-env.sh - Set up the build environment for serviceradar + +set -e + +echo "Setting up ServiceRadar build environment..." + +# Check for required tools +echo "Checking for required tools..." + +# Check for Go +if ! command -v go &> /dev/null; then + echo "Error: Go is not installed or not in PATH" + echo "Please install Go from https://golang.org/dl/" + exit 1 +fi + +GO_VERSION=$(go version | awk '{print $3}') +echo "Found Go $GO_VERSION" + +# Check for Node.js and pnpm for web UI building +if ! command -v node &> /dev/null; then + echo "Error: Node.js is not installed or not in PATH" + echo "Please install Node.js from https://nodejs.org/" + exit 1 +fi + +NODE_VERSION=$(node -v) +echo "Found Node.js $NODE_VERSION" + +if ! command -v pnpm &> /dev/null; then + echo "Error: pnpm is not installed or not in PATH" + echo "Please install pnpm (usually installed w/ npm)" + exit 1 +fi + +PNPM_VERSION=$(pnpm -v) +echo "Found pnpm $PNPM_VERSION" + +# Check for ko if building containers +if [[ "$1" == "containers" ]]; then + if ! command -v ko &> /dev/null; then + echo "Ko not found. Installing ko..." + go install github.com/google/ko@latest + else + KO_VERSION=$(ko version) + echo "Found ko $KO_VERSION" + fi +fi + +# Set up web dependencies +echo "Setting up web UI dependencies..." +cd web +pnpm install +cd .. + +# Create necessary directories +echo "Creating necessary directories..." +mkdir -p release-artifacts +mkdir -p bin +mkdir -p pkg/cloud/api/web + +# Build web UI +echo "Building web UI..." +cd web +pnpm run build +cd .. + +# Copy web UI to embedded location +echo "Setting up web assets for embedding..." +cp -r web/dist pkg/cloud/api/web/ + +if [[ "$1" == "containers" ]]; then + # Set up kodata directory + echo "Setting up kodata directory for container builds..." + mkdir -p cmd/cloud/.kodata + cp -r web/dist cmd/cloud/.kodata/web + + echo "Build environment for containerized builds is ready!" +else + echo "Build environment for standard builds is ready!" +fi + +echo "You can now run:" +if [[ "$1" == "containers" ]]; then + echo " - 'make container-build' to build container images" + echo " - 'make container-push' to build and push container images" + echo " - 'make deb-cloud-container' to build the cloud Debian package with container support" + echo " - 'make deb-all-container' to build all Debian packages with container support" +else + echo " - 'make build' to build all binaries" + echo " - 'make deb-cloud' to build the cloud Debian package" + echo " - 'make deb-all' to build all Debian packages" +fi \ No newline at end of file diff --git a/scripts/setup-deb-cloud.sh b/scripts/setup-deb-cloud.sh index 457c167..e80f6b7 100755 --- a/scripts/setup-deb-cloud.sh +++ b/scripts/setup-deb-cloud.sh @@ -5,6 +5,7 @@ set -e # Exit on any error echo "Setting up package structure..." VERSION=${VERSION:-1.0.19} +BUILD_TAGS=${BUILD_TAGS:-""} # Create package directory structure PKG_ROOT="serviceradar-cloud_${VERSION}" @@ -12,24 +13,41 @@ mkdir -p "${PKG_ROOT}/DEBIAN" mkdir -p "${PKG_ROOT}/usr/local/bin" mkdir -p "${PKG_ROOT}/etc/serviceradar" mkdir -p "${PKG_ROOT}/lib/systemd/system" +mkdir -p "${PKG_ROOT}/usr/local/share/serviceradar-cloud/web" echo "Building web interface..." -# Build web interface -cd ./web -npm install -npm run build -cd .. +# Build web interface if not already built +if [ ! -d "web/dist" ]; then + cd ./web + npm install + npm run build + cd .. +fi # Create a directory for the embedded content mkdir -p pkg/cloud/api/web cp -r web/dist pkg/cloud/api/web/ +# Only copy web assets to package directory for container builds +# For non-container builds, they're embedded in the binary +if [[ "$BUILD_TAGS" == *"containers"* ]]; then + cp -r web/dist "${PKG_ROOT}/usr/local/share/serviceradar-cloud/web/" + echo "Copied web assets for container build" +fi + echo "Building Go binary..." -# Build Go binary with embedded web content +# Build Go binary with or without container tags +BUILD_CMD="CGO_ENABLED=1 GOOS=linux GOARCH=amd64" +if [[ ! -z "$BUILD_TAGS" ]]; then + BUILD_CMD="$BUILD_CMD GOFLAGS=\"-tags=$BUILD_TAGS\"" +fi +BUILD_CMD="$BUILD_CMD go build -o \"../../${PKG_ROOT}/usr/local/bin/serviceradar-cloud\"" + +# Build Go binary cd cmd/cloud -CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o "../../${PKG_ROOT}/usr/local/bin/serviceradar-cloud" +eval $BUILD_CMD cd ../.. echo "Creating package files..." @@ -77,41 +95,41 @@ EOF if [ ! -f "/etc/serviceradar/cloud.json" ]; then # Create default config file cat > "${PKG_ROOT}/etc/serviceradar/cloud.json" << EOF - { - "listen_addr": ":8090", - "grpc_addr": ":50052", - "alert_threshold": "5m", - "known_pollers": ["home-poller-1"], - "metrics": { - "enabled": true, - "retention": 100, - "max_nodes": 10000 - }, - "security": { - "mode": "none", - "cert_dir": "/etc/serviceradar/certs", - "role": "cloud" - }, - "webhooks": [ - { - "enabled": false, - "url": "https://your-webhook-url", - "cooldown": "15m", - "headers": [ - { - "key": "Authorization", - "value": "Bearer your-token" - } - ] - }, - { - "enabled": true, - "url": "https://discord.com/api/webhooks/changeme", - "cooldown": "15m", - "template": "{\"embeds\":[{\"title\":\"{{.alert.Title}}\",\"description\":\"{{.alert.Message}}\",\"color\":{{if eq .alert.Level \"error\"}}15158332{{else if eq .alert.Level \"warning\"}}16776960{{else}}3447003{{end}},\"timestamp\":\"{{.alert.Timestamp}}\",\"fields\":[{\"name\":\"Node ID\",\"value\":\"{{.alert.NodeID}}\",\"inline\":true}{{range $key, $value := .alert.Details}},{\"name\":\"{{$key}}\",\"value\":\"{{$value}}\",\"inline\":true}{{end}}]}]}" - } - ] - } +{ + "listen_addr": ":8090", + "grpc_addr": ":50052", + "alert_threshold": "5m", + "known_pollers": ["home-poller-1"], + "metrics": { + "enabled": true, + "retention": 100, + "max_nodes": 10000 + }, + "security": { + "mode": "none", + "cert_dir": "/etc/serviceradar/certs", + "role": "cloud" + }, + "webhooks": [ + { + "enabled": false, + "url": "https://your-webhook-url", + "cooldown": "15m", + "headers": [ + { + "key": "Authorization", + "value": "Bearer your-token" + } + ] + }, + { + "enabled": true, + "url": "https://discord.com/api/webhooks/changeme", + "cooldown": "15m", + "template": "{\"embeds\":[{\"title\":\"{{.alert.Title}}\",\"description\":\"{{.alert.Message}}\",\"color\":{{if eq .alert.Level \"error\"}}15158332{{else if eq .alert.Level \"warning\"}}16776960{{else}}3447003{{end}},\"timestamp\":\"{{.alert.Timestamp}}\",\"fields\":[{\"name\":\"Node ID\",\"value\":\"{{.alert.NodeID}}\",\"inline\":true}{{range $key, $value := .alert.Details}},{\"name\":\"{{$key}}\",\"value\":\"{{$value}}\",\"inline\":true}{{end}}]}]}" + } + ] +} EOF fi @@ -129,14 +147,21 @@ fi chown -R serviceradar:serviceradar /etc/serviceradar chmod 755 /usr/local/bin/serviceradar-cloud -mkdir -p "${PKG_ROOT}/var/lib/serviceradar" -chown -R serviceradar:serviceradar "${PKG_ROOT}/var/lib/serviceradar" -chmod 755 "${PKG_ROOT}/var/lib/serviceradar" +# Create data directory +mkdir -p /var/lib/serviceradar +chown -R serviceradar:serviceradar /var/lib/serviceradar +chmod 755 /var/lib/serviceradar + +# Set permissions for web assets +if [ -d "/usr/local/share/serviceradar-cloud/web" ]; then + chown -R serviceradar:serviceradar /usr/local/share/serviceradar-cloud + chmod -R 755 /usr/local/share/serviceradar-cloud +fi # Enable and start service systemctl daemon-reload systemctl enable serviceradar-cloud -systemctl start serviceradar-cloud +systemctl start serviceradar-cloud || echo "Failed to start service, please check the logs" exit 0 EOF @@ -149,8 +174,8 @@ cat > "${PKG_ROOT}/DEBIAN/prerm" << EOF set -e # Stop and disable service -systemctl stop serviceradar-cloud -systemctl disable serviceradar-cloud +systemctl stop serviceradar-cloud || true +systemctl disable serviceradar-cloud || true exit 0 EOF @@ -168,4 +193,11 @@ dpkg-deb --build "${PKG_ROOT}" # Move the deb file to the release-artifacts directory mv "${PKG_ROOT}.deb" "./release-artifacts/" -echo "Package built: release-artifacts/${PKG_ROOT}.deb" +if [[ ! -z "$BUILD_TAGS" ]]; then + # For tagged builds, add the tag to the filename + PACKAGE_NAME="serviceradar-cloud_${VERSION}-${BUILD_TAGS//,/_}.deb" + mv "./release-artifacts/${PKG_ROOT}.deb" "./release-artifacts/$PACKAGE_NAME" + echo "Package built: release-artifacts/$PACKAGE_NAME" +else + echo "Package built: release-artifacts/${PKG_ROOT}.deb" +fi \ No newline at end of file