Compare commits

...

10 Commits

5 changed files with 355 additions and 247 deletions

View File

@ -1,5 +1,32 @@
# Changelog
## 2024-12-23 - 1.3.0 - feat(core)
Initial release of Docker client with TypeScript support
- Provides easy communication with Docker's remote API from Node.js
- Includes implementations for managing Docker services, networks, secrets, containers, and images
## 2024-12-23 - 1.2.8 - fix(core)
Improved the image creation process from tar stream in DockerImage class.
- Enhanced `DockerImage.createFromTarStream` method to handle streamed response and parse imported image details.
- Fixed the dependency version for `@push.rocks/smartarchive` in package.json.
## 2024-10-13 - 1.2.7 - fix(core)
Prepare patch release with minor fixes and improvements
## 2024-10-13 - 1.2.6 - fix(core)
Minor refactoring and code quality improvements.
## 2024-10-13 - 1.2.5 - fix(dependencies)
Update dependencies for stability improvements
- Updated @push.rocks/smartstream to version ^3.0.46
- Updated @push.rocks/tapbundle to version ^5.3.0
- Updated @types/node to version 22.7.5
## 2024-10-13 - 1.2.4 - fix(core)
Refactored DockerImageStore constructor to remove DockerHost dependency

View File

@ -1,6 +1,6 @@
{
"name": "@apiclient.xyz/docker",
"version": "1.2.4",
"version": "1.3.0",
"description": "Provides easy communication with Docker remote API from Node.js, with TypeScript support.",
"private": false,
"main": "dist_ts/index.js",
@ -34,7 +34,7 @@
"homepage": "https://gitlab.com/mojoio/docker#readme",
"dependencies": {
"@push.rocks/lik": "^6.0.15",
"@push.rocks/smartarchive": "^4.0.37",
"@push.rocks/smartarchive": "^4.0.39",
"@push.rocks/smartbucket": "^3.0.22",
"@push.rocks/smartfile": "^11.0.21",
"@push.rocks/smartjson": "^5.0.20",
@ -43,7 +43,7 @@
"@push.rocks/smartpath": "^5.0.18",
"@push.rocks/smartpromise": "^4.0.4",
"@push.rocks/smartrequest": "^2.0.22",
"@push.rocks/smartstream": "^3.0.44",
"@push.rocks/smartstream": "^3.0.46",
"@push.rocks/smartstring": "^4.0.15",
"@push.rocks/smartunique": "^3.0.9",
"@push.rocks/smartversion": "^3.0.5",
@ -55,8 +55,8 @@
"@git.zone/tsrun": "^1.2.49",
"@git.zone/tstest": "^1.0.90",
"@push.rocks/qenv": "^6.0.5",
"@push.rocks/tapbundle": "^5.0.24",
"@types/node": "22.4.2"
"@push.rocks/tapbundle": "^5.3.0",
"@types/node": "22.7.5"
},
"files": [
"ts/**/*",

469
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@apiclient.xyz/docker',
version: '1.2.4',
version: '1.3.0',
description: 'Provides easy communication with Docker remote API from Node.js, with TypeScript support.'
}

View File

@ -82,14 +82,94 @@ export class DockerImage {
* @param dockerHostArg
* @param tarStreamArg
*/
public static async createFromTarStream(dockerHostArg: DockerHost, optionsArg: {
creationObject: interfaces.IImageCreationDescriptor,
tarStream: plugins.smartstream.stream.Readable,
}) {
const response = await dockerHostArg.requestStreaming('POST', '/images/load', optionsArg.tarStream);
return response;
public static async createFromTarStream(
dockerHostArg: DockerHost,
optionsArg: {
creationObject: interfaces.IImageCreationDescriptor;
tarStream: plugins.smartstream.stream.Readable;
}
): Promise<DockerImage> {
// Start the request for importing an image
const response = await dockerHostArg.requestStreaming(
'POST',
'/images/load',
optionsArg.tarStream
);
/**
* Docker typically returns lines like:
* {"stream":"Loaded image: myrepo/myimage:latest"}
*
* So we will collect those lines and parse out the final image name.
*/
let rawOutput = '';
response.on('data', (chunk) => {
rawOutput += chunk.toString();
});
// Wrap the end event in a Promise for easier async/await usage
await new Promise<void>((resolve, reject) => {
response.on('end', () => {
resolve();
});
response.on('error', (err) => {
reject(err);
});
});
// Attempt to parse each line to find something like "Loaded image: ..."
let loadedImageTag: string | undefined;
const lines = rawOutput.trim().split('\n').filter(Boolean);
for (const line of lines) {
try {
const jsonLine = JSON.parse(line);
if (
jsonLine.stream &&
(jsonLine.stream.startsWith('Loaded image:') ||
jsonLine.stream.startsWith('Loaded image ID:'))
) {
// Examples:
// "Loaded image: your-image:latest"
// "Loaded image ID: sha256:...."
loadedImageTag = jsonLine.stream
.replace('Loaded image: ', '')
.replace('Loaded image ID: ', '')
.trim();
}
} catch {
// not valid JSON, ignore
}
}
if (!loadedImageTag) {
throw new Error(
`Could not parse the loaded image info from Docker response.\nResponse was:\n${rawOutput}`
);
}
// Now try to look up that image by the "loadedImageTag".
// Depending on Dockers response, it might be something like:
// "myrepo/myimage:latest" OR "sha256:someHash..."
// If Docker gave you an ID (e.g. "sha256:..."), you may need a separate
// DockerImage.getImageById method; or if you prefer, you can treat it as a name.
const newlyImportedImage = await DockerImage.getImageByName(dockerHostArg, loadedImageTag);
if (!newlyImportedImage) {
throw new Error(
`Image load succeeded, but no local reference found for "${loadedImageTag}".`
);
}
logger.log(
'info',
`Successfully imported image "${loadedImageTag}".`
);
return newlyImportedImage;
}
public static async tagImageByIdOrName(
dockerHost: DockerHost,
idOrNameArg: string,
@ -99,6 +179,8 @@ export class DockerImage {
'POST',
`/images/${encodeURIComponent(idOrNameArg)}/${encodeURIComponent(newTagArg)}`
);
}
public static async buildImage(dockerHostArg: DockerHost, dockerImageTag) {