fix(containers): remap identity bind sources to host paths in dev
The dev maestro container's data root is /data/.dcntrlized (XDG_DATA_HOME=/data), but bind-mount sources are resolved on the daemon's host namespace — a nonexistent /data/.dcntrlized/... source made Docker create empty directories, so the auth hub saw /dcntrlized/pki/tls.crt as a directory and TLS setup failed. DCNTRLIZED_HOST_DATA_ROOT (compose-injected, /home/franciscofadigas/.dcntrlized) is now substituted for the container-internal prefix when building identity bind sources. hostBindSource leaves paths unchanged on host installs.
This commit is contained in:
@@ -16,6 +16,10 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- DCNTRLIZED_DEV=true
|
- DCNTRLIZED_DEV=true
|
||||||
- XDG_DATA_HOME=/data
|
- XDG_DATA_HOME=/data
|
||||||
|
# Host path backing the data root, so Maestro's containerized start path
|
||||||
|
# can produce bind-mount sources the daemon resolves on the host
|
||||||
|
# namespace (identity injection for infra/peers).
|
||||||
|
- DCNTRLIZED_HOST_DATA_ROOT=${XDG_DATA_HOME:-${HOME}}/.dcntrlized
|
||||||
- DCNTRLIZED_GITEA_URL=${DCNTRLIZED_GITEA_URL:-http://192.168.122.183:3000}
|
- DCNTRLIZED_GITEA_URL=${DCNTRLIZED_GITEA_URL:-http://192.168.122.183:3000}
|
||||||
- GITEA_REGISTRY_RO_TOKEN=${GITEA_REGISTRY_RO_TOKEN}
|
- GITEA_REGISTRY_RO_TOKEN=${GITEA_REGISTRY_RO_TOKEN}
|
||||||
- GITEA_RW_PACKAGE_TOKEN=${GITEA_RW_PACKAGE_TOKEN}
|
- GITEA_RW_PACKAGE_TOKEN=${GITEA_RW_PACKAGE_TOKEN}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package containers
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -130,9 +131,9 @@ func injectServiceIdentity(ctx context.Context, project *composetypes.Project, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
mounts := []string{
|
mounts := []string{
|
||||||
fmt.Sprintf("%s:%s/ca.crt:ro", pki.CertPath(dataRoot), identityMountDir),
|
fmt.Sprintf("%s:%s/ca.crt:ro", hostBindSource(dataRoot, pki.CertPath(dataRoot)), identityMountDir),
|
||||||
fmt.Sprintf("%s:%s/tls.crt:ro", identity.CertPath, identityMountDir),
|
fmt.Sprintf("%s:%s/tls.crt:ro", hostBindSource(dataRoot, identity.CertPath), identityMountDir),
|
||||||
fmt.Sprintf("%s:%s/tls.key:ro", identity.KeyPath, identityMountDir),
|
fmt.Sprintf("%s:%s/tls.key:ro", hostBindSource(dataRoot, identity.KeyPath), identityMountDir),
|
||||||
}
|
}
|
||||||
env := map[string]string{
|
env := map[string]string{
|
||||||
"SERVICE_NAME": serviceName,
|
"SERVICE_NAME": serviceName,
|
||||||
@@ -161,6 +162,22 @@ func injectServiceIdentity(ctx context.Context, project *composetypes.Project, s
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hostBindSource maps a dataRoot-relative path to a bind-mount source the
|
||||||
|
// Docker daemon can resolve. Bind sources are resolved on the daemon's host
|
||||||
|
// namespace, but inside the dev container the data root lives at a
|
||||||
|
// container-internal path (/data/.dcntrlized via XDG_DATA_HOME=/data) that
|
||||||
|
// does not exist on the host — the daemon would silently create it as an
|
||||||
|
// empty directory. DCNTRLIZED_HOST_DATA_ROOT (compose-injected, e.g.
|
||||||
|
// $HOME/.dcntrlized) carries the host path backing the data root; when set,
|
||||||
|
// the container-internal prefix is swapped for it. On a host install the path
|
||||||
|
// is already host-resolvable and returned unchanged.
|
||||||
|
func hostBindSource(dataRoot, p string) string {
|
||||||
|
if host := os.Getenv("DCNTRLIZED_HOST_DATA_ROOT"); host != "" && strings.HasPrefix(p, dataRoot) {
|
||||||
|
return filepath.Join(host, strings.TrimPrefix(p, dataRoot))
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
// pinAuthFingerprint returns the service's pinned auth fingerprint, fetching
|
// pinAuthFingerprint returns the service's pinned auth fingerprint, fetching
|
||||||
// and persisting it when the install record does not have one yet (M2 §5).
|
// and persisting it when the install record does not have one yet (M2 §5).
|
||||||
// Best-effort: when the auth service is unreachable, it returns "" and the
|
// Best-effort: when the auth service is unreachable, it returns "" and the
|
||||||
|
|||||||
@@ -14,3 +14,26 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package containers
|
package containers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHostBindSource(t *testing.T) {
|
||||||
|
t.Setenv("DCNTRLIZED_HOST_DATA_ROOT", "")
|
||||||
|
got := hostBindSource("/data/.dcntrlized", "/data/.dcntrlized/pki/services/auth/tls.crt")
|
||||||
|
if got != "/data/.dcntrlized/pki/services/auth/tls.crt" {
|
||||||
|
t.Fatalf("without host root the path must pass through, got %q", got)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Setenv("DCNTRLIZED_HOST_DATA_ROOT", "/home/user/.dcntrlized")
|
||||||
|
got = hostBindSource("/data/.dcntrlized", "/data/.dcntrlized/pki/services/auth/tls.crt")
|
||||||
|
if want := "/home/user/.dcntrlized/pki/services/auth/tls.crt"; got != want {
|
||||||
|
t.Fatalf("host root must replace the container-internal prefix, got %q want %q", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
got = hostBindSource("/data/.dcntrlized", "/data/.dcntrlized/pki/ca.crt")
|
||||||
|
if want := "/home/user/.dcntrlized/pki/ca.crt"; got != want {
|
||||||
|
t.Fatalf("ca path must be remapped too, got %q want %q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user