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
|
(async () => {
const fs = require('fs');
const os = require('os');
const path = require('path');
const pkg = require('./package.json');
const chalk = (await import('chalk')).default;
const YAML = require('yaml');
const uuid = require('uuid');
const cp = require('child_process');
let p;
function verbose(message) {
console.log(chalk.cyan("[snowjail] " + message));
}
function info(message) {
console.log(chalk.green("[snowjail] " + message));
}
function warning(message) {
console.log(chalk.yellow("[snowjail] " + message));
}
function fatal(message) {
console.log(chalk.red("[snowjail] " + message));
process.exit(1);
}
verbose("Starting Snowjail v" + pkg.version + "...");
warning("Moving to Podman (instead of Docker) is planned before v1.0.0, made sure you have both installed to keep running your applications smoothly");
if (process.argv[2] !== undefined && fs.existsSync(process.argv[2]) && fs.lstatSync(process.argv[2]).isDirectory()) {
global.root = path.resolve(process.argv[2]);
verbose("Loading from " + root + "...");
} else if (process.argv[2] !== undefined) {
if (fs.existsSync(process.argv[2])) {
fatal(process.argv[2] + ": not a directory");
} else {
fatal(process.argv[2] + ": not found");
}
} else {
fatal("missing operand");
}
if (!fs.existsSync(root + "/snowjail.yml") || (fs.existsSync(root + "/snowjail.yml") && !fs.lstatSync(root + "/snowjail.yml").isFile())) {
warning("Config not found, creating a default config file");
try {
fs.writeFileSync(root + "/snowjail.yml", fs.readFileSync(__dirname + "/default.yml").toString().replace("$VERSION$", pkg.version));
} catch (e) {
fatal("unable to create config: " + e.message);
}
}
try {
global.config = YAML.parse(fs.readFileSync(root + "/snowjail.yml").toString());
} catch (e) {
fatal("unable to load config: " + e.message);
}
verbose("Loaded config")
verbose("Checking config...")
// TODO: Check config for completeness
verbose("Locking config file...")
if (os.platform() === "darwin") {
cp.spawnSync("chflags", ["uchg", root]);
} else {
cp.spawnSync("chattr", ["+i", root]);
}
verbose("Creating jail...")
let jid = uuid.v4();
let hid = jid.replaceAll("-", "");
let args = ["create", "-h", "snowjail-" + hid, "-v", root + ":/snowjail/" + hid, "--name", "sj-" + jid, "-i", "-t"];
if (config.cpu > 0) {
args.push(...["-c", config.cpu]);
}
if (config.ram > 0) {
if (config.enforce_ram) {
args.push(...["-m", config.ram * 1048576]);
} else {
args.push(...["--memory-reservation", config.ram * 1048576]);
}
}
if (config.hardware) {
args.push("--privileged");
}
for (let port of config.ports) {
if (port.match(/^[0-9]{1,5}:[0-9]{1,5}$/g) !== null) {
args.push(...["-p", port]);
}
}
args.push(config.image);
p = cp.spawnSync("docker", args, { stdio: "inherit" });
if (p.exitCode !== 0 && p.exitCode !== undefined) {
fatal("unable to create jail: subprocess finished with non-zero exit code: " + p.exitCode);
}
verbose("Starting jail...")
p = cp.spawnSync("docker", ["start", "sj-" + jid], { stdio: "inherit" });
if (p.exitCode !== 0 && p.exitCode !== undefined) {
fatal("unable to start jail: subprocess finished with non-zero exit code: " + p.exitCode);
}
let index = 1;
for (let command of config.commands) {
info("Running command " + index + "/" + config.commands.length + ": " + command.join(" "));
p = cp.spawnSync("docker", ["exec", "-i", "-t", "sj-" + jid, ...command], { stdio: "inherit" });
if (p.exitCode !== 0 && p.exitCode !== undefined) {
fatal("unable to execute command: subprocess finished with non-zero exit code: " + p.exitCode);
}
index++;
}
verbose("Deleting jail...")
p = cp.spawnSync("docker", ["stop", "sj-" + jid], { stdio: "inherit" });
if (p.exitCode !== 0 && p.exitCode !== undefined) {
fatal("unable to delete jail: subprocess finished with non-zero exit code: " + p.exitCode);
}
p = cp.spawnSync("docker", ["rm", "sj-" + jid], { stdio: "inherit" });
if (p.exitCode !== 0 && p.exitCode !== undefined) {
fatal("unable to delete jail: subprocess finished with non-zero exit code: " + p.exitCode);
}
verbose("Unlocking config file...")
if (os.platform() === "darwin") {
cp.spawnSync("chflags", ["nouchg", root]);
} else {
cp.spawnSync("chattr", ["-i", root]);
}
})()
|