feat: provision shared database as hidden infrastructure
The shared dcntrlized-db Postgres service is now treated as Maestro infrastructure: it is hidden from the service grid and auto-started before any app container when already installed. - Container model gains role/hidden/capabilities; registry items gain hidden; installed metadata persists manifest capabilities so stopped services still surface them. - Registry marks the shared database image as hidden (OCI annotation, label, or name fallback). - Compose label rewrite merges existing service labels instead of replacing them, so org.dcntrlized.role/hidden survive. - New infra helpers ensure the external dcntrlized_net network and start the database on the prod path and before each StartContainer. - Watcher skips manifest fetch for db-role containers and persists capabilities from the manifest. - spec.yaml documents the new fields.
This commit is contained in:
@@ -89,33 +89,48 @@ func (cache *ContainerCache) WatchContainers(ctx context.Context, dc *docker.Doc
|
||||
ver, _ := docker.GetContainerVersion(ctx, dc, containerID)
|
||||
|
||||
// Fetch Manifest (best effort; fall back to basic info if it fails)
|
||||
host := containerID[:12]
|
||||
port := event.Actor.Attributes["org.dcntrlized.port"]
|
||||
manifest, err := docker.FetchManifestWithRetry(ctx, host, port, 20, 50*time.Millisecond)
|
||||
if err != nil {
|
||||
log.Printf("Error fetching manifest for container %s: %v", containerID, err)
|
||||
// Infrastructure containers (e.g. the shared database) have no HTTP
|
||||
// manifest endpoint; keep their role marker and skip the fetch.
|
||||
role := event.Actor.Attributes["org.dcntrlized.role"]
|
||||
var manifest *types.Manifest
|
||||
if role != "db" {
|
||||
host := containerID[:12]
|
||||
port := event.Actor.Attributes["org.dcntrlized.port"]
|
||||
var fetchErr error
|
||||
manifest, fetchErr = docker.FetchManifestWithRetry(ctx, host, port, 20, 50*time.Millisecond)
|
||||
if fetchErr != nil {
|
||||
log.Printf("Error fetching manifest for container %s: %v", containerID, fetchErr)
|
||||
}
|
||||
}
|
||||
|
||||
// Save to Cache
|
||||
log.Printf("Service started. Adding container %s - %s to cache", host, containerName)
|
||||
log.Printf("Service started. Adding container %s - %s to cache", containerID[:12], containerName)
|
||||
existing, _ := cache.services[key]
|
||||
if existing.Version != "" && existing.Version != "latest" && (ver == "" || ver == "latest") {
|
||||
ver = existing.Version
|
||||
}
|
||||
capabilities := existing.Capabilities
|
||||
if manifest != nil {
|
||||
capabilities = manifest.Capabilities
|
||||
updateInstalledMetadataCapabilities(serviceLabel, manifest.Capabilities)
|
||||
}
|
||||
container := types.Container{
|
||||
ID: containerID,
|
||||
ServiceName: serviceLabel,
|
||||
DockerName: containerName,
|
||||
Image: event.Actor.Attributes["image"],
|
||||
CreatedAt: fmt.Sprint(event.TimeNano),
|
||||
Network: containerNetwork,
|
||||
Status: "running",
|
||||
Version: ver,
|
||||
Title: existing.Title,
|
||||
Vendor: existing.Vendor,
|
||||
Author: existing.Author,
|
||||
Description: existing.Description,
|
||||
Source: existing.Source,
|
||||
ID: containerID,
|
||||
ServiceName: serviceLabel,
|
||||
DockerName: containerName,
|
||||
Image: event.Actor.Attributes["image"],
|
||||
CreatedAt: fmt.Sprint(event.TimeNano),
|
||||
Network: containerNetwork,
|
||||
Status: "running",
|
||||
Version: ver,
|
||||
Role: role,
|
||||
Hidden: existing.Hidden || event.Actor.Attributes["org.dcntrlized.hidden"] == "true",
|
||||
Capabilities: capabilities,
|
||||
Title: existing.Title,
|
||||
Vendor: existing.Vendor,
|
||||
Author: existing.Author,
|
||||
Description: existing.Description,
|
||||
Source: existing.Source,
|
||||
}
|
||||
if manifest != nil {
|
||||
container.Name = manifest.Name
|
||||
@@ -220,6 +235,12 @@ func (cache *ContainerCache) ReconcileContainers(ctx context.Context, dc *docker
|
||||
entry.Status = normalizeDockerState(c.State)
|
||||
entry.ID = c.ID
|
||||
entry.DockerName = strings.TrimPrefix(c.Names[0], "/")
|
||||
if role := c.Labels["org.dcntrlized.role"]; role != "" {
|
||||
entry.Role = role
|
||||
}
|
||||
if c.Labels["org.dcntrlized.hidden"] == "true" {
|
||||
entry.Hidden = true
|
||||
}
|
||||
cache.services[key] = entry
|
||||
cache.Unlock()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user