docker-storage-gc 4.0.1 → 4.0.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/.versionbot/CHANGELOG.yml +37 -1
- package/CHANGELOG.md +8 -0
- package/build/docker-event-stream.js +1 -3
- package/build/docker-event-stream.js.map +1 -1
- package/build/docker-image-tree.d.ts +1 -1
- package/build/docker-image-tree.js +1 -1
- package/build/docker-image-tree.js.map +1 -1
- package/build/docker.js +1 -2
- package/build/docker.js.map +1 -1
- package/build/index.d.ts +0 -1
- package/build/index.js +17 -17
- package/build/index.js.map +1 -1
- package/lib/docker-event-stream.ts +1 -3
- package/lib/docker-image-tree.ts +2 -2
- package/lib/docker.ts +1 -2
- package/lib/index.ts +33 -40
- package/package.json +3 -7
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
- commits:
|
|
2
|
+
- subject: Remove dependency on bluebird
|
|
3
|
+
hash: 943922d916cf5dccff6cc94ed497f3b4e29a6c07
|
|
4
|
+
body: ""
|
|
5
|
+
footer:
|
|
6
|
+
Change-type: patch
|
|
7
|
+
change-type: patch
|
|
8
|
+
author: Pagan Gazzard
|
|
9
|
+
- subject: Remove dependency on lodash
|
|
10
|
+
hash: 4354905941a3696024ae035528e2afbaf81e9fa2
|
|
11
|
+
body: ""
|
|
12
|
+
footer:
|
|
13
|
+
Change-type: patch
|
|
14
|
+
change-type: patch
|
|
15
|
+
author: Pagan Gazzard
|
|
16
|
+
- subject: Remove unnecessary check before deleting layer mtime info
|
|
17
|
+
hash: 5cc423ddf93e6f953dba90924dad8f9e1224ac9e
|
|
18
|
+
body: ""
|
|
19
|
+
footer:
|
|
20
|
+
Change-type: patch
|
|
21
|
+
change-type: patch
|
|
22
|
+
author: Pagan Gazzard
|
|
23
|
+
- subject: Make it clear that `getImagesToRemove` mutates the passed in tree
|
|
24
|
+
hash: ab023bacab8b2b74fdbd3448353079f46ecbb960
|
|
25
|
+
body: |
|
|
26
|
+
The function was already mutating everything other than the root level
|
|
27
|
+
and as we do not re-use the tree anywhere it is safe to keep the
|
|
28
|
+
mutation but this helps avoid issues being caused by future refactoring
|
|
29
|
+
that might not consider that
|
|
30
|
+
footer:
|
|
31
|
+
Change-type: patch
|
|
32
|
+
change-type: patch
|
|
33
|
+
author: Pagan Gazzard
|
|
34
|
+
version: 4.0.2
|
|
35
|
+
title: ""
|
|
36
|
+
date: 2023-12-07T13:44:12.633Z
|
|
1
37
|
- commits:
|
|
2
38
|
- subject: Use native promises with dockerode
|
|
3
39
|
hash: e437d1b00cbde9984187cd4fcf055c307df7fcde
|
|
@@ -15,7 +51,7 @@
|
|
|
15
51
|
author: Pagan Gazzard
|
|
16
52
|
version: 4.0.1
|
|
17
53
|
title: ""
|
|
18
|
-
date: 2023-12-05T22:
|
|
54
|
+
date: 2023-12-05T22:27:53.958Z
|
|
19
55
|
- commits:
|
|
20
56
|
- subject: Update to dockerode 3.x
|
|
21
57
|
hash: c6b5416ef2026eba121414cbd349d0717a6d3a68
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file
|
|
|
4
4
|
automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
|
|
5
5
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
|
7
|
+
# v4.0.2
|
|
8
|
+
## (2023-12-07)
|
|
9
|
+
|
|
10
|
+
* Remove dependency on bluebird [Pagan Gazzard]
|
|
11
|
+
* Remove dependency on lodash [Pagan Gazzard]
|
|
12
|
+
* Remove unnecessary check before deleting layer mtime info [Pagan Gazzard]
|
|
13
|
+
* Make it clear that `getImagesToRemove` mutates the passed in tree [Pagan Gazzard]
|
|
14
|
+
|
|
7
15
|
# v4.0.1
|
|
8
16
|
## (2023-12-05)
|
|
9
17
|
|
|
@@ -60,9 +60,7 @@ const parseEventStream = async (docker) => {
|
|
|
60
60
|
return es.pipeline(JSONStream_1.default.parse(undefined), es.mapSync(function ({ status, id, from, timeNano }) {
|
|
61
61
|
if (IMAGE_EVENTS.includes(status)) {
|
|
62
62
|
if (status === 'delete') {
|
|
63
|
-
|
|
64
|
-
delete layerMtimes[id];
|
|
65
|
-
}
|
|
63
|
+
delete layerMtimes[id];
|
|
66
64
|
}
|
|
67
65
|
else {
|
|
68
66
|
layerMtimes[id] = timeNano;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker-event-stream.js","sourceRoot":"","sources":["../lib/docker-event-stream.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAAmC;AACnC,4DAAoC;AAGpC,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAEjE,MAAM,gBAAgB,GAAG;IACxB,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,SAAS;IACT,KAAK;IACL,aAAa;IACb,YAAY;IACZ,QAAQ;IACR,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,OAAO;IACP,MAAM;IACN,KAAK;IACL,SAAS;CACT,CAAC;AA4BK,MAAM,gBAAgB,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;IACxD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,WAAW,GAAgB,EAAE,CAAC;IAKpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,EAAE,CAAC,QAAQ,CACjB,oBAAU,CAAC,KAAK,CAAC,SAAS,CAAwB,EAClD,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAe;QAC/D,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACzB,
|
|
1
|
+
{"version":3,"file":"docker-event-stream.js","sourceRoot":"","sources":["../lib/docker-event-stream.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAAmC;AACnC,4DAAoC;AAGpC,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAEjE,MAAM,gBAAgB,GAAG;IACxB,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,SAAS;IACT,KAAK;IACL,aAAa;IACb,YAAY;IACZ,QAAQ;IACR,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,OAAO;IACP,MAAM;IACN,KAAK;IACL,SAAS;CACT,CAAC;AA4BK,MAAM,gBAAgB,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;IACxD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,WAAW,GAAgB,EAAE,CAAC;IAKpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,EAAE,CAAC,QAAQ,CACjB,oBAAU,CAAC,KAAK,CAAC,SAAS,CAAwB,EAClD,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAe;QAC/D,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACzB,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACP,WAAW,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC;YAC5B,CAAC;QACF,CAAC;aAAM,IAAI,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9C,WAAW,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;QAC9B,CAAC;QACD,OAAO,WAAW,CAAC;IACpB,CAAC,CAAC,CACF,CAAC;AACH,CAAC,CAAC;AA1BW,QAAA,gBAAgB,oBA0B3B;AAEK,KAAK,UAAU,iBAAiB,CAAC,MAAc;IACrD,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAChD,MAAM,CAAC,SAAS,EAAE;QAClB,IAAA,wBAAgB,EAAC,MAAM,CAAC;KACxB,CAAC,CAAC;IACH,OAAO,EAAE,CAAC,QAAQ,CAAC,MAA6B,EAAE,YAAY,CAAC,CAAC;AACjE,CAAC;AAND,8CAMC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker-image-tree.js","sourceRoot":"","sources":["../lib/docker-image-tree.ts"],"names":[],"mappings":";;;AAGA,MAAM,aAAa,GAAG,UAAU,SAA+B;IAC9D,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACX,CAAC;IACD,IACC,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC;QACnC,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,EAClC,CAAC;QACF,OAAO,EAAE,CAAC;IACX,CAAC;SAAM,CAAC;QACP,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC,CAAC;AAEK,MAAM,UAAU,GAAG,CAAC,EAAU,EAAa,EAAE,CAAC,CAAC;IACrD,EAAE;IACF,IAAI,EAAE,CAAC;IACP,QAAQ,EAAE,EAAE;IACZ,WAAW,EAAE,EAAE;IACf,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"docker-image-tree.js","sourceRoot":"","sources":["../lib/docker-image-tree.ts"],"names":[],"mappings":"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"}
|
package/build/docker.js
CHANGED
|
@@ -5,9 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getDocker = void 0;
|
|
7
7
|
const dockerode_1 = __importDefault(require("dockerode"));
|
|
8
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
9
8
|
const getDockerConnectOpts = function (hostObj) {
|
|
10
|
-
if (
|
|
9
|
+
if (Object.keys(hostObj).length > 0) {
|
|
11
10
|
return hostObj;
|
|
12
11
|
}
|
|
13
12
|
return {
|
package/build/docker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../lib/docker.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA+B;
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../lib/docker.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA+B;AAE/B,MAAM,oBAAoB,GAAG,UAAU,OAA6B;IACnE,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,OAAO;QACN,UAAU,EAAE,sBAAsB;KAClC,CAAC;AACH,CAAC,CAAC;AAEF,SAAgB,SAAS,CAAC,OAA6B;IACtD,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC3C,OAAO,IAAI,mBAAM,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAHD,8BAGC"}
|
package/build/index.d.ts
CHANGED
package/build/index.js
CHANGED
|
@@ -3,8 +3,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const bluebird_1 = __importDefault(require("bluebird"));
|
|
7
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
8
6
|
const eventemitter3_1 = require("eventemitter3");
|
|
9
7
|
const docker_progress_1 = require("docker-progress");
|
|
10
8
|
const dockerode_1 = __importDefault(require("dockerode"));
|
|
@@ -13,10 +11,7 @@ const docker_image_tree_1 = require("./docker-image-tree");
|
|
|
13
11
|
const docker_1 = require("./docker");
|
|
14
12
|
const getUnusedTreeLeafs = function (tree, result = []) {
|
|
15
13
|
if (!tree.removed) {
|
|
16
|
-
const children =
|
|
17
|
-
.values()
|
|
18
|
-
.filter(lodash_1.default.negate(lodash_1.default.property('removed')))
|
|
19
|
-
.value();
|
|
14
|
+
const children = Object.values(tree.children).filter((n) => !n.removed);
|
|
20
15
|
if (children.length === 0 && !tree.isUsedByAContainer) {
|
|
21
16
|
result.push(tree);
|
|
22
17
|
}
|
|
@@ -28,12 +23,18 @@ const getUnusedTreeLeafs = function (tree, result = []) {
|
|
|
28
23
|
}
|
|
29
24
|
return result;
|
|
30
25
|
};
|
|
26
|
+
const sortBy = (key) => {
|
|
27
|
+
return (a, b) => (a[key] > b[key] ? 1 : b[key] > a[key] ? -1 : 0);
|
|
28
|
+
};
|
|
29
|
+
const mtimeSort = sortBy('mtime');
|
|
30
|
+
const sizeSort = sortBy('size');
|
|
31
31
|
const getImagesToRemove = function (tree, reclaimSpace, metrics) {
|
|
32
|
-
tree = lodash_1.default.clone(tree);
|
|
33
32
|
const result = [];
|
|
34
33
|
let size = 0;
|
|
35
34
|
while (size < reclaimSpace) {
|
|
36
|
-
const leafs =
|
|
35
|
+
const leafs = getUnusedTreeLeafs(tree).sort((a, b) => {
|
|
36
|
+
return mtimeSort(a, b) || -sizeSort(a, b);
|
|
37
|
+
});
|
|
37
38
|
if (leafs.length === 0) {
|
|
38
39
|
break;
|
|
39
40
|
}
|
|
@@ -139,22 +140,21 @@ class DockerGC {
|
|
|
139
140
|
throw err;
|
|
140
141
|
}
|
|
141
142
|
}
|
|
142
|
-
getOutput(image, command) {
|
|
143
|
-
|
|
143
|
+
async getOutput(image, command) {
|
|
144
|
+
const [, container] = await this.docker.run(image, command, undefined);
|
|
145
|
+
try {
|
|
144
146
|
const logs = await container.logs({ stdout: true, follow: true });
|
|
145
147
|
return await streamToString(logs);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
runDisposer(image, command) {
|
|
149
|
-
const containerPromise = this.docker.run(image, command, undefined);
|
|
150
|
-
return bluebird_1.default.resolve(containerPromise.then(([, container]) => container)).disposer(async (container) => {
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
151
150
|
await container.wait();
|
|
152
151
|
await container.remove();
|
|
153
|
-
}
|
|
152
|
+
}
|
|
154
153
|
}
|
|
155
154
|
async getDaemonFreeSpace() {
|
|
156
155
|
const baseImage = await this.baseImagePromise;
|
|
157
|
-
await this.dockerProgress.pull(baseImage,
|
|
156
|
+
await this.dockerProgress.pull(baseImage, () => {
|
|
157
|
+
});
|
|
158
158
|
const spaceStr = await this.getOutput(baseImage, [
|
|
159
159
|
'/bin/df',
|
|
160
160
|
'-B',
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -68,9 +68,7 @@ export const parseEventStream = async (docker: Docker) => {
|
|
|
68
68
|
es.mapSync(function ({ status, id, from, timeNano }: DockerEvent) {
|
|
69
69
|
if (IMAGE_EVENTS.includes(status)) {
|
|
70
70
|
if (status === 'delete') {
|
|
71
|
-
|
|
72
|
-
delete layerMtimes[id];
|
|
73
|
-
}
|
|
71
|
+
delete layerMtimes[id];
|
|
74
72
|
} else {
|
|
75
73
|
layerMtimes[id] = timeNano;
|
|
76
74
|
}
|
package/lib/docker-image-tree.ts
CHANGED
|
@@ -20,7 +20,7 @@ export const createNode = (id: string): ImageNode => ({
|
|
|
20
20
|
size: 0,
|
|
21
21
|
repoTags: [],
|
|
22
22
|
repoDigests: [],
|
|
23
|
-
mtime:
|
|
23
|
+
mtime: 0,
|
|
24
24
|
children: {},
|
|
25
25
|
});
|
|
26
26
|
|
|
@@ -45,7 +45,7 @@ export interface ImageNode {
|
|
|
45
45
|
size: number;
|
|
46
46
|
repoTags: string[];
|
|
47
47
|
repoDigests: string[];
|
|
48
|
-
mtime: LayerMtimes[string]
|
|
48
|
+
mtime: NonNullable<LayerMtimes[string]>;
|
|
49
49
|
children: Record<string, ImageNode>;
|
|
50
50
|
isUsedByAContainer?: boolean;
|
|
51
51
|
}
|
package/lib/docker.ts
CHANGED
package/lib/index.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import Bluebird, { Disposer } from 'bluebird';
|
|
2
|
-
import _ from 'lodash';
|
|
3
1
|
import { EventEmitter } from 'eventemitter3';
|
|
4
2
|
import { DockerProgress } from 'docker-progress';
|
|
5
3
|
import Docker from 'dockerode';
|
|
@@ -18,17 +16,15 @@ type Metrics = EventEmitter<Events>;
|
|
|
18
16
|
|
|
19
17
|
interface RemovableImageNode extends ImageNode {
|
|
20
18
|
removed?: true;
|
|
19
|
+
children: Record<string, RemovableImageNode>;
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
const getUnusedTreeLeafs = function (
|
|
24
23
|
tree: RemovableImageNode,
|
|
25
24
|
result: RemovableImageNode[] = [],
|
|
26
|
-
) {
|
|
25
|
+
): RemovableImageNode[] {
|
|
27
26
|
if (!tree.removed) {
|
|
28
|
-
const children =
|
|
29
|
-
.values()
|
|
30
|
-
.filter(_.negate(_.property('removed')))
|
|
31
|
-
.value();
|
|
27
|
+
const children = Object.values(tree.children).filter((n) => !n.removed);
|
|
32
28
|
if (children.length === 0 && !tree.isUsedByAContainer) {
|
|
33
29
|
result.push(tree);
|
|
34
30
|
} else {
|
|
@@ -40,22 +36,30 @@ const getUnusedTreeLeafs = function (
|
|
|
40
36
|
return result;
|
|
41
37
|
};
|
|
42
38
|
|
|
39
|
+
const sortBy = <T extends object>(key: keyof T): ((a: T, b: T) => number) => {
|
|
40
|
+
return (a, b) => (a[key] > b[key] ? 1 : b[key] > a[key] ? -1 : 0);
|
|
41
|
+
};
|
|
42
|
+
const mtimeSort = sortBy('mtime');
|
|
43
|
+
const sizeSort = sortBy('size');
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* This will mutate the passed in tree, marking the images to be removed as removed.
|
|
47
|
+
* Do not re-use the tree for multiple calls to this function as it will cause issues.
|
|
48
|
+
*/
|
|
43
49
|
const getImagesToRemove = function (
|
|
44
50
|
tree: RemovableImageNode,
|
|
45
51
|
reclaimSpace: number,
|
|
46
52
|
metrics: Metrics,
|
|
47
|
-
) {
|
|
53
|
+
): RemovableImageNode[] {
|
|
48
54
|
// Removes the oldest, largest leafs first.
|
|
49
55
|
// This should avoid trying to remove images with children.
|
|
50
|
-
tree = _.clone(tree);
|
|
51
56
|
const result = [];
|
|
52
57
|
let size = 0;
|
|
53
58
|
while (size < reclaimSpace) {
|
|
54
|
-
const leafs =
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
);
|
|
59
|
+
const leafs = getUnusedTreeLeafs(tree).sort((a, b) => {
|
|
60
|
+
// mtime asc, size desc
|
|
61
|
+
return mtimeSort(a, b) || -sizeSort(a, b);
|
|
62
|
+
});
|
|
59
63
|
if (leafs.length === 0) {
|
|
60
64
|
break;
|
|
61
65
|
}
|
|
@@ -199,33 +203,20 @@ export default class DockerGC {
|
|
|
199
203
|
}
|
|
200
204
|
}
|
|
201
205
|
|
|
202
|
-
private getOutput(image: string, command: string[]): Promise<string> {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
image: string,
|
|
214
|
-
command: string[],
|
|
215
|
-
): Disposer<Docker.Container> {
|
|
216
|
-
const containerPromise: Promise<[unknown, Docker.Container]> =
|
|
217
|
-
this.docker.run(
|
|
218
|
-
image,
|
|
219
|
-
command,
|
|
220
|
-
// @ts-expect-error -- The typings expect an array of streams but in reality they're optional
|
|
221
|
-
undefined,
|
|
222
|
-
);
|
|
223
|
-
return Bluebird.resolve(
|
|
224
|
-
containerPromise.then(([, container]) => container),
|
|
225
|
-
).disposer(async (container) => {
|
|
206
|
+
private async getOutput(image: string, command: string[]): Promise<string> {
|
|
207
|
+
const [, container] = await (this.docker.run(
|
|
208
|
+
image,
|
|
209
|
+
command,
|
|
210
|
+
// @ts-expect-error -- The typings expect an array of streams but in reality they're optional
|
|
211
|
+
undefined,
|
|
212
|
+
) as Promise<[unknown, Docker.Container]>);
|
|
213
|
+
try {
|
|
214
|
+
const logs = await container.logs({ stdout: true, follow: true });
|
|
215
|
+
return await streamToString(logs);
|
|
216
|
+
} finally {
|
|
226
217
|
await container.wait();
|
|
227
218
|
await container.remove();
|
|
228
|
-
}
|
|
219
|
+
}
|
|
229
220
|
}
|
|
230
221
|
|
|
231
222
|
public async getDaemonFreeSpace(): Promise<{
|
|
@@ -236,7 +227,9 @@ export default class DockerGC {
|
|
|
236
227
|
const baseImage = await this.baseImagePromise;
|
|
237
228
|
|
|
238
229
|
// Ensure the image is available (if it is this is essentially a no-op)
|
|
239
|
-
await this.dockerProgress.pull(baseImage,
|
|
230
|
+
await this.dockerProgress.pull(baseImage, () => {
|
|
231
|
+
// noop
|
|
232
|
+
});
|
|
240
233
|
|
|
241
234
|
const spaceStr = await this.getOutput(baseImage, [
|
|
242
235
|
'/bin/df',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docker-storage-gc",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"main": "build/index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"lint": "balena-lint -t tsconfig.dev.json -e ts -e js lib test tools",
|
|
@@ -14,19 +14,15 @@
|
|
|
14
14
|
"license": "Apache 2.0",
|
|
15
15
|
"description": "Automatically cleanup unused images based on various cache replacement algorithms",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@types/bluebird": "^3.5.42",
|
|
18
17
|
"@types/dockerode": "^3.3.23",
|
|
19
18
|
"@types/event-stream": "^4.0.5",
|
|
20
19
|
"@types/JSONStream": "npm:@types/jsonstream@^0.8.31",
|
|
21
|
-
"@types/lodash": "^4.14.202",
|
|
22
20
|
"@types/node": "^16.18.65",
|
|
23
|
-
"bluebird": "^3.7.2",
|
|
24
21
|
"docker-progress": "^5.2.0",
|
|
25
22
|
"dockerode": "^3.3.5",
|
|
26
23
|
"event-stream": "^4.0.1",
|
|
27
24
|
"eventemitter3": "^5.0.1",
|
|
28
|
-
"JSONStream": "^1.3.5"
|
|
29
|
-
"lodash": "^4.17.21"
|
|
25
|
+
"JSONStream": "^1.3.5"
|
|
30
26
|
},
|
|
31
27
|
"devDependencies": {
|
|
32
28
|
"@balena/lint": "^7.2.4",
|
|
@@ -39,6 +35,6 @@
|
|
|
39
35
|
"typescript": "^5.3.2"
|
|
40
36
|
},
|
|
41
37
|
"versionist": {
|
|
42
|
-
"publishedAt": "2023-12-
|
|
38
|
+
"publishedAt": "2023-12-07T13:44:12.762Z"
|
|
43
39
|
}
|
|
44
40
|
}
|