-
Notifications
You must be signed in to change notification settings - Fork 0
/
DockerUtils.js
141 lines (108 loc) · 4.21 KB
/
DockerUtils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import { promises as fs } from "fs";
import { createHash } from 'crypto';
import ExpiryMap from 'expiry-map';
import pMemoize from 'p-memoize';
import Dockerode from 'dockerode';
import { IsMain } from "utils";
import { NODE, HOST, dir, RERUN } from './CONFIG.js';
import { IMAGES } from './Command.js';
export const Hash = data => createHash('md5').update(JSON.stringify(data)).digest('hex');
export function StopSocatStartExpress(docker) {
console.log('Stopping socat, Starting express');
const Cmd = ["sh", "-c", 'docker stop socat && docker start express'];
async function wait(condition) {
console.log('waiting', condition);
while (condition !== await docker.ping()
.then(() => true)
.catch(() => process.stdout.write('=') && false));
await new Promise(resolve => setTimeout(resolve, 100));
console.log('\nwaited', condition);
}
return docker.createContainer({
Image: "docker",
Cmd,
HostConfig: {
Binds: [
'/var/run/docker.sock:/var/run/docker.sock',
],
},
}).then(async Container => {
console.log(Cmd, 'created');
await Container.start();
await wait(false);
await wait(true);
await Container.remove();
console.log('docker removed');
});
}
export async function Script(docker, Command, Data) {
const Container = Array.isArray(Data) ? Data.find(x => x.Names[0] === "/script") : true;
const SCRIPT = await fs.readFile(dir + "/Script.sh")
.then(data => {
const SCRIPT = Hash(data);
if (typeof Container === 'object' && Container.Labels.SCRIPT === SCRIPT);
else return SCRIPT;
});
//console.log({ SCRIPT });
if (RERUN.includes('script') || SCRIPT);
else
return Data;
console.log("script Container");
await Pull(docker);
Container && await docker.getContainer("script").remove()
.catch(console.log);
const Params = Command({
Image: "alpine",
name: "script",
Labels: { SCRIPT },
Cmd: ["wget", "-O", "Docker.sh", `https://${HOST}/Docker/Script.sh`],
});
const { Binds } = Params.HostConfig;
Binds[0] = Binds[0].replace(':ro', '');
await docker.createContainer(Params)
.then(Container => Container.start());
return Data;
}
const checkLatestDigests = pMemoize(image => {
let [repository, tag='latest'] = image.split(':');
if (!repository.includes('/'))
repository = 'library/' + repository;
console.log('Searching Docker Hub', { repository, tag });
return fetch(`https://registry.hub.docker.com/v2/repositories/${repository}/tags?` + new URLSearchParams({
name: tag || 'latest',
page_size: 1,
}))
.then(res => res.ok ? res.json() : Promise.reject(res))
.then(({ results: [{ images }] }) => [image, new Set(images.map(({ digest }) => digest))]);
}, {
cache: new ExpiryMap(60 * 1000),
});
export async function Pull(docker) {
let [localImages, ...latestDigests] = await Promise.all([
docker.listImages(),
...IMAGES.map(checkLatestDigests)
]);
localImages = localImages.map(({ Digests }) => Digests);
latestDigests = Object.fromEntries(latestDigests);
//console.log(localImages, latestDigests);
const pullRequests = IMAGES.filter(image => localImages.some(localImage => latestDigests[image].has(localImage)));
if (!pullRequests.length)
return console.log('All images are up to date');
console.log('Pulling', pullRequests);
const { followProgress, host } = docker.modem;
return Promise.all(pullRequests.map(Image => docker.pull(Image).then(stream => {
let args;
const promise = new Promise((..._args) => args = _args);
const [resolve, reject] = args;
followProgress(stream,
(error, output) => error ? reject(error) : resolve(output.pop().status),
({ status, id, progress }) => console.log(host, status, id, progress));
return promise;
})))
.then(console.log);
}
if (IsMain(
import.meta.url)) {
checkLatestDigests(IMAGES[0]);
Pull(new Dockerode());
}