@apiclient.xyz/docker
Version:
Provides easy communication with Docker remote API from Node.js, with TypeScript support.
112 lines • 13.7 kB
JavaScript
import * as plugins from './plugins.js';
import * as paths from './paths.js';
import { logger } from './logger.js';
const smartfileFactory = plugins.smartfile.SmartFileFactory.nodeFs();
export class DockerImageStore {
constructor(optionsArg) {
this.options = optionsArg;
}
// Method to store tar stream
async storeImage(imageName, tarStream) {
logger.log('info', `Storing image ${imageName}...`);
const uniqueProcessingId = plugins.smartunique.shortId();
const initialTarDownloadPath = plugins.path.join(this.options.localDirPath, `${uniqueProcessingId}.tar`);
const extractionDir = plugins.path.join(this.options.localDirPath, uniqueProcessingId);
// Create a write stream to store the tar file
const writeStream = plugins.fs.createWriteStream(initialTarDownloadPath);
// lets wait for the write stream to finish
await new Promise((resolve, reject) => {
tarStream.pipe(writeStream);
writeStream.on('finish', () => resolve());
writeStream.on('error', reject);
});
logger.log('info', `Image ${imageName} stored locally for processing. Extracting...`);
// lets process the image
await plugins.smartarchive.SmartArchive.create()
.file(initialTarDownloadPath)
.extract(extractionDir);
logger.log('info', `Image ${imageName} extracted.`);
await plugins.fs.promises.rm(initialTarDownloadPath, { force: true });
logger.log('info', `deleted original tar to save space.`);
logger.log('info', `now repackaging for s3...`);
const smartfileIndexJson = await smartfileFactory.fromFilePath(plugins.path.join(extractionDir, 'index.json'));
const smartfileManifestJson = await smartfileFactory.fromFilePath(plugins.path.join(extractionDir, 'manifest.json'));
const smartfileOciLayoutJson = await smartfileFactory.fromFilePath(plugins.path.join(extractionDir, 'oci-layout'));
// repositories file is optional in OCI image tars
const repositoriesPath = plugins.path.join(extractionDir, 'repositories');
const hasRepositories = plugins.fs.existsSync(repositoriesPath);
const smartfileRepositoriesJson = hasRepositories
? await smartfileFactory.fromFilePath(repositoriesPath)
: null;
const indexJson = JSON.parse(smartfileIndexJson.contents.toString());
const manifestJson = JSON.parse(smartfileManifestJson.contents.toString());
const ociLayoutJson = JSON.parse(smartfileOciLayoutJson.contents.toString());
if (indexJson.manifests?.[0]?.annotations) {
indexJson.manifests[0].annotations['io.containerd.image.name'] = imageName;
}
if (manifestJson?.[0]?.RepoTags) {
manifestJson[0].RepoTags[0] = imageName;
}
if (smartfileRepositoriesJson) {
const repositoriesJson = JSON.parse(smartfileRepositoriesJson.contents.toString());
const repoFirstKey = Object.keys(repositoriesJson)[0];
const repoFirstValue = repositoriesJson[repoFirstKey];
repositoriesJson[imageName] = repoFirstValue;
delete repositoriesJson[repoFirstKey];
smartfileRepositoriesJson.contents = Buffer.from(JSON.stringify(repositoriesJson, null, 2));
}
smartfileIndexJson.contents = Buffer.from(JSON.stringify(indexJson, null, 2));
smartfileManifestJson.contents = Buffer.from(JSON.stringify(manifestJson, null, 2));
smartfileOciLayoutJson.contents = Buffer.from(JSON.stringify(ociLayoutJson, null, 2));
const writePromises = [
smartfileIndexJson.write(),
smartfileManifestJson.write(),
smartfileOciLayoutJson.write(),
];
if (smartfileRepositoriesJson) {
writePromises.push(smartfileRepositoriesJson.write());
}
await Promise.all(writePromises);
logger.log('info', 'repackaging archive for s3...');
const tartools = new plugins.smartarchive.TarTools();
const newTarPack = await tartools.getDirectoryPackStream(extractionDir);
const finalTarName = `${uniqueProcessingId}.processed.tar`;
const finalTarPath = plugins.path.join(this.options.localDirPath, finalTarName);
const finalWriteStream = plugins.fs.createWriteStream(finalTarPath);
await new Promise((resolve, reject) => {
newTarPack.pipe(finalWriteStream);
finalWriteStream.on('finish', () => resolve());
finalWriteStream.on('error', reject);
});
logger.log('ok', `Repackaged image ${imageName} for s3.`);
await plugins.fs.promises.rm(extractionDir, { recursive: true, force: true });
// Remove existing file in bucket if it exists (smartbucket v4 no longer silently overwrites)
try {
await this.options.bucketDir.fastRemove({ path: `${imageName}.tar` });
}
catch (e) {
// File may not exist, which is fine
}
const finalTarReadStream = plugins.fs.createReadStream(finalTarPath);
await this.options.bucketDir.fastPutStream({
stream: finalTarReadStream,
path: `${imageName}.tar`,
});
await plugins.fs.promises.rm(finalTarPath, { force: true });
}
async start() {
// Ensure the local directory exists and is empty
await plugins.fs.promises.rm(this.options.localDirPath, { recursive: true, force: true });
await plugins.fs.promises.mkdir(this.options.localDirPath, { recursive: true });
}
async stop() { }
// Method to retrieve tar stream
async getImage(imageName) {
const imagePath = plugins.path.join(this.options.localDirPath, `${imageName}.tar`);
if (!plugins.fs.existsSync(imagePath)) {
throw new Error(`Image ${imageName} does not exist.`);
}
return plugins.fs.createReadStream(imagePath);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5pbWFnZXN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5pbWFnZXN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sS0FBSyxLQUFLLE1BQU0sWUFBWSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFHckMsTUFBTSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDO0FBYXJFLE1BQU0sT0FBTyxnQkFBZ0I7SUFHM0IsWUFBWSxVQUErQztRQUN6RCxJQUFJLENBQUMsT0FBTyxHQUFHLFVBQVUsQ0FBQztJQUM1QixDQUFDO0lBRUQsNkJBQTZCO0lBQ3RCLEtBQUssQ0FBQyxVQUFVLENBQ3JCLFNBQWlCLEVBQ2pCLFNBQThDO1FBRTlDLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGlCQUFpQixTQUFTLEtBQUssQ0FBQyxDQUFDO1FBQ3BELE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUV6RCxNQUFNLHNCQUFzQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUM5QyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFDekIsR0FBRyxrQkFBa0IsTUFBTSxDQUM1QixDQUFDO1FBQ0YsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQ3JDLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUN6QixrQkFBa0IsQ0FDbkIsQ0FBQztRQUNGLDhDQUE4QztRQUM5QyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsRUFBRSxDQUFDLGlCQUFpQixDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFFekUsMkNBQTJDO1FBQzNDLE1BQU0sSUFBSSxPQUFP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