@@ -26,6 +26,33 @@ export enum ContainerStatus {
26
26
const DOCKER_DEFAULT_COMMAND = 'sh'
27
27
const DOCKER_CONTAINER_ID_SHORT_LENGTH = 12
28
28
29
+ interface ContainerMount {
30
+ /**
31
+ * The path inside the container
32
+ */
33
+ destination : string
34
+
35
+ /**
36
+ * The path on the host
37
+ */
38
+ source : string
39
+
40
+ /**
41
+ * Mount options (e.g. rw/ro)
42
+ */
43
+ options : Array < string >
44
+ }
45
+
46
+ /**
47
+ * Convert a ContainerMount to a --volume argument that can be passed to docker
48
+ * @param containerMount
49
+ */
50
+ function containerMountToVolumeArg ( containerMount : ContainerMount ) : Array < string > {
51
+ const options = containerMount . options . join ( ',' )
52
+
53
+ return [ '--volume' , `${ containerMount . source } :${ containerMount . destination } :${ options } ` ]
54
+ }
55
+
29
56
/**
30
57
* Parameters of a user session inside an environment
31
58
*/
@@ -73,6 +100,11 @@ export class SessionParameters {
73
100
* will start a new container.
74
101
*/
75
102
containerId : string = ''
103
+
104
+ /**
105
+ * Volumes to mount inside a container
106
+ */
107
+ mounts : Array < ContainerMount > = [ ]
76
108
}
77
109
78
110
let ENVIRONS_HOME = path . join ( home , 'envs' )
@@ -459,7 +491,7 @@ export default class Environment {
459
491
private getDockerRunCommand ( sessionParameters : SessionParameters , daemonize : boolean = false ) : Array < string > {
460
492
const { command, cpuShares, memoryLimit } = sessionParameters
461
493
const nixLocation = nix . location ( this . name )
462
- const shellArgs = [
494
+ let shellArgs = [
463
495
'run' , '--interactive' , '--tty' , '--rm' ,
464
496
// Prepend the environment path to the PATH variable
465
497
'--env' , `PATH=${ nixLocation } /bin:${ nixLocation } /sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin` ,
@@ -470,19 +502,25 @@ export default class Environment {
470
502
// Apply CPU shares
471
503
`--cpu-shares=${ cpuShares } ` ,
472
504
// Apply memory limit
473
- `--memory=${ memoryLimit } ` ,
474
- // We use Alpine Linux as a base image because it is very small but has some basic
475
- // shell utilities (lkike ls and uname) that are good for debugging but also sometimes
476
- // required for things like R
477
- 'alpine'
478
- ] . concat (
479
- // Command to execute in the container
480
- command ? command . split ( ' ' ) : DOCKER_DEFAULT_COMMAND
481
- )
505
+ `--memory=${ memoryLimit } `
506
+ ]
507
+
508
+ sessionParameters . mounts . map ( ( mount : ContainerMount ) => {
509
+ const volumeArgs = containerMountToVolumeArg ( mount )
510
+ shellArgs = shellArgs . concat ( volumeArgs )
511
+ } )
482
512
483
513
if ( daemonize ) shellArgs . splice ( 1 , 0 , '-d' )
484
514
485
- return shellArgs
515
+ // We use Alpine Linux as a base image because it is very small but has some basic
516
+ // shell utilities (lkike ls and uname) that are good for debugging but also sometimes
517
+ // required for things like R
518
+ shellArgs . push ( 'alpine' )
519
+
520
+ return shellArgs . concat (
521
+ // Command to execute in the container
522
+ command ? command . split ( ' ' ) : DOCKER_DEFAULT_COMMAND
523
+ )
486
524
}
487
525
488
526
/**
0 commit comments