-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
125 lines (94 loc) · 3.31 KB
/
index.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
import Emitter from 'events';
import { IsMain } from 'utils';
import { Docker } from './Portainer.js';
import DockerClass, { DefaultDockerClass } from './DockerClass.js';
import DockerClasses from './DockerClasses.js';
let Unpipe;
function Result(stream, { stdout } = process) {
Unpipe && Unpipe();
Unpipe = () => stream.unpipe(stdout);
setTimeout(Unpipe, 10000);
stream.pipe(process.stdout);
let data;
stream.on('data', _data => data = _data);
const { socket } = stream;
const destroy = socket.onerror;
return new Promise((resolve, reject) => {
socket.onerror = error => error.message === 'invalid status code: 1006' || reject(error);
socket.onclose = () => resolve(data);
})
.finally(destroy);
}
async function Work(container, emitter) {
try {
const Log = (...args) => console.log("Contaner", container.id, "has been", ...args);
Log("created");
const stream = await container.attach();
Log("attatched to");
emitter.emit('Stream', stream);
Result(stream)
.then(result => emitter.emit('Result', result))
.catch(error => console.log('rejected', error));
setImmediate(container.start.bind(container));
const { StatusCode: Code } = await container.wait();
Log("awaited", { Code });
emitter.emit('Code', Code);
}
catch (error) {
-
emitter.emit('error', error);
console.log(error);
}
finally {
if (container) {
emitter.emit('Finished');
//await container.remove({ force: true });
//console.log("Container", container.id, "has been removed");
//emitter.emit('Removed');
}
else
console.log("Failed to create ontainer");
}
}
function IterateDeep(obj, arg) {
Object.entries(obj).forEach(([key, value]) => {
const type = typeof value;
if (type === 'function')
obj[key] = value(arg);
else if (type === 'object')
IterateDeep(value, arg);
});
return obj;
}
async function Run(Options, arg) {
let dockerClass;
if (typeof arg === 'number')
dockerClass = DockerClasses.get(Number(arg));
else if (arg instanceof DockerClass)
dockerClass = arg;
const { docker } = dockerClass;
const container = await docker.createContainer({
...JSON.parse('{"AttachStdin": true, "AttachStdout": true, "AttachStderr": true, "Tty": false, "OpenStdin": true, "StdinOnce": true}'),
...IterateDeep(dockerClass.Command(Options), docker.Info),
});
const { id } = container;
const emitter = new Emitter();
Work(container, emitter)
.catch(console.log);
setImmediate(() => {
emitter.emit('Container', container);
emitter.emit('id', id);
container.inspect()
.then(({ Name }) => emitter.emit('Name', [Name.substr(1), id.substr(0, 12)].join('-')));
});
return emitter;
}
export { Docker };
export default Run;
IsMain(
import.meta.url) && DefaultDockerClass().then(dockerClass => Run({
Image: 'hello-world',
Cmd: [],
}, dockerClass))
.then(emitter => new Promise(resolve => emitter.once('Result', resolve)))
.then(data => console.log('Last test message', data.toString()));