Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Path parameters
GO ?= $(shell which go 2>/dev/null)
DOCKER ?= $(shell which docker 2>/dev/null)
WASMBUILD ?= $(shell which wasmbuild 2>/dev/null)
BUILDDIR ?= build
CMDDIR=$(wildcard cmd/*)
WASMDIR=$(wildcard wasm/*)

# Set OS and Architecture
ARCH ?= $(shell arch | tr A-Z a-z | sed 's/x86_64/amd64/' | sed 's/i386/amd64/' | sed 's/armv7l/arm/' | sed 's/aarch64/arm64/')
Expand All @@ -16,7 +18,7 @@ BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/version.GitTag=$(shell git describe --t
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/version.GitBranch=$(shell git name-rev HEAD --name-only --always)
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/version.GitHash=$(shell git rev-parse HEAD)
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/version.GoBuildTime=$(shell date -u '+%Y-%m-%dT%H:%M:%SZ')
BUILD_FLAGS = -ldflags "-s -w ${BUILD_LD_FLAGS}"
BUILD_FLAGS = -ldflags="-s -w ${BUILD_LD_FLAGS}"

# Docker
DOCKER_REPO ?= ghcr.io/mutablelogic/pgmanager
Expand All @@ -29,8 +31,22 @@ all: tidy $(CMDDIR)
# Rules for building
.PHONY: $(CMDDIR)
$(CMDDIR): go-dep mkdir
@echo 'building $@'
@$(GO) build $(BUILD_FLAGS) -o ${BUILDDIR}/$(shell basename $@) ./$@
@echo 'go build $@'
@rm -rf ${BUILDDIR}/$(shell basename $@)
@$(GO) build -tags frontend $(BUILD_FLAGS) -o ${BUILDDIR}/$(shell basename $@) ./$@

# Rules for building
.PHONY: $(WASMDIR)
$(WASMDIR): go-dep wasmbuild-dep mkdir
@echo 'wasmbuild $@'
@$(GO) get github.com/djthorpe/go-wasmbuild/pkg/bootstrap github.com/djthorpe/go-wasmbuild/pkg/bootstrap/extra github.com/djthorpe/go-wasmbuild/pkg/mvc
@${WASMBUILD} build --go-flags='$(BUILD_FLAGS)' -o ${BUILDDIR}/wasm/$(shell basename $@) ./$@ && \
mv ${BUILDDIR}/wasm/$(shell basename $@)/wasm_exec.html ${BUILDDIR}/wasm/$(shell basename $@)/index.html && \
cp etc/embed.go ${BUILDDIR}/wasm/$(shell basename $@)/

# Build pgmanager with embedded frontend
.PHONY: pgmanager
pgmanager: wasm/pgmanager cmd/pgmanager

# Build the docker image
.PHONY: docker
Expand Down Expand Up @@ -68,8 +84,11 @@ mkdir:
@install -d $(BUILDDIR)

.PHONY: go-dep tidy
tidy:
tidy: mkdir
@echo 'go tidy'
@install -d ${BUILDDIR}/wasm/pgmanager
@cp -n etc/embed.go ${BUILDDIR}/wasm/pgmanager/ 2>/dev/null || true
@echo 'module github.com/mutablelogic/go-pg/build/wasm/pgmanager' > ${BUILDDIR}/wasm/pgmanager/go.mod
@$(GO) mod tidy

.PHONY: clean
Expand All @@ -88,3 +107,7 @@ go-dep:
.PHONY: docker-dep
docker-dep:
@test -f "${DOCKER}" && test -x "${DOCKER}" || (echo "Missing docker binary" && exit 1)

.PHONY: wasmbuild-dep
wasmbuild-dep:
@test -f "${WASMBUILD}" && test -x "${WASMBUILD}" || (echo "Missing wasmbuild binary" && exit 1)
9 changes: 2 additions & 7 deletions cmd/pgmanager/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/mutablelogic/go-pg"
"github.com/mutablelogic/go-pg/pkg/manager"
"github.com/mutablelogic/go-pg/pkg/manager/httphandler"
"github.com/mutablelogic/go-server/pkg/httpresponse"
"github.com/mutablelogic/go-server/pkg/httpserver"
)

Expand Down Expand Up @@ -75,12 +74,8 @@ func (cmd *RunServer) Run(ctx *Globals) error {

// Register HTTP handlers
router := http.NewServeMux()
httphandler.RegisterHandlers(router, ctx.HTTP.Prefix, manager)

// Catch all handler returns a "not found" error
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
_ = httpresponse.Error(w, httpresponse.ErrNotFound, r.URL.String())
})
httphandler.RegisterBackendHandlers(router, ctx.HTTP.Prefix, manager)
httphandler.RegisterFrontendHandler(router, "")

// Create a TLS config
var tlsconfig *tls.Config
Expand Down
5 changes: 3 additions & 2 deletions etc/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ ARG ARCH=amd64
FROM --platform=${OS}/${ARCH} golang:1.24 AS builder
WORKDIR /usr/src/app
COPY . .
RUN OS=${OS} ARCH=${ARCH} make cmd/pgmanager
RUN go install github.com/djthorpe/go-wasmbuild/cmd/wasmbuild@latest && \
OS=${OS} ARCH=${ARCH} make pgmanager

# Runtime stage
FROM --platform=${OS}/${ARCH} debian:bookworm-slim
Expand All @@ -21,5 +22,5 @@ RUN apt-get update && \
LABEL org.opencontainers.image.source=${SOURCE}

# Entrypoint when running the server
EXPOSE 80 443
EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/pgmanager"]
6 changes: 6 additions & 0 deletions etc/embed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package frontend

import "embed"

//go:embed *.html *.js *.wasm *.png
var FS embed.FS
13 changes: 11 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ toolchain go1.24.2

require (
github.com/alecthomas/kong v1.13.0
github.com/djthorpe/go-wasmbuild v0.0.1
github.com/docker/go-connections v0.6.0
github.com/jackc/pgx/v5 v5.7.6
github.com/mutablelogic/go-client v1.2.2
github.com/mutablelogic/go-pg/build/wasm/pgmanager v0.0.0-00010101000000-000000000000
github.com/mutablelogic/go-server v1.5.17
github.com/prometheus/client_golang v1.23.2
github.com/stretchr/testify v1.11.1
Expand Down Expand Up @@ -42,6 +44,7 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
Expand All @@ -57,6 +60,7 @@ require (
github.com/moby/term v0.5.2 // indirect
github.com/morikuni/aec v1.1.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mutablelogic/go-tokenizer v0.0.1 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
Expand All @@ -74,18 +78,23 @@ require (
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect
go.opentelemetry.io/otel v1.39.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect
go.opentelemetry.io/otel/metric v1.39.0 // indirect
go.opentelemetry.io/otel/trace v1.39.0 // indirect
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.32.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
google.golang.org/grpc v1.75.1 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

// Redirect old module path to this module (for transitive dependencies)
replace github.com/djthorpe/go-pg => ./

// Frontend embedded files (local path, built by make wasm/pgmanager)
replace github.com/mutablelogic/go-pg/build/wasm/pgmanager => ./build/wasm/pgmanager
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/djthorpe/go-errors v1.0.3 h1:GZeMPkC1mx2vteXLI/gvxZS0Ee9zxzwD1mcYyKU5jD0=
github.com/djthorpe/go-errors v1.0.3/go.mod h1:HtfrZnMd6HsX75Mtbv9Qcnn0BqOrrFArvCaj3RMnZhY=
github.com/djthorpe/go-wasmbuild v0.0.1 h1:HoPNhNcrK5S0ze2TS46NouoAyXPqupgQImNfwaM1b0o=
github.com/djthorpe/go-wasmbuild v0.0.1/go.mod h1:T3vqsVbmzws0VG50oXY5OiQMDIdBQsgYRjkoVIedPFM=
github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=
github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
Expand Down Expand Up @@ -130,6 +132,8 @@ github.com/mutablelogic/go-client v1.2.2 h1:ZKIQFL4qYydyyBb2s3BaMUwIF3dlA5HCOTDN
github.com/mutablelogic/go-client v1.2.2/go.mod h1:Y31sWrM22cSWiiOtvkc0MHSpFt5hMsk/CsjJ0d8iB10=
github.com/mutablelogic/go-server v1.5.17 h1:NXuP8IWIM3DLlu/I375fK8pq+OIYHil3Xun1GGklUWM=
github.com/mutablelogic/go-server v1.5.17/go.mod h1:HCX8WZtE3RXR4i+npBvCdILfnBelomDIe8/B68O/MA4=
github.com/mutablelogic/go-tokenizer v0.0.1 h1:3gSF+zoMq4tLpH+XYawkVUb7qmWuYNCez1CTs/iX3mU=
github.com/mutablelogic/go-tokenizer v0.0.1/go.mod h1:zdAyIhfqUKxFXb8MwChbXNwMOZt/5NlUylmx6Qjr4v8=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
Expand Down
2 changes: 1 addition & 1 deletion pkg/manager/httphandler/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//
// Register all handlers with an http.ServeMux:
//
// httphandler.RegisterHandlers(mux, "/api/v1", mgr)
// httphandler.RegisterBackendHandlers(mux, "/api/v1", mgr)
//
// This registers endpoints for roles, databases, schemas, objects, tablespaces,
// extensions, connections, settings, statements, replication slots, and
Expand Down
17 changes: 17 additions & 0 deletions pkg/manager/httphandler/frontend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//go:build frontend

package httphandler

import (
"net/http"

// Packages
frontend "github.com/mutablelogic/go-pg/build/wasm/pgmanager"
)

// RegisterFrontendHandler registers the frontend static file handler
func RegisterFrontendHandler(router *http.ServeMux, prefix string) {
// Serve static files
fileServer := http.FileServer(http.FS(frontend.FS))
router.Handle(joinPath(prefix, "/"), http.StripPrefix(prefix, fileServer))
}
18 changes: 18 additions & 0 deletions pkg/manager/httphandler/frontend_excluded.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//go:build !frontend

package httphandler

import (
"net/http"

// Packages
"github.com/mutablelogic/go-server/pkg/httpresponse"
)

// RegisterFrontendHandler registers a fallback handler when frontend is not included
func RegisterFrontendHandler(router *http.ServeMux, prefix string) {
// Catch all handler returns a "not found" error
router.HandleFunc(joinPath(prefix, "/"), func(w http.ResponseWriter, r *http.Request) {
_ = httpresponse.Error(w, httpresponse.ErrNotFound, r.URL.String())
})
}
2 changes: 1 addition & 1 deletion pkg/manager/httphandler/httphandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
///////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS

func RegisterHandlers(router *http.ServeMux, prefix string, manager *manager.Manager) {
func RegisterBackendHandlers(router *http.ServeMux, prefix string, manager *manager.Manager) {
RegisterConnectionHandlers(router, prefix, manager)
RegisterDatabaseHandlers(router, prefix, manager)
RegisterExtensionHandlers(router, prefix, manager)
Expand Down
25 changes: 25 additions & 0 deletions wasm/pgmanager/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import (
// Packages
bs "github.com/djthorpe/go-wasmbuild/pkg/bootstrap"
bsextra "github.com/djthorpe/go-wasmbuild/pkg/bootstrap/extra"
mvc "github.com/djthorpe/go-wasmbuild/pkg/mvc"
)

func main() {
// Navigation controller
controller := bsextra.NavbarController(navbar())

// Run the application
mvc.New(controller.Views()[0]).Run()
}

func navbar() mvc.View {
return bs.NavBar("main",
bs.WithPosition(bs.Sticky|bs.Top), bs.WithTheme(bs.Dark), bs.WithSize(bs.Medium),
bs.NavItem("#roles", "Roles"),
).Label(
bs.Icon("bootstrap-fill", mvc.WithClass("me-2")), "pgmanager",
)
}
9 changes: 9 additions & 0 deletions wasm/pgmanager/wasmbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
vars:
Title: "pgmanager"
Header: |
<!-- bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>

<!-- bootstrap icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.min.css">