feat(auth): surface manifest has_auth/public_key and ensure shared auth running

Parse has_auth/public_key from the service manifest onto Container
(persisted to InstalledMetadata), fetch manifests for running non-db
containers during reconciliation, hide role=auth containers from the
grid, and ensure dcntrlized-auth starts with the shared database.
This commit is contained in:
2026-08-15 00:23:09 +01:00
parent a008245db9
commit d6482f5592
10 changed files with 190 additions and 23 deletions
+27 -10
View File
@@ -32,6 +32,8 @@ const (
DCNTRLIZEDNetwork = "dcntrlized_net"
// DatabaseServiceName is the shared database service (image, container and DNS name).
DatabaseServiceName = "dcntrlized-db"
// AuthServiceName is the shared auth service (image, container and DNS name).
AuthServiceName = "dcntrlized-auth"
)
// EnsureDCNTRLIZEDNetwork creates the external dcntrlized_net network when it is
@@ -53,6 +55,21 @@ func EnsureDCNTRLIZEDNetwork(ctx context.Context, dc *docker.DockerClient) error
// leaves installation to the UI. The database is infrastructure, so this must
// never be invoked for the database service itself (StartContainer guards that).
func EnsureDatabaseRunning(ctx context.Context) error {
return ensureInfraRunning(ctx, DatabaseServiceName, "shared database")
}
// EnsureAuthRunning ensures the shared auth service container is running. The
// auth service is hidden infrastructure: every consumer proxies /auth/* to it
// and validates action tokens with its key, so it must be up before services
// that depend on it start. Only starts when already installed.
func EnsureAuthRunning(ctx context.Context) error {
return ensureInfraRunning(ctx, AuthServiceName, "shared auth service")
}
// ensureInfraRunning starts a hidden infrastructure container (shared database,
// shared auth service) when it is installed but not running. It never installs
// infrastructure itself — the UI does that from the registry.
func ensureInfraRunning(ctx context.Context, serviceName, label string) error {
dc, err := docker.NewDockerClient()
if err != nil {
return fmt.Errorf("failed to initialize docker client: %w", err)
@@ -63,29 +80,29 @@ func EnsureDatabaseRunning(ctx context.Context) error {
return err
}
if databaseRunning(ctx, dc) {
if infraRunning(ctx, dc, serviceName) {
return nil
}
if !IsInstalled(DatabaseServiceName) {
logger.Info("Shared database not installed; install %s from the registry to enable database-backed services", DatabaseServiceName)
if !IsInstalled(serviceName) {
logger.Info("%s not installed; install %s from the registry to enable services that need it", label, serviceName)
return nil
}
logger.Info("Starting shared database %s...", DatabaseServiceName)
if err := StartContainer(ctx, types.RegistryContainer{Name: DatabaseServiceName}); err != nil {
return fmt.Errorf("failed to start shared database %s: %w", DatabaseServiceName, err)
logger.Info("Starting %s %s...", label, serviceName)
if err := StartContainer(ctx, types.RegistryContainer{Name: serviceName}); err != nil {
return fmt.Errorf("failed to start %s %s: %w", label, serviceName, err)
}
return nil
}
// databaseRunning reports whether the shared database container is currently up.
func databaseRunning(ctx context.Context, dc *docker.DockerClient) bool {
// infraRunning reports whether the named infrastructure container is currently up.
func infraRunning(ctx context.Context, dc *docker.DockerClient, serviceName string) bool {
filter := filters.NewArgs()
filter.Add("label", "org.dcntrlized.service="+DatabaseServiceName)
filter.Add("label", "org.dcntrlized.service="+serviceName)
containers, err := dc.ContainerList(ctx, container.ListOptions{All: true, Filters: filter})
if err != nil {
logger.Warn("Failed to list database containers: %v", err)
logger.Warn("Failed to list %s containers: %v", serviceName, err)
return false
}
for _, c := range containers {