Skip to content
This repository was archived by the owner on May 17, 2024. It is now read-only.

Commit 138b5bc

Browse files
committed
fix: add build store option and refactor bootup
1 parent 7dc52ce commit 138b5bc

9 files changed

+77
-77
lines changed

.dockerignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
/*.sqlite3
22
/Dockerfile
3-
/nixstore
3+
/nixroot
44
/node_modules

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
/demo.cast
66
/dist
77
/docs
8-
/nixstore
8+
/nixster.tgz
9+
/nixroot
910
/node_modules
10-
/node_modules.tar.gz

Makefile

+11-5
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,31 @@ docker:
2727
docker-push:
2828
docker push stencila/nixster
2929

30-
# Build the Nixster environments within the local `nixstore` directory
30+
# Build the Nixster environments within the local `nixroot` directory
3131
# Currently this builds the `multi-mega` environment but in the future it
32-
# may build all environments
32+
# may build all environments.
3333
# The --privileged flag is necessary to avoid `error: cloning builder process: Operation not permitted`
3434
# (see https://github.com/NixOS/nix/issues/2636 and other issues)
35+
# This mounts the local ./nixroot directory and tells Nixster (and thus Nix :) to build into it
3536
docker-build:
36-
docker run --rm --interactive --tty --volume $$PWD/nixstore:/nixstore --privileged stencila/nixster nixster build multi-mega
37+
docker run --rm --interactive --tty \
38+
--privileged \
39+
--volume $$PWD/nixroot:/nixroot \
40+
stencila/nixster nixster build multi-mega --store /nixroot
3741

3842
# Run the Nixster server
3943
docker-serve:
4044
docker run --rm --interactive --tty \
41-
--volume $$PWD/nixstore:/nixstore \
4245
--volume /var/run/docker.sock:/var/run/docker.sock \
4346
--publish 3000:3000 \
4447
stencila/nixster nixster serve
4548

4649
# Interact with the container in a Bash shell. Useful for debugging build errors
4750
docker-interact:
48-
docker run --rm --interactive --tty --volume $$PWD/nixstore:/nixstore --privileged stencila/nixster bash
51+
docker run --rm --interactive --tty \
52+
--privileged \
53+
--volume $$PWD/nixroot:/nixroot \
54+
stencila/nixster bash
4955

5056
docs:
5157
npm run docs

package-lock.json

+6-16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"cover": "jest --collectCoverage",
1414
"build": "npm run build:dist && npm run build:bins",
1515
"build:dist": "tsc && cp -TRv src/static/ dist/static/",
16-
"build:bins": "tar czf node_modules.tar.gz node_modules/better-sqlite3 node_modules/integer node_modules/node-pty && pkg --target=node10 --out-path=build .",
16+
"build:tgz": "tar czf nixster.tgz envs node_modules/better-sqlite3 node_modules/integer node_modules/node-pty",
17+
"build:bins": "npm run build:tgz && pkg --target=node10 --out-path=build .",
1718
"contributors:add": "all-contributors add",
1819
"docs": "markdown-toc -i --maxdepth=4 README.md && typedoc --readme README.md --mode file --out ./docs ./src",
1920
"serve:dev": "ts-node-dev src/cli.ts serve",
@@ -70,6 +71,7 @@
7071
"express": "^4.16.4",
7172
"express-async-handler": "^1.1.4",
7273
"express-ws": "^4.0.0",
74+
"fs-extra": "^7.0.1",
7375
"glob": "^7.1.3",
7476
"js-yaml": "^3.12.1",
7577
"mkdirp": "^0.5.1",
@@ -82,9 +84,8 @@
8284
},
8385
"pkg": {
8486
"assets": [
85-
"./envs/**/*",
8687
"./dist/static/**/*",
87-
"./node_modules.tar.gz"
88+
"./nixster.tgz"
8889
]
8990
}
9091
}

src/Environment.ts

+24-20
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@ import * as pty from 'node-pty'
1111
import tmp from 'tmp'
1212
import yaml from 'js-yaml'
1313

14+
import {home} from './boot'
1415
import spawn from './spawn'
1516
import * as nix from './nix'
1617

17-
// The home directory for environments
18-
let home = path.join(path.dirname(__dirname), 'envs')
19-
2018
export enum Platform {
2119
UNIX, WIN, DOCKER
2220
}
@@ -103,21 +101,11 @@ export default class Environment {
103101
if (read) this.read()
104102
}
105103

106-
/**
107-
* Get or set the ome directory for environments
108-
*
109-
* @param value Value for home directory
110-
*/
111-
static home (value?: string): string {
112-
if (value) home = value
113-
return home
114-
}
115-
116104
/**
117105
* Path to the environment specification files
118106
*/
119107
path (): string {
120-
return path.join(Environment.home(), this.name) + '.yaml'
108+
return path.join(home, 'envs', this.name + '.yaml')
121109
}
122110

123111
/**
@@ -137,7 +125,7 @@ export default class Environment {
137125
if (this.adds && this.adds.length === 0) this.adds = undefined
138126
if (this.removes && this.removes.length === 0) this.removes = undefined
139127

140-
mkdirp.sync(Environment.home())
128+
mkdirp.sync(path.join(home, 'envs'))
141129
const yml = yaml.safeDump(this, { skipInvalid: true })
142130
fs.writeFileSync(this.path(), yml)
143131
return this
@@ -180,13 +168,13 @@ export default class Environment {
180168
* List the environments on this machine
181169
*/
182170
static async envs (): Promise<Array<any>> {
183-
const names = glob.sync('*.yaml', { cwd: Environment.home() }).map(file => file.slice(0, -5))
171+
const names = glob.sync('*.yaml', { cwd: path.join(home, 'envs') }).map(file => file.slice(0, -5))
184172
const envs = []
185173
for (let name of names) {
186174
const env = new Environment(name)
187175
envs.push(Object.assign({}, env, {
188176
path: env.path(),
189-
built: await nix.built(name),
177+
built: await env.built(),
190178
location: await nix.location(name)
191179
}))
192180
}
@@ -313,8 +301,8 @@ export default class Environment {
313301
*
314302
* @param docker Also build a Docker container for the environment?
315303
*/
316-
async build (docker: boolean = false): Promise<Environment> {
317-
await nix.install(this.name, this.pkgs(), true)
304+
async build (store?: string, docker: boolean = false): Promise<Environment> {
305+
await nix.install(this.name, this.pkgs(), true, store)
318306

319307
if (docker) {
320308
// TODO: complete implementation of this, using these files...
@@ -337,6 +325,18 @@ export default class Environment {
337325
return this.write()
338326
}
339327

328+
/**
329+
* Has this environment been built?
330+
*/
331+
async built (): Promise<boolean> {
332+
try {
333+
await nix.location(this.name)
334+
return true
335+
} catch {
336+
return false
337+
}
338+
}
339+
340340
/**
341341
* Upgrade all packages in the environment
342342
*
@@ -358,7 +358,7 @@ export default class Environment {
358358
*
359359
* @param pure Should the shell that this command is executed in be 'pure'?
360360
*/
361-
async vars (pure: boolean = false) : Promise<{[key: string]: string}> {
361+
async vars (pure: boolean = false): Promise<{[key: string]: string}> {
362362
const location = await nix.location(this.name)
363363

364364
let PATH = `${location}/bin:${location}/sbin`
@@ -379,6 +379,8 @@ export default class Environment {
379379
* @param pure Should the shell that this command is executed in be 'pure'?
380380
*/
381381
async within (command: string, pure: boolean = false) {
382+
if (!this.built()) throw new Error(`Environment "${this.name}" has not be built yet.`)
383+
382384
// Get the path to bash because it may not be available in
383385
// the PATH of a pure shell
384386
let shell = await spawn('which', ['bash'])
@@ -395,6 +397,8 @@ export default class Environment {
395397
* @param sessionParameters Parameters of the session
396398
*/
397399
async enter (sessionParameters: SessionParameters) {
400+
if (!this.built()) throw new Error(`Environment "${this.name}" has not be built yet.`)
401+
398402
let { command, platform, pure, stdin, stdout } = sessionParameters
399403
const location = await nix.location(this.name)
400404

src/boot.ts

+13-16
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,21 @@
1313
* - https://github.com/JoshuaWise/better-sqlite3/issues/173
1414
* - `package.json`
1515
*/
16-
import fs from 'fs'
1716
import path from 'path'
1817

18+
import fs from 'fs-extra'
1919
import tar from 'tar'
20-
import mkdirp from 'mkdirp'
2120

22-
if (
23-
(process.mainModule && process.mainModule.id.endsWith('.exe') || process.hasOwnProperty('pkg')) &&
24-
fs.existsSync(path.join('/', 'snapshot'))
25-
) {
26-
const modules = path.join(path.dirname(process.execPath), 'node_modules')
27-
if (!fs.existsSync(modules)) {
28-
mkdirp.sync(modules)
29-
tar.x({
30-
sync: true,
31-
file: path.join('/', 'snapshot', 'nixster', 'node_modules.tar.gz'),
32-
strip: 1,
33-
C: modules
34-
})
35-
}
21+
export const packaged = (
22+
process.mainModule && process.mainModule.id.endsWith('.exe') || process.hasOwnProperty('pkg')
23+
) && fs.existsSync(path.join('/', 'snapshot'))
24+
25+
export const home = packaged ? path.dirname(process.execPath) : path.dirname(__dirname)
26+
27+
if(packaged && !fs.existsSync(path.join(home, 'node_modules'))) {
28+
tar.x({
29+
sync: true,
30+
file: path.join('/', 'snapshot', 'nixster', 'nixster.tgz'),
31+
C: home
32+
})
3633
}

src/cli.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,19 @@ yargs
178178
type: 'string'
179179
})
180180
.env('NIXSTER')
181+
.option('store', {
182+
describe: 'The Nix store to be built into.',
183+
type: 'string',
184+
alias: 's'
185+
})
181186
.option('docker', {
182187
describe: 'Also build a Docker container for the environment?',
183188
type: 'boolean',
184189
alias: 'd',
185190
default: false
186191
})
187192
}, async (argv: any) => {
188-
await new Environment(argv.name).build(argv.docker)
193+
await new Environment(argv.name).build(argv.store, argv.docker)
189194
info(`Environment "${argv.name}" built`)
190195
})
191196

0 commit comments

Comments
 (0)