From d71060a2f19127ae481f26e08b74c6e6bf7900d7 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Thu, 2 Oct 2025 17:00:59 +0200 Subject: [PATCH] implement ContainerExport Signed-off-by: Nicolas De Loof --- README.md | 16 +++++++--------- lib/docker-client.ts | 27 +++++++++++++++++---------- lib/http.ts | 10 ++++++---- main.ts | 8 +------- 4 files changed, 31 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index be162ec..e7ecc9e 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ _tl;dr:_ You're free to use this code, make any changes you need, have fun with - [x] ContainerTop - [x] ContainerLogs - [x] ContainerChanges -- [ ] ContainerExport +- [x] ContainerExport - [x] ContainerStats - [x] ContainerResize - [x] ContainerStart @@ -50,7 +50,6 @@ _tl;dr:_ You're free to use this code, make any changes you need, have fun with - [x] ContainerPause - [x] ContainerUnpause - [x] ContainerAttach -- [ ] ContainerAttachWebsocket - [x] ContainerWait - [x] ContainerDelete - [x] ContainerArchiveInfo @@ -61,20 +60,20 @@ _tl;dr:_ You're free to use this code, make any changes you need, have fun with ### Image - [x] ImageList -- [ ] ImageBuild +- [x] ImageBuild - [x] BuildPrune - [x] ImageCreate - [x] ImageInspect - [x] ImageHistory -- [ ] ImagePush +- [x] ImagePush - [x] ImageTag - [x] ImageDelete - [ ] ImageSearch - [x] ImagePrune -- [ ] ImageCommit -- [ ] ImageGet -- [ ] ImageGetAll -- [ ] ImageLoad +- [x] ImageCommit +- [x] ImageGet +- [x] ImageGetAll +- [x] ImageLoad ### Network @@ -122,7 +121,6 @@ _tl;dr:_ You're free to use this code, make any changes you need, have fun with - [x] SystemInfo - [x] SystemVersion - [x] SystemPing -- [ ] SystemPingHead - [x] SystemEvents - [x] SystemDataUsage diff --git a/lib/docker-client.ts b/lib/docker-client.ts index 1fbcd54..61abe06 100644 --- a/lib/docker-client.ts +++ b/lib/docker-client.ts @@ -299,8 +299,8 @@ export class DockerClient { ) { await this.api.sendHTTPRequest('GET', '/events', { params: options, - callback: (data: Buffer) => { - data.toString('utf-8') + callback: (data: Buffer, encoding?: BufferEncoding) => { + data.toString(encoding) .split('\n') .filter((line) => line.trim() !== '') .forEach((line) => { @@ -489,11 +489,18 @@ export class DockerClient { /** * Export the contents of a container as a tarball. * Export a container - * @param options - * @param options.id ID or name of the container + * @param id ID or name of the container */ - public async containerExport(options?: { id: string }): Promise { - // TODO + public async containerExport( + id: string, + w: stream.Writable, + ): Promise { + return this.api.get( + `/containers/${id}/export`, + undefined, + 'application/x-tar', + (data: any) => w.write(data), + ); } /** @@ -1099,8 +1106,8 @@ export class DockerClient { }, buildContext, headers, - (data: Buffer) => { - data.toString('utf-8') + (data: Buffer, encoding?: BufferEncoding) => { + data.toString(encoding) .split('\n') .filter((line) => line.trim() !== '') .forEach((line) => { @@ -1203,8 +1210,8 @@ export class DockerClient { }, undefined, headers, - (data: Buffer) => { - data.toString('utf-8') + (data: Buffer, encoding?: BufferEncoding) => { + data.toString(encoding) .split('\n') .filter((line) => line.trim() !== '') .forEach((line) => { diff --git a/lib/http.ts b/lib/http.ts index 5b4168a..f33a4e8 100644 --- a/lib/http.ts +++ b/lib/http.ts @@ -101,7 +101,7 @@ export class HTTPClient { options?: { params?: Record; data?: any; - callback?: (data: Buffer, encoding?: string) => void; + callback?: (data: Buffer, encoding?: BufferEncoding) => void; accept?: string; headers?: Record; }, @@ -217,6 +217,8 @@ export class HTTPClient { const contentType = res.headers['content-type']; const { type: mimeType, charset } = parseContentType(contentType); + var encoding = (charset || 'utf8') as BufferEncoding; + const isDockerStream = mimeType === DOCKER_RAW_STREAM || mimeType === DOCKER_MULTIPLEXED_STREAM; @@ -224,7 +226,7 @@ export class HTTPClient { if (isDockerStream && callback) { // For upgrade protocols, forward all data directly to callback res.on('data', (data: Buffer) => { - callback(data, charset || 'utf8'); + callback(data, encoding); }); // Resolve immediately with upgrade response @@ -238,14 +240,14 @@ export class HTTPClient { callback ) { res.on('data', (chunk: Buffer) => { - callback(chunk, charset); + callback(chunk, encoding); }); res.on('end', () => handleResponseEnd()); } else { // Collect response body for non-streaming responses res.on('data', (chunk: Buffer) => { - responseBody += chunk.toString('utf8'); + responseBody += chunk.toString(encoding); }); res.on('end', () => handleResponseEnd(responseBody)); diff --git a/main.ts b/main.ts index ea66b63..9f603a7 100644 --- a/main.ts +++ b/main.ts @@ -18,14 +18,8 @@ try { return value.Id; }); - const fileinfo = await docker.containerArchiveInfo(ctr, '/etc/resolv.conf'); - console.dir(fileinfo, { depth: null }); - const out = fs.createWriteStream('/tmp/test.tar'); - await docker.containerArchive(ctr, '/etc/resolv.conf', out); - - const input = fs.createReadStream('/tmp/test.tar'); - await docker.putContainerArchive(ctr, '/etc', input); + await docker.containerExport(ctr, out); docker.close(); } catch (error) {