forked from ethereum/hive
-
Notifications
You must be signed in to change notification settings - Fork 4
/
shell.go
56 lines (50 loc) · 1.72 KB
/
shell.go
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
package main
import (
"os"
"os/signal"
"github.com/fsouza/go-dockerclient"
"gopkg.in/inconshreveable/log15.v2"
)
// mainInShell is the entry point into hive in the case where an outer docker
// container shell is requested. It assembles a new docker image from the entire
// project and just calls a hive instance within it.
//
// The end goal of this mechanism is preventing any leakage of junk (be that file
// system, docker images and/or containers, network traffic) into the host system.
func mainInShell(daemon *docker.Client, overrides []string) error {
// Build the image for the outer shell container and the container itself
log15.Info("creating outer shell container")
image, err := buildShell(daemon)
if err != nil {
return err
}
// Create the shell container and make sure it's deleted afterwards
shell, err := createShellContainer(daemon, image, overrides)
if err != nil {
log15.Error("failed to create shell container", "error", err)
return err
}
log15.Debug("created shell container")
defer func() {
log15.Debug("deleting shell container")
daemon.RemoveContainer(docker.RemoveContainerOptions{ID: shell.ID, Force: true})
}()
// Start up a hive instance within the shell
log15.Info("starting outer shell container")
waiter, err := runContainer(daemon, shell.ID, log15.Root(), "", true)
if err != nil {
log15.Error("failed to execute hive shell", "error", err)
return err
}
// Register an interrupt handler to cleanly tear the shell down
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
go func() {
<-interrupt
log15.Error("shell interrupted, stopping")
daemon.StopContainer(shell.ID, 0)
}()
// Wait for container termination and return
waiter.Wait()
return nil
}