Greenfield Go multi-tenant IPFS Pinning Service wire-compatible with the
IPFS Pinning Services API spec. Paired 1:1 with Kubo over localhost RPC,
clustered via embedded NATS JetStream, Postgres source-of-truth with
RLS-enforced tenancy, Fiber + huma v2 for the HTTP surface, Authentik
OIDC for session login with kid-rotated HS256 JWT API tokens.
Feature-complete against the 22-milestone build plan, including the
ship-it v1.0 gap items:
* admin CLIs: drain/uncordon, maintenance, mint-token, rotate-key,
prune-denylist, rebalance --dry-run, cache-stats, cluster-presences
* TTL leader election via NATS KV, fence tokens, JetStream dedup
* rebalancer (plan/apply split), reconciler, requeue sweeper
* ristretto caches with NATS-backed cross-node invalidation
(placements live-nodes + token denylist)
* maintenance watchdog for stuck cluster-pause flag
* Prometheus /metrics with CIDR ACL, HTTP/pin/scheduler/cache gauges
* rate limiting: session (10/min) + anonymous global (120/min)
* integration tests: rebalance, refcount multi-org, RLS belt
* goreleaser (tar + deb/rpm/apk + Alpine Docker) targeting Gitea
Stack: Cobra/Viper, Fiber v2 + huma v2, embedded NATS JetStream,
pgx/sqlc/golang-migrate, ristretto, TypeID, prometheus/client_golang,
testcontainers-go.
56 lines
1.8 KiB
Go
56 lines
1.8 KiB
Go
// Package cmd assembles the anchorage Cobra command tree.
|
|
//
|
|
// Each sub-command lives in its own file (serve.go, version.go, ...). The
|
|
// root command is intentionally minimal: it sets up the tree and delegates
|
|
// all wiring to the composition root in internal/app/anchorage, which is
|
|
// created lazily by the sub-commands that need it.
|
|
package cmd
|
|
|
|
import (
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// globalFlags carries flags that every subcommand inherits via
|
|
// PersistentFlags. Exposed as a struct so sub-commands can read them without
|
|
// re-parsing the command line.
|
|
type globalFlags struct {
|
|
configPath string
|
|
// Admin-only flags, populated by newAdminCmd's PersistentFlags.
|
|
adminURL string
|
|
adminToken string
|
|
}
|
|
|
|
// newRootCmd builds the top-level `anchorage` command.
|
|
//
|
|
// A factory is used (rather than a package-global var) so tests can construct
|
|
// a fresh command tree with isolated flags.
|
|
func newRootCmd() *cobra.Command {
|
|
flags := &globalFlags{}
|
|
|
|
root := &cobra.Command{
|
|
Use: "anchorage",
|
|
Short: "anchorage — highly-available IPFS Pinning Service",
|
|
Long: "anchorage runs the IPFS Pinning Service API, cluster coordination, and WebSocket event fan-out for a paired Kubo daemon.",
|
|
SilenceUsage: true,
|
|
SilenceErrors: true,
|
|
}
|
|
|
|
root.PersistentFlags().StringVarP(&flags.configPath, "config", "c", "",
|
|
"path to anchorage config file (default: ./configs/anchorage.yaml, $HOME/.anchorage, /etc/anchorage)")
|
|
|
|
root.AddCommand(newVersionCmd())
|
|
root.AddCommand(newServeCmd(flags))
|
|
root.AddCommand(newMigrateCmd(flags))
|
|
root.AddCommand(newAdminCmd(flags))
|
|
|
|
return root
|
|
}
|
|
|
|
// Execute runs the anchorage command tree against os.Args.
|
|
//
|
|
// It is intentionally the only exported symbol in this package so main.go
|
|
// stays a thin wrapper.
|
|
func Execute() error {
|
|
return newRootCmd().Execute()
|
|
}
|