This repository has been archived by the owner on Jun 18, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sandbox.go
140 lines (113 loc) · 2.44 KB
/
sandbox.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package main
import (
"bufio"
"fmt"
"io"
"os"
"os/exec"
"path"
"strings"
"syscall"
)
const (
//EnvFile default location of env file
EnvFile = "/etc/env"
//BufferSize of data captured from the sandbox stdout stderr (tail)
BufferSize = 32 * 1024 // 32KB
)
func parseEnv(r io.Reader) ([]string, error) {
reader := bufio.NewReader(r)
var env []string
var err error
for err == nil {
var line string
line, err = reader.ReadString('\n')
log.Debugf("line: %s", line)
if err != nil && err != io.EOF {
return env, err
}
line = strings.TrimSpace(line)
if line == "" {
continue
}
if strings.HasPrefix(line, "#") {
continue
}
//TODO: some env line validation goes here
env = append(env, line)
}
return env, nil
}
func environ(root string) ([]string, error) {
name := path.Join(root, EnvFile)
log.Debugf("opening file: %s", name)
file, err := os.Open(name)
if os.IsNotExist(err) {
return nil, nil
} else if err != nil {
return nil, err
}
defer file.Close()
reader := bufio.NewReader(file)
var env []string
for err == nil {
var line string
line, err = reader.ReadString('\n')
log.Debugf("line: %s", line)
if err != nil && err != io.EOF {
return env, err
}
line = strings.TrimSpace(line)
if line == "" {
continue
}
if strings.HasPrefix(line, "#") {
continue
}
//TODO: some env line validation goes here
env = append(env, line)
}
return env, nil
}
type Sandbox struct {
Root string
UserEnv []string
EntryPoint string
Args []string
cmd *exec.Cmd
}
//Run runs the sandbox, blocks until the sandbox
//entry point exits
func (s *Sandbox) Run() ([]byte, []byte, error) {
log.Debugf("reading the env")
flistenv, err := environ(s.Root)
if err != nil {
return nil, nil, err
}
stdout := NewTailBuffer(BufferSize)
stderr := NewTailBuffer(BufferSize)
args := []string{s.EntryPoint}
args = append(args, s.Args...)
//start
cmd := exec.Cmd{
Path: s.EntryPoint,
Dir: "/",
Args: args,
Env: append(flistenv, s.UserEnv...),
SysProcAttr: &syscall.SysProcAttr{
Chroot: s.Root,
},
Stdout: io.MultiWriter(os.Stdout, stdout),
Stderr: io.MultiWriter(os.Stderr, stderr),
}
s.cmd = &cmd
err = cmd.Run()
return stdout.Bytes(), stderr.Bytes(), err
}
//Signal the sandbox process
func (s *Sandbox) Signal(signal os.Signal) error {
if s.cmd == nil || s.cmd.Process == nil {
return fmt.Errorf("sandbox is not started")
}
return s.cmd.Process.Signal(signal)
}