UNPKG

3.68 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6const fs_1 = __importDefault(require("fs"));
7const path_1 = __importDefault(require("path"));
8const child_process_1 = require("child_process");
9const dockerode_1 = __importDefault(require("dockerode"));
10const js_yaml_1 = __importDefault(require("js-yaml"));
11const NixGenerator_1 = __importDefault(require("./NixGenerator"));
12const CachingUrlFetcher_1 = __importDefault(require("./CachingUrlFetcher"));
13const generator = new NixGenerator_1.default(new CachingUrlFetcher_1.default(), undefined);
14const docker = new dockerode_1.default();
15/**
16 * Generates a default.nix and a nixDockerfile for a `SoftwareEnvironment`
17 */
18function compile(environ, folder) {
19 // Generate .default.nix file
20 generator.generate(environ, folder);
21 // Figure out if a custom default.nix file is present
22 let defaultNix = path_1.default.join(folder, 'default.nix');
23 let dockterNix = path_1.default.join(folder, '.default.nix');
24 let nixfile = fs_1.default.existsSync(defaultNix) ? defaultNix : dockterNix;
25 // Generate .nixDockerfile
26 let dockerfile = path_1.default.join(folder, '.nixDockerfile');
27 fs_1.default.writeFileSync(dockerfile, `FROM nixos/nix
28
29# Copy over the Nix derivation
30COPY ${path_1.default.basename(nixfile)} default.nix
31# Run nix-shell
32CMD nix-shell --pure\n`);
33}
34/**
35 * Builds a Docker image from a nixDockerfile
36 */
37async function build(folder) {
38 let name = path_1.default.basename(folder).toLocaleLowerCase().replace(' ', '-');
39 // Figure out if a custom default.nix file is present
40 let defaultNix = path_1.default.join(folder, 'default.nix');
41 let dockterNix = path_1.default.join(folder, '.default.nix');
42 let nixfile = fs_1.default.existsSync(defaultNix) ? defaultNix : dockterNix;
43 // Start building the image
44 let build = await docker.buildImage({
45 context: folder,
46 src: ['.nixDockerfile', path_1.default.basename(nixfile)]
47 }, { t: name, dockerfile: '.nixDockerfile' });
48 // Wait for image to finish building
49 docker.modem.followProgress(build, (err, res) => {
50 if (err)
51 throw err;
52 output(res);
53 });
54}
55/**
56 * Executes nix-shell inside a Docker image from nixDockerfile with a Docker data volume for /nix store
57 */
58async function execute(folder, command = '') {
59 // Create shared /nix/store Docker volume if needed
60 let volumes = await docker.listVolumes();
61 let nixStoreVolume = volumes.Volumes.find((vol) => (vol.Name === 'nix-store'));
62 if (!nixStoreVolume) {
63 await docker.createVolume({ name: 'nix-store' });
64 }
65 let name = path_1.default.basename(folder).toLocaleLowerCase().replace(' ', '-');
66 let args = `run -it --rm -v /tmp:/tmp -v nix-store:/nix ${name}`;
67 // If there is a user specified command then run that within the Nix shell, otherwise
68 // will run the CMD from the Dockerfile
69 if (command)
70 args += ` /root/.nix-profile/bin/nix-shell --pure --run "${command.replace('"', '\\"')}"`;
71 child_process_1.spawnSync('docker', args.split(' '), {
72 shell: true,
73 cwd: process.cwd(),
74 stdio: 'inherit'
75 });
76}
77exports.default = { compile, build, execute };
78/**
79 * Print output to stdout
80 *
81 * @param object The object to print
82 * @param format The format use: `json` or `yaml`
83 */
84function output(object, format = 'json') {
85 if (object)
86 console.log(format === 'yaml' ? js_yaml_1.default.safeDump(object, { lineWidth: 120 }) : JSON.stringify(object, null, ' '));
87}