Skip to content

Commit

Permalink
Merge pull request #242 from carverauto/updates/k8s_build_and_demo
Browse files Browse the repository at this point in the history
server updates for ko build stuff
  • Loading branch information
mfreeman451 authored Feb 24, 2025
2 parents 1e83c56 + daee2df commit 9669ff1
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 21 deletions.
70 changes: 70 additions & 0 deletions .github/workflows/container-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# .github/workflows/container-build.yml
name: Build and Push Containers
on:
push:
branches:
- main
paths-ignore:
- '*.md'
- 'docs/**'
- '.github/**'
- '!.github/workflows/container-build.yml'

permissions:
contents: read
packages: write

jobs:
build-containers:
runs-on: ubuntu-latest
env:
VERSION: latest
KO_DOCKER_REPO: ghcr.io/carverauto/serviceradar
steps:
- uses: actions/checkout@v4
- name: Extract short SHA
id: vars
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: 'web/package-lock.json'
- name: Setup ko
uses: ko-build/[email protected]
- name: Build web UI
run: ./scripts/build-web.sh
- name: Move web artifacts
run: |
mkdir -p pkg/cloud/api/web/
cp -r web/dist pkg/cloud/api/web/
mkdir -p cmd/cloud/.kodata
cp -r web/dist cmd/cloud/.kodata/web
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push container images
run: |
# Set up ko repository
export KO_DOCKER_REPO=ghcr.io/carverauto/serviceradar
# Build and push container images for all components
GOFLAGS="-tags=containers" ko build \
--platform=linux/amd64,linux/arm64 \
--base-import-paths \
--tags=sha-${{ steps.vars.outputs.sha_short }},latest \
--bare \
--image-refs=image-refs.txt \
./cmd/agent \
./cmd/poller \
./cmd/cloud \
./cmd/checkers/dusk \
./cmd/checkers/snmp
55 changes: 54 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ on:
types: [created]
permissions:
contents: write
packages: write
jobs:
build:
build-packages:
runs-on: ubuntu-latest
env:
VERSION: ${{ github.ref_name }}
Expand Down Expand Up @@ -35,3 +36,55 @@ jobs:
files: ./release-artifacts/*.deb
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

build-containers:
runs-on: ubuntu-latest
needs: build-packages
env:
VERSION: ${{ github.ref_name }}
KO_DOCKER_REPO: ghcr.io/carverauto/serviceradar
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: 'web/package-lock.json'
- name: Setup ko
uses: ko-build/[email protected]
- name: Build web UI
run: ./scripts/build-web.sh
- name: Move web artifacts
run: |
mkdir -p pkg/cloud/api/web/
cp -r web/dist pkg/cloud/api/web/
mkdir -p cmd/cloud/.kodata
cp -r web/dist cmd/cloud/.kodata/web
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push container images
run: |
# Set up ko repository
export KO_DOCKER_REPO=ghcr.io/carverauto/serviceradar
# Build and push container images for all components
GOFLAGS="-tags=containers" ko build \
--platform=linux/amd64,linux/arm64 \
--base-import-paths \
--tags=${VERSION},latest \
--bare \
--image-refs=image-refs.txt \
./cmd/agent \
./cmd/poller \
./cmd/cloud \
./cmd/checkers/dusk \
./cmd/checkers/snmp
58 changes: 58 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ GOLANGCI_LINT_VERSION ?= v1.64.5
VERSION ?= $(shell git describe --tags --always)
NEXT_VERSION ?= $(shell git describe --tags --abbrev=0 | awk -F. '{$$NF = $$NF + 1;} 1' | sed 's/ /./g')

# Container configuration
REGISTRY ?= ghcr.io/carverauto/serviceradar
KO_DOCKER_REPO ?= $(REGISTRY)
PLATFORMS ?= linux/amd64,linux/arm64

# Colors for pretty printing
COLOR_RESET = \033[0m
COLOR_BOLD = \033[1m
Expand Down Expand Up @@ -75,6 +80,59 @@ version: ## Show current and next version
clean: ## Clean up build artifacts
@echo "$(COLOR_BOLD)Cleaning up build artifacts$(COLOR_RESET)"
@rm -f cover.*.profile cover.html
@rm -rf bin/

.PHONY: build
build: ## Build all binaries
@echo "$(COLOR_BOLD)Building all binaries$(COLOR_RESET)"
@$(GO) build -ldflags "-X main.version=$(VERSION)" -o bin/serviceradar-agent cmd/agent/main.go
@$(GO) build -ldflags "-X main.version=$(VERSION)" -o bin/serviceradar-poller cmd/poller/main.go
@$(GO) build -ldflags "-X main.version=$(VERSION)" -o bin/serviceradar-dusk-checker cmd/checkers/dusk/main.go
@$(GO) build -ldflags "-X main.version=$(VERSION)" -o bin/serviceradar-cloud cmd/cloud/main.go
@$(GO) build -ldflags "-X main.version=$(VERSION)" -o bin/serviceradar-snmp-checker cmd/checkers/snmp/main.go

.PHONY: build-web
build-web: ## Build web UI
@echo "$(COLOR_BOLD)Building web UI$(COLOR_RESET)"
@./scripts/build-web.sh
@mkdir -p pkg/cloud/api/web/
@cp -r web/dist pkg/cloud/api/web/

.PHONY: kodata-prep
kodata-prep: build-web ## Prepare kodata directories
@echo "$(COLOR_BOLD)Preparing kodata directories$(COLOR_RESET)"
@mkdir -p cmd/cloud/.kodata
@cp -r pkg/cloud/api/web/dist cmd/cloud/.kodata/web

.PHONY: container-build
container-build: kodata-prep ## Build container images with ko
@echo "$(COLOR_BOLD)Building container images with ko$(COLOR_RESET)"
@GOFLAGS="-tags=containers" KO_DOCKER_REPO=$(KO_DOCKER_REPO) ko build \
--platform=$(PLATFORMS) \
--base-import-paths \
--tags=$(VERSION) \
--bare \
--image-refs=image-refs.txt \
./cmd/agent \
./cmd/poller \
./cmd/cloud \
./cmd/checkers/dusk \
./cmd/checkers/snmp

.PHONY: container-push
container-push: kodata-prep ## Build and push container images with ko
@echo "$(COLOR_BOLD)Building and pushing container images with ko$(COLOR_RESET)"
@GOFLAGS="-tags=containers" KO_DOCKER_REPO=$(KO_DOCKER_REPO) ko build \
--platform=$(PLATFORMS) \
--base-import-paths \
--tags=$(VERSION),latest \
--bare \
--image-refs=image-refs.txt \
./cmd/agent \
./cmd/poller \
./cmd/cloud \
./cmd/checkers/dusk \
./cmd/checkers/snmp

# Docusaurus commands
.PHONY: docs-start
Expand Down
51 changes: 31 additions & 20 deletions pkg/cloud/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
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"
Expand Down Expand Up @@ -99,19 +101,6 @@ func WithDB(db db.Service) func(server *APIServer) {
}
}

func (s *APIServer) setupStaticFileServing() {
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)))
}

//go:embed web/dist/*
var webContent embed.FS

func (s *APIServer) setupRoutes() {
// Add CORS middleware
s.router.Use(srHttp.CommonMiddleware)
Expand All @@ -134,8 +123,24 @@ func (s *APIServer) setupRoutes() {
// SNMP endpoints
s.router.HandleFunc("/api/nodes/{id}/snmp", s.getSNMPData).Methods("GET")

// Serve static files
s.setupStaticFileServing()
// 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)
})
}

// getSNMPData retrieves SNMP data for a specific node.
Expand Down Expand Up @@ -408,13 +413,19 @@ func (s *APIServer) getServiceDetails(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Service not found", http.StatusNotFound)
}

const (
defaultReadTimeout = 10 * time.Second
defaultWriteTimeout = 10 * time.Second
defaultIdleTimeout = 60 * time.Second
)

func (s *APIServer) Start(addr string) error {
srv := &http.Server{
Addr: addr,
Handler: s.router,
ReadTimeout: 10 * time.Second, // Timeout for reading the entire request, including the body.
WriteTimeout: 10 * time.Second, // Timeout for writing the response.
IdleTimeout: 60 * time.Second, // Timeout for idle connections waiting in the Keep-Alive state.
ReadTimeout: defaultReadTimeout, // Timeout for reading the entire request, including the body.
WriteTimeout: defaultWriteTimeout, // Timeout for writing the response.
IdleTimeout: defaultIdleTimeout, // Timeout for idle connections waiting in the Keep-Alive state.
// Optional: You can also set ReadHeaderTimeout to limit the time for reading request headers
// ReadHeaderTimeout: 5 * time.Second,
}
Expand Down
11 changes: 11 additions & 0 deletions pkg/cloud/api/web/non-container.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build !containers
// +build !containers

// Package web pkg/cloud/api/web/noncontainer.go
package web

// GetStaticFilesPath returns the path to static files in non-container mode.
func GetStaticFilesPath() string {
// Default path for deb package installation
return "/usr/local/share/serviceradar-cloud/web/dist"
}

0 comments on commit 9669ff1

Please sign in to comment.