@codiac.io/codiac-cli 1.3.254 → 1.3.256

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const core_1 = require("@oclif/core");
5
+ const contracts_1 = require("../../apis/codiac-api/contracts");
6
+ const command_base_exec_tenant_1 = require("../../command-base-exec-tenant");
7
+ const prettify_1 = require("../../prettify");
8
+ const cloud_resource_configurator_factory_1 = require("../../uilogic/cloud-resource-configurator-factory");
9
+ const cloud_provider_contextualizer_1 = require("../../uilogic/cloud-provider-contextualizer");
10
+ const image_registry_contextualizer_1 = require("../../uilogic/image-registry-contextualizer");
11
+ const image_contextualizer_1 = require("../../uilogic/image-contextualizer");
12
+ const registry_resolver_1 = require("../../uilogic/registry-resolver");
13
+ /**
14
+ * Edits the mutable attributes of an existing container-registry reference.
15
+ *
16
+ * WHY this exists: `imageRegistry capture` is create-only (it throws if the code already
17
+ * exists), so a fat-fingered registry url had no in-CLI fix — you had to `forget` and
18
+ * re-`capture`, which orphans every asset that referenced the old code. This command
19
+ * updates the record in place, keeping the code (the join key assets resolve against)
20
+ * stable so those assets keep resolving.
21
+ *
22
+ * The `code`, `provider`, and `type` are the record's identity and the relay's client
23
+ * selector, so they are immutable here; a change to any of those is a different registry
24
+ * (capture a new one). Only `url` and the private/public flag are editable.
25
+ *
26
+ * NOTE: assets carry a denormalized copy of `image.registry` from create time, and the
27
+ * deploy path reads that copy — so after fixing a registry url here, existing assets also
28
+ * need `cod asset edit --registry <code>` to re-resolve their embedded reference.
29
+ */
30
+ class ImageRegistryEdit extends command_base_exec_tenant_1.CommandBaseExecTenant {
31
+ bootstrap() {
32
+ super.bootstrap();
33
+ cloud_provider_contextualizer_1.CloudProviderContextualizer.bootstrap(this.ioc);
34
+ this.ioc.bind(image_registry_contextualizer_1.ImageRegistryContextualizer).toSelf();
35
+ this.ioc.bind(image_contextualizer_1.ImageContextualizer).toSelf();
36
+ }
37
+ // --------------------------------------------------------------------
38
+ // Lazy-loaded properties
39
+ get uiRegistry() {
40
+ if (this._uiRegistry_backer === undefined) {
41
+ this._uiRegistry_backer = this.ioc.get(image_registry_contextualizer_1.ImageRegistryContextualizer);
42
+ }
43
+ return this._uiRegistry_backer;
44
+ }
45
+ // --------------------------------------------------------------------
46
+ captureArgs() {
47
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
48
+ const { flags } = yield this.parse(ImageRegistryEdit);
49
+ // partial.code identifies WHICH registry (immutable); partial.url / pullRequiresAuth
50
+ // carry the requested edits. private is only assigned when the user passed a --private
51
+ // or --no-private, so an omitted flag leaves the stored value untouched.
52
+ let partial = {};
53
+ if (flags.registry)
54
+ partial.code = flags.registry;
55
+ if (flags.url)
56
+ partial.url = flags.url.trim();
57
+ if (flags.private !== undefined)
58
+ partial.pullRequiresAuth = flags.private;
59
+ return [partial, false];
60
+ });
61
+ }
62
+ buildCandidate_silently(partial, _rootMap) {
63
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
64
+ if (!partial.code)
65
+ throw new Error("A registry code must be set (use --registry <code> to identify the registry to edit; run `cod imageRegistry list` for codes).");
66
+ const all = yield this._codiacApi.ImageRegistry.readMany({ all: true }, { throwNotFound: false });
67
+ const existing = (0, registry_resolver_1.resolveRegistryByCodeOrThrow)(all !== null && all !== void 0 ? all : [], partial.code, "--registry");
68
+ return this.applyEdits(existing, partial);
69
+ });
70
+ }
71
+ buildCandidate_interactively(partial, _takeDefaults, _rootMap) {
72
+ var _a;
73
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
74
+ cloud_resource_configurator_factory_1.RegistryConfiguratorFactory.bootstrap(this.ioc);
75
+ const all = yield this._codiacApi.ImageRegistry.readMany({ all: true }, { throwNotFound: false });
76
+ if (!all || all.length === 0)
77
+ throw new Error("Cannot edit: no image registries are defined yet.");
78
+ // Resolve the target: honor --registry if given & valid, otherwise let the user pick.
79
+ let existing = partial.code ? all.find(r => r.code === partial.code) : undefined;
80
+ if (!existing) {
81
+ existing = yield this.uiRegistry.promptForExistingRegistry(contracts_1.PackageType.container, false, all);
82
+ }
83
+ if (!existing)
84
+ throw new Error("No registry selected.");
85
+ this._ui.userMessage(`Editing ${existing.type} image registry ${this._styler.bold(this._styler.hilite(existing.code))} ${this._styler.dim(`(current url: ${existing.url})`)}`);
86
+ // URL — default to the current value so pressing enter leaves it unchanged.
87
+ if (partial.url === undefined) {
88
+ partial.url = yield this._ui.prompt("url", "Registry url:", true, existing.url);
89
+ }
90
+ // Private/public — default to the current value.
91
+ if (partial.pullRequiresAuth === undefined) {
92
+ partial.pullRequiresAuth = yield this._ui.promptConfirm("private", "Requires authentication to pull (private)?", (_a = existing.pullRequiresAuth) !== null && _a !== void 0 ? _a : true);
93
+ }
94
+ const candidate = this.applyEdits(existing, partial);
95
+ this._ui.userMessage("About to save:");
96
+ this._ui.userMessage((0, prettify_1.prettify)(candidate));
97
+ const confirmed = yield this._ui.promptConfirm("confirm", "Save changes?", false);
98
+ if (!confirmed)
99
+ return undefined;
100
+ return candidate;
101
+ });
102
+ }
103
+ /** Overlays the requested edits onto the existing record, keeping every other field intact.
104
+ * Throws if the caller asked for no change at all. */
105
+ applyEdits(existing, partial) {
106
+ const candidate = Object.assign({}, existing);
107
+ let changed = false;
108
+ if (partial.url !== undefined && partial.url.length > 0 && partial.url !== existing.url) {
109
+ candidate.url = partial.url;
110
+ changed = true;
111
+ }
112
+ if (partial.pullRequiresAuth !== undefined && partial.pullRequiresAuth !== existing.pullRequiresAuth) {
113
+ candidate.pullRequiresAuth = partial.pullRequiresAuth;
114
+ changed = true;
115
+ }
116
+ if (!changed)
117
+ throw new Error(`Nothing to edit for [${existing.code}]. Provide --url and/or --private/--no-private with a value different from the current one.`);
118
+ return candidate;
119
+ }
120
+ buildCommandString(candidate, cmd) {
121
+ cmd.push("--registry", candidate.code);
122
+ cmd.push("--url", candidate.url);
123
+ cmd.push(candidate.pullRequiresAuth === false ? "--no-private" : "--private");
124
+ cmd.push("--silent");
125
+ return cmd;
126
+ }
127
+ executeTask(candidate) {
128
+ var _a;
129
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
130
+ const result = yield this._codiacApi.ImageRegistry.tryUpdate(candidate);
131
+ if (result.success) {
132
+ this._ui.userMessage(`Successfully updated ${candidate.type} image registry [${this._styler.hilite(candidate.code)}] — url: ${this._styler.hilite(candidate.url)}`);
133
+ }
134
+ else if (result.error) {
135
+ this._ui.userMessage(`${this._styler.colorCritical("Error")} updating ${candidate.type} image registry [${candidate.code}]: ${result.error.name} ${(_a = result.error.message) !== null && _a !== void 0 ? _a : result.error.stack}`);
136
+ throw result.error;
137
+ }
138
+ else {
139
+ this._ui.userMessage(`Failed to update image registry [${candidate.code}]. Check logs for details.`);
140
+ }
141
+ });
142
+ }
143
+ }
144
+ exports.default = ImageRegistryEdit;
145
+ ImageRegistryEdit.description = 'Changes the mutable attributes (url, private/public) of an existing container registry reference. The code, provider, and type are immutable.';
146
+ ImageRegistryEdit.aliases = [];
147
+ ImageRegistryEdit.examples = [
148
+ { description: "Edit a registry interactively (select it, then change its url).", command: "<%= config.bin %> <%= command.id %>" },
149
+ { description: "Correct a registry's url (identified by its Codiac code, not its url).", command: "<%= config.bin %> <%= command.id %> --registry devCodiacContainers --url newname.azurecr.io --silent" },
150
+ { description: "Flip a registry to public (no pull authentication).", command: "<%= config.bin %> <%= command.id %> --registry 'Other|ghcr' --no-private --silent" },
151
+ { description: "Render the equivalent silent command without executing it.", command: "<%= config.bin %> <%= command.id %> --registry devCodiacContainers --url newname.azurecr.io --to-script" },
152
+ ];
153
+ ImageRegistryEdit.flags = {
154
+ help: core_1.Flags.help({ char: 'h' }),
155
+ registry: core_1.Flags.string({ char: 'r', required: false, description: "The Codiac code identifying the registry to edit (NOT its url). Run `cod imageRegistry list` to see codes." }),
156
+ url: core_1.Flags.string({ char: 'u', required: false, description: "The corrected container registry url." }),
157
+ private: core_1.Flags.boolean({ allowNo: true, description: 'Whether pulling from this registry requires authentication. Pass --private or --no-private only to change it; omit to leave it unchanged.' }),
158
+ silent: core_1.Flags.boolean({ exclusive: ["echo", "to-script"], description: 'Executes without any user interaction; fails on missing or invalid arguments.' }),
159
+ echo: core_1.Flags.boolean({ exclusive: ["to-script", "silent"], description: 'Renders the equivalent non-interactive command for future use before executing.' }),
160
+ "to-script": core_1.Flags.boolean({ exclusive: ["echo", "silent"], description: 'Renders the equivalent non-interactive command without executing it.' }),
161
+ };
162
+ ImageRegistryEdit.args = {};
163
+ //# sourceMappingURL=edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/commands/imageRegistry/edit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { ImageRegistry } from '../apis/codiac-api/contracts';
2
+ /**
3
+ * Resolves an image registry from a pre-fetched list by its Codiac **code**, throwing a
4
+ * message that steers the user back on track when the lookup fails.
5
+ *
6
+ * WHY this exists: `-r`/`--registry` (and `--chart-repo`) match `ImageRegistry.code`
7
+ * (e.g. `devCodiacContainers`, `DockerHub|codiacimages`), NOT the registry URL. Users
8
+ * routinely paste the URL (`devcodiaccontainers.azurecr.io`) and get a bare "not found"
9
+ * that reads like the registry was never registered at all. When the miss looks like a
10
+ * pasted URL, we detect the registry it actually belongs to and name its code instead.
11
+ *
12
+ * Callers pass the full registry list (a single `readMany({ all: true })`) so the by-URL
13
+ * suggestion can be computed without a second round-trip.
14
+ *
15
+ * @param all Every registry reference for the tenant (from `ImageRegistry.readMany`).
16
+ * @param codeHint The value the user supplied to `--registry` / `--chart-repo`.
17
+ * @param flagLabel The flag name to name in the error (e.g. `--registry`, `--chart-repo`).
18
+ * @returns The matching `ImageRegistry`.
19
+ * @throws If no registry has that code (message suggests the right code when the hint is a URL).
20
+ */
21
+ export declare function resolveRegistryByCodeOrThrow(all: ImageRegistry[], codeHint: string, flagLabel: string): ImageRegistry;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveRegistryByCodeOrThrow = void 0;
4
+ /**
5
+ * Resolves an image registry from a pre-fetched list by its Codiac **code**, throwing a
6
+ * message that steers the user back on track when the lookup fails.
7
+ *
8
+ * WHY this exists: `-r`/`--registry` (and `--chart-repo`) match `ImageRegistry.code`
9
+ * (e.g. `devCodiacContainers`, `DockerHub|codiacimages`), NOT the registry URL. Users
10
+ * routinely paste the URL (`devcodiaccontainers.azurecr.io`) and get a bare "not found"
11
+ * that reads like the registry was never registered at all. When the miss looks like a
12
+ * pasted URL, we detect the registry it actually belongs to and name its code instead.
13
+ *
14
+ * Callers pass the full registry list (a single `readMany({ all: true })`) so the by-URL
15
+ * suggestion can be computed without a second round-trip.
16
+ *
17
+ * @param all Every registry reference for the tenant (from `ImageRegistry.readMany`).
18
+ * @param codeHint The value the user supplied to `--registry` / `--chart-repo`.
19
+ * @param flagLabel The flag name to name in the error (e.g. `--registry`, `--chart-repo`).
20
+ * @returns The matching `ImageRegistry`.
21
+ * @throws If no registry has that code (message suggests the right code when the hint is a URL).
22
+ */
23
+ function resolveRegistryByCodeOrThrow(all, codeHint, flagLabel) {
24
+ const found = (all !== null && all !== void 0 ? all : []).find(r => r.code === codeHint);
25
+ if (found)
26
+ return found;
27
+ // Miss. Did they paste a URL instead of a code? Match against known registry urls,
28
+ // tolerating a missing scheme (index.docker.io vs https://index.docker.io).
29
+ const bare = codeHint.replace(/^[a-z]+:\/\//i, "");
30
+ const byUrl = (all !== null && all !== void 0 ? all : []).find(r => {
31
+ var _a;
32
+ const rBare = ((_a = r.url) !== null && _a !== void 0 ? _a : "").replace(/^[a-z]+:\/\//i, "");
33
+ return r.url === codeHint || rBare === bare || (bare.length > 3 && rBare.includes(bare));
34
+ });
35
+ const lead = `No image registry has code [${codeHint}]. The ${flagLabel} flag takes the registry CODE, not its URL.`;
36
+ const tail = byUrl
37
+ ? ` That looks like a URL — did you mean code [${byUrl.code}] (its url is ${byUrl.url})?`
38
+ : ` Run \`cod imageRegistry list\` to see the available codes (e.g. 'devCodiacContainers', not 'devcodiaccontainers.azurecr.io').`;
39
+ throw new Error(lead + tail);
40
+ }
41
+ exports.resolveRegistryByCodeOrThrow = resolveRegistryByCodeOrThrow;
42
+ //# sourceMappingURL=registry-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-resolver.js","sourceRoot":"","sources":["../../src/uilogic/registry-resolver.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,4BAA4B,CAAC,GAAoB,EAAE,QAAgB,EAAE,SAAiB;IACpG,MAAM,KAAK,GAAG,CAAC,GAAG,aAAH,GAAG,cAAH,GAAG,GAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACzD,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IAExB,mFAAmF;IACnF,4EAA4E;IAC5E,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,CAAC,GAAG,aAAH,GAAG,cAAH,GAAG,GAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;;QACjC,MAAM,KAAK,GAAG,CAAC,MAAA,CAAC,CAAC,GAAG,mCAAI,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACzD,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,+BAA+B,QAAQ,UAAU,SAAS,6CAA6C,CAAC;IACrH,MAAM,IAAI,GAAG,KAAK;QAChB,CAAC,CAAC,+CAA+C,KAAK,CAAC,IAAI,iBAAiB,KAAK,CAAC,GAAG,IAAI;QACzF,CAAC,CAAC,gIAAgI,CAAC;IACrI,MAAM,IAAI,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AAC/B,CAAC;AAjBD,oEAiBC"}
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.254",
2
+ "version": "1.3.256",
3
3
  "commands": {
4
4
  "branch": {
5
5
  "id": "branch",
@@ -2017,6 +2017,10 @@
2017
2017
  {
2018
2018
  "description": "Remove a deploy condition so the asset always deploys.",
2019
2019
  "command": "<%= config.bin %> <%= command.id %> -e myEnterprise -n my-api --remove-deploy-condition --silent"
2020
+ },
2021
+ {
2022
+ "description": "Re-point an asset at a corrected registry (by its Codiac code, not its url).",
2023
+ "command": "<%= config.bin %> <%= command.id %> -e myEnterprise -n my-api --registry devCodiacContainers --silent"
2020
2024
  }
2021
2025
  ],
2022
2026
  "flags": {
@@ -2044,6 +2048,14 @@
2044
2048
  "required": false,
2045
2049
  "multiple": false
2046
2050
  },
2051
+ "registry": {
2052
+ "name": "registry",
2053
+ "type": "option",
2054
+ "char": "r",
2055
+ "description": "Re-point this asset at a different container registry, given by its Codiac registry CODE (run `cod imageRegistry list`; NOT the registry url). Re-resolves the asset's embedded registry reference — use this after correcting a registry url so the asset picks up the fix.",
2056
+ "required": false,
2057
+ "multiple": false
2058
+ },
2047
2059
  "deploy-condition": {
2048
2060
  "name": "deploy-condition",
2049
2061
  "type": "option",
@@ -7445,6 +7457,96 @@
7445
7457
  },
7446
7458
  "args": {}
7447
7459
  },
7460
+ "imageRegistry:edit": {
7461
+ "id": "imageRegistry:edit",
7462
+ "description": "Changes the mutable attributes (url, private/public) of an existing container registry reference. The code, provider, and type are immutable.",
7463
+ "strict": true,
7464
+ "pluginName": "@codiac.io/codiac-cli",
7465
+ "pluginAlias": "@codiac.io/codiac-cli",
7466
+ "pluginType": "core",
7467
+ "aliases": [],
7468
+ "hiddenAliases": [],
7469
+ "examples": [
7470
+ {
7471
+ "description": "Edit a registry interactively (select it, then change its url).",
7472
+ "command": "<%= config.bin %> <%= command.id %>"
7473
+ },
7474
+ {
7475
+ "description": "Correct a registry's url (identified by its Codiac code, not its url).",
7476
+ "command": "<%= config.bin %> <%= command.id %> --registry devCodiacContainers --url newname.azurecr.io --silent"
7477
+ },
7478
+ {
7479
+ "description": "Flip a registry to public (no pull authentication).",
7480
+ "command": "<%= config.bin %> <%= command.id %> --registry 'Other|ghcr' --no-private --silent"
7481
+ },
7482
+ {
7483
+ "description": "Render the equivalent silent command without executing it.",
7484
+ "command": "<%= config.bin %> <%= command.id %> --registry devCodiacContainers --url newname.azurecr.io --to-script"
7485
+ }
7486
+ ],
7487
+ "flags": {
7488
+ "help": {
7489
+ "name": "help",
7490
+ "type": "boolean",
7491
+ "char": "h",
7492
+ "description": "Show CLI help.",
7493
+ "allowNo": false
7494
+ },
7495
+ "registry": {
7496
+ "name": "registry",
7497
+ "type": "option",
7498
+ "char": "r",
7499
+ "description": "The Codiac code identifying the registry to edit (NOT its url). Run `cod imageRegistry list` to see codes.",
7500
+ "required": false,
7501
+ "multiple": false
7502
+ },
7503
+ "url": {
7504
+ "name": "url",
7505
+ "type": "option",
7506
+ "char": "u",
7507
+ "description": "The corrected container registry url.",
7508
+ "required": false,
7509
+ "multiple": false
7510
+ },
7511
+ "private": {
7512
+ "name": "private",
7513
+ "type": "boolean",
7514
+ "description": "Whether pulling from this registry requires authentication. Pass --private or --no-private only to change it; omit to leave it unchanged.",
7515
+ "allowNo": true
7516
+ },
7517
+ "silent": {
7518
+ "name": "silent",
7519
+ "type": "boolean",
7520
+ "description": "Executes without any user interaction; fails on missing or invalid arguments.",
7521
+ "allowNo": false,
7522
+ "exclusive": [
7523
+ "echo",
7524
+ "to-script"
7525
+ ]
7526
+ },
7527
+ "echo": {
7528
+ "name": "echo",
7529
+ "type": "boolean",
7530
+ "description": "Renders the equivalent non-interactive command for future use before executing.",
7531
+ "allowNo": false,
7532
+ "exclusive": [
7533
+ "to-script",
7534
+ "silent"
7535
+ ]
7536
+ },
7537
+ "to-script": {
7538
+ "name": "to-script",
7539
+ "type": "boolean",
7540
+ "description": "Renders the equivalent non-interactive command without executing it.",
7541
+ "allowNo": false,
7542
+ "exclusive": [
7543
+ "echo",
7544
+ "silent"
7545
+ ]
7546
+ }
7547
+ },
7548
+ "args": {}
7549
+ },
7448
7550
  "imageRegistry:forget": {
7449
7551
  "id": "imageRegistry:forget",
7450
7552
  "description": "Removes the reference to the given container registry for the tenant. Does NOT delete the registry itself.",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@codiac.io/codiac-cli",
3
3
  "description": "Local command line interface for managing enterprise assets and environments.",
4
- "version": "1.3.254",
4
+ "version": "1.3.256",
5
5
  "author": "Codiac",
6
6
  "bin": {
7
7
  "codiac": "./bin/run",
@@ -33,7 +33,7 @@ Top-level: `branch`, `build`, `cli`, `commit`, `deploy`, `dep`, `identity`, `ini
33
33
  - **filestore**: `capture`, `forget`, `list`
34
34
  - **host**: `map`, `list`, `view`, `delete`
35
35
  - **identity**: `list`, `delete`
36
- - **imageRegistry**: `capture`, `forget`, `list`; `pullSecret set/unset`
36
+ - **imageRegistry**: `capture`, `edit`, `forget`, `list`; `pullSecret set/unset` *(`-r`/`--registry` and `--chart-repo` take the registry **code**, e.g. `devCodiacContainers`, NOT its url; `edit` fixes an existing registry's url in place)*
37
37
  - **images**: `add`, `list`, `patch`, `remove`, `version`, `version bump`
38
38
  - **import**: `cluster`
39
39
  - **kit**: `create`
@@ -74,9 +74,32 @@ Lifecycle:
74
74
  4. Inspect/operate: `cod asset list`, `cod asset view` (logs/term/exec/env/config/status),
75
75
  `cod asset undeploy`, `cod asset recycle`.
76
76
 
77
- **Image registries policy:** never AWS ECR. Images live in **Docker Hub** or **Azure
78
- Container Registry (ACR)**. Registries are captured as first-class objects
79
- (`cod imageRegistry ...`, `cod secretStore ...` for pull secrets).
77
+ **Image registries.** Never AWS ECR images live in **Docker Hub** or **Azure Container
78
+ Registry (ACR)** (plus generic OCI registries like ghcr/quay/Harbor via provider `other`).
79
+ A registry is a first-class object with two fields you must **not** conflate:
80
+
81
+ - **`code`** — the Codiac identifier you reference everywhere: `-r`/`--registry` on
82
+ `asset create`, `--chart-repo`, `asset edit --registry`. Its shape depends on how it was
83
+ captured — Azure ACR → the resource name (`devCodiacContainers`); Docker Hub →
84
+ `DockerHub|<org>` (`DockerHub|codiacimages`); generic OCI → `Other|<label>` (`Other|ghcr`);
85
+ Helm repo → `helm|<provider>|<name>` (`helm|artifactHub|hermes-agent`).
86
+ - **`url`** — the registry endpoint (`devCodiacContainers.azurecr.io`, `index.docker.io`).
87
+
88
+ `-r`/`--registry` matches the **code**, never the url. Passing the url
89
+ (`devCodiacContainers.azurecr.io`) fails with *"No image registry has code […]"* — which
90
+ reads like it was never registered. **Always `cod imageRegistry list` first** to read the
91
+ exact code.
92
+
93
+ Managing them: `cod imageRegistry capture` (add — create-only; it *throws* if the code already
94
+ exists), `cod imageRegistry edit` (fix an existing registry's **url** or private/public in
95
+ place — `code`/`provider`/`type` are immutable), `cod imageRegistry forget` (drop the
96
+ reference), `cod imageRegistry list`, and `cod imageRegistry pullSecret set/unset` for auth.
97
+ `cod secretStore ...` holds the pull secrets themselves.
98
+
99
+ **Gotcha — assets snapshot their registry.** An asset stores a *copy* of `image.registry`
100
+ (url included) at create time, and the deploy path reads that copy, not the registry record.
101
+ So after `cod imageRegistry edit` corrects a url, already-created assets still carry the old
102
+ one — run `cod asset edit --registry <code>` on each to re-resolve its embedded reference.
80
103
 
81
104
  The `type` of an asset (`helm` vs `service`) changes which config `targetFile`s apply (see §3):
82
105
  `[helm]` values for charts, `[env]`/`[footprint]`/etc. for services.