-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuilder.cpp
79 lines (75 loc) · 2.42 KB
/
builder.cpp
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
#include <sys/stat.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <nlohmann/json.hpp>
#include <reproc++/run.hpp>
using namespace std;
using json = nlohmann::json;
json read_json(string fn) {
ifstream st(fn);
json j;
st >> j;
return j;
}
void copy_file(string from, string to) {
ifstream is(from);
ofstream os(to);
os << is.rdbuf();
}
// builder sandbox.json output
int main(int argc, char **argv) {
if (argc != 3) {
cerr << "Usage: builder sandbox.json output" << endl;
return EXIT_FAILURE;
}
auto sandbox_config = read_json(argv[1]);
string output = argv[2], url = sandbox_config["base"].get<string>();
if (mkdir(argv[2], 0666) && errno != EEXIST) {
cerr << "Error creating output directory" << endl;
return EXIT_FAILURE;
}
umask(0);
int status;
error_code ec;
vector<const char *> cmdline_dl{"curl", "-L", "-o", "rootfs.tar.gz", url.c_str(),
nullptr};
tie(status, ec) = reproc::run(cmdline_dl.data());
if (ec || status) {
cerr << "Download failed" << endl;
return EXIT_FAILURE;
}
cmdline_dl[4] = "https://github.com/MikeMirzayanov/testlib/raw/0.9.12/testlib.h";
cmdline_dl[3] = "testlib.h";
tie(status, ec) = reproc::run(cmdline_dl.data());
if(ec || status) {
cerr << "testlib.h download failed" << endl;
return EXIT_FAILURE;
}
vector<const char *> cmdline_extract{
"tar", "-x", "-f", "rootfs.tar.gz", "-C", output.c_str(), nullptr};
tie(status, ec) = reproc::run(cmdline_extract.data());
if (ec || status) {
cerr << "Extraction failed" << endl;
return EXIT_FAILURE;
}
mkdir((output + "/usr/include").c_str(), 0777);
copy_file("testlib.h", output + "/usr/include/testlib.h");
unlink("rootfs.tar.gz");
unlink("testlib.h");
copy_file("/etc/resolv.conf", output + "/etc/resolv.conf");
copy_file(argv[1], output + "/sandbox.json");
chroot(argv[2]);
chdir("/");
string env = string("PATH=/sbin:") + getenv("PATH");
putenv(env.data());
for (const auto &cmd : sandbox_config["run"]) {
system(cmd.get<string>().c_str());
}
for (const auto &[lang, prop] : sandbox_config["languages"].items()) {
cerr << "Installing " << lang << endl;
for (const auto &cmd : prop["install"]) {
system(cmd.get<string>().c_str());
}
}
}