MergeDockerConfigs reads each / / /.dockerconfigjson, merges their auths maps into a single config, and writes it to outPath. Returns outPath's parent dir so callers can set DOCKER_CONFIG. Missing per-secret files are skipped silently (matches the old script behavior, where a miscon
(secretsDir string, secretNames []string, outPath string)
| 16 | // behavior, where a misconfigured secret is non-fatal). A malformed file is |
| 17 | // an error. |
| 18 | func MergeDockerConfigs(secretsDir string, secretNames []string, outPath string) (dockerConfigDir string, err error) { |
| 19 | merged := map[string]any{"auths": map[string]any{}} |
| 20 | |
| 21 | for _, name := range secretNames { |
| 22 | path := filepath.Join(secretsDir, name, ".dockerconfigjson") |
| 23 | raw, readErr := os.ReadFile(path) |
| 24 | if readErr != nil { |
| 25 | if os.IsNotExist(readErr) { |
| 26 | continue |
| 27 | } |
| 28 | return "", fmt.Errorf("read %s: %w", path, readErr) |
| 29 | } |
| 30 | var parsed struct { |
| 31 | Auths map[string]any `json:"auths"` |
| 32 | } |
| 33 | if err := json.Unmarshal(raw, &parsed); err != nil { |
| 34 | return "", fmt.Errorf("parse %s: %w", path, err) |
| 35 | } |
| 36 | dst := merged["auths"].(map[string]any) |
| 37 | maps.Copy(dst, parsed.Auths) |
| 38 | } |
| 39 | |
| 40 | if err := os.MkdirAll(filepath.Dir(outPath), 0o700); err != nil { |
| 41 | return "", fmt.Errorf("mkdir docker config: %w", err) |
| 42 | } |
| 43 | buf, err := json.Marshal(merged) |
| 44 | if err != nil { |
| 45 | return "", fmt.Errorf("marshal docker config: %w", err) |
| 46 | } |
| 47 | if err := os.WriteFile(outPath, buf, 0o600); err != nil { |
| 48 | return "", fmt.Errorf("write %s: %w", outPath, err) |
| 49 | } |
| 50 | return filepath.Dir(outPath), nil |
| 51 | } |