hologit 0.46.1 → 0.46.2

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.
Files changed (2) hide show
  1. package/lib/Lens.js +55 -21
  2. package/package.json +1 -1
package/lib/Lens.js CHANGED
@@ -110,33 +110,46 @@ class Lens extends Configurable {
110
110
  }
111
111
  }
112
112
 
113
- async buildSpecForContainer (inputTree, config) {
114
- const { container: containerQuery } = config;
115
-
116
- // check if image exists locally first
117
- let imageHash;
113
+ async getImageHash (containerQuery) {
114
+ // Try local first (fastest)
118
115
  try {
119
116
  const inspectOutput = await Studio.execDocker(['inspect', containerQuery]);
120
117
  const imageInfo = JSON.parse(inspectOutput)[0];
121
- imageHash = imageInfo.Id;
122
- logger.info(`found local image: ${containerQuery}@${imageHash}`);
118
+ logger.info(`found local image: ${containerQuery}@${imageInfo.Id}`);
119
+ return { hash: imageInfo.Id, isLocal: true };
123
120
  } catch (err) {
124
- // image doesn't exist locally or can't be inspected, try pulling
125
- logger.info(`pulling image: ${containerQuery}`);
126
-
127
- try {
128
- await Studio.execDocker(['pull', containerQuery], { $relayStdout: true });
129
- const inspectOutput = await Studio.execDocker(['inspect', containerQuery]);
130
- const imageInfo = JSON.parse(inspectOutput)[0];
131
- imageHash = imageInfo.Id;
132
- } catch (err) {
133
- throw new Error(`failed to pull container image ${containerQuery}: ${err.message}`);
134
- }
121
+ // Not found locally, try remote manifest
135
122
  }
136
123
 
137
- if (!imageHash) {
138
- throw new Error(`failed to get hash for container image ${containerQuery}`);
124
+ // Try remote manifest (doesn't pull the image)
125
+ try {
126
+ logger.info(`querying remote manifest for: ${containerQuery}`);
127
+ const manifestOutput = await Studio.execDocker(['manifest', 'inspect', containerQuery]);
128
+ const manifest = JSON.parse(manifestOutput);
129
+
130
+ // Extract digest from manifest
131
+ // For multi-arch images, manifest.config.digest contains the config digest
132
+ // For single-arch images, we may need to look at the digest field
133
+ const digest = manifest.config?.digest || manifest.digest;
134
+
135
+ if (!digest) {
136
+ throw new Error('No digest found in manifest');
137
+ }
138
+
139
+ // Ensure the digest is in the format sha256:...
140
+ const imageHash = digest.startsWith('sha256:') ? digest : `sha256:${digest}`;
141
+ logger.info(`found remote image hash: ${containerQuery}@${imageHash}`);
142
+ return { hash: imageHash, isLocal: false };
143
+ } catch (err) {
144
+ throw new Error(`failed to get hash for container image ${containerQuery}: ${err.message}`);
139
145
  }
146
+ }
147
+
148
+ async buildSpecForContainer (inputTree, config) {
149
+ const { container: containerQuery } = config;
150
+
151
+ // Get image hash without pulling
152
+ const { hash: imageHash, isLocal } = await this.getImageHash(containerQuery);
140
153
 
141
154
  // build spec
142
155
  const data = {
@@ -152,7 +165,8 @@ class Lens extends Configurable {
152
165
  return {
153
166
  ...await SpecObject.write(this.workspace.getRepo(), 'lens', data),
154
167
  data,
155
- type: 'container'
168
+ type: 'container',
169
+ imageIsLocal: isLocal
156
170
  };
157
171
  }
158
172
 
@@ -317,6 +331,26 @@ class Lens extends Configurable {
317
331
  }
318
332
  const [, sha256Hash] = containerMatch;
319
333
 
334
+ // Ensure image is available locally
335
+ try {
336
+ await Studio.execDocker(['inspect', sha256Hash]);
337
+ } catch (err) {
338
+ // Image not found locally, need to pull it
339
+ // Extract the original container query from spec to pull by name:tag
340
+ const containerQueryMatch = spec.container.match(/^(.+)@sha256:[a-f0-9]{64}$/);
341
+ if (containerQueryMatch) {
342
+ const containerQuery = containerQueryMatch[1];
343
+ logger.info(`pulling required image: ${containerQuery}`);
344
+ try {
345
+ await Studio.execDocker(['pull', containerQuery], { $relayStdout: true });
346
+ } catch (pullErr) {
347
+ throw new Error(`failed to pull container image ${containerQuery}: ${pullErr.message}`);
348
+ }
349
+ } else {
350
+ throw new Error(`cannot extract container query from spec.container: ${spec.container}`);
351
+ }
352
+ }
353
+
320
354
  // create and start container
321
355
  const persistentDebugContainer = process.env.HOLO_DEBUG_PERSIST_CONTAINER;
322
356
  let containerId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hologit",
3
- "version": "0.46.1",
3
+ "version": "0.46.2",
4
4
  "description": "Hologit automates the projection of layered composite file trees based on flat, declarative plans",
5
5
  "repository": "https://github.com/EmergencePlatform/hologit",
6
6
  "main": "lib/index.js",