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.
- package/lib/Lens.js +55 -21
- 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
|
|
114
|
-
|
|
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
|
-
|
|
122
|
-
|
|
118
|
+
logger.info(`found local image: ${containerQuery}@${imageInfo.Id}`);
|
|
119
|
+
return { hash: imageInfo.Id, isLocal: true };
|
|
123
120
|
} catch (err) {
|
|
124
|
-
//
|
|
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
|
-
|
|
138
|
-
|
|
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.
|
|
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",
|