forked from cloudfoundry-attic/garden-linux
-
Notifications
You must be signed in to change notification settings - Fork 0
/
running.go
126 lines (94 loc) · 3.35 KB
/
running.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
package linux_container
import (
"errors"
"fmt"
"os/exec"
"path"
"code.cloudfoundry.org/garden"
"code.cloudfoundry.org/garden-linux/process"
"code.cloudfoundry.org/lager"
)
func (c *LinuxContainer) Run(spec garden.ProcessSpec, processIO garden.ProcessIO) (garden.Process, error) {
wshPath := path.Join(c.ContainerPath, "bin", "wsh")
sockPath := path.Join(c.ContainerPath, "run", "wshd.sock")
if spec.User == "" {
c.logger.Error("linux_container: Run:", errors.New("linux_container: Run: A User for the process to run as must be specified."))
return nil, errors.New("A User for the process to run as must be specified.")
}
args := []string{"--socket", sockPath, "--readSignals", "--user", spec.User}
specEnv, err := process.NewEnv(spec.Env)
if err != nil {
return nil, err
}
procEnv, err := process.NewEnv(c.Env)
if err != nil {
return nil, err
}
processEnv := procEnv.Merge(specEnv)
for _, envVar := range processEnv.Array() {
args = append(args, "--env", envVar)
}
if spec.Dir != "" {
args = append(args, "--dir", spec.Dir)
}
processID := c.processIDPool.Next()
c.logger.Info("next pid", lager.Data{"pid": processID})
if c.Version.Compare(MissingVersion) == 0 {
pidfile := path.Join(c.ContainerPath, "processes", fmt.Sprintf("%d.pid", processID))
args = append(args, "--pidfile", pidfile)
}
args = append(args, spec.Path)
wsh := exec.Command(wshPath, append(args, spec.Args...)...)
setRLimitsEnv(wsh, spec.Limits)
return c.processTracker.Run(fmt.Sprintf("%d", processID), wsh, processIO, spec.TTY, c.processSignaller())
}
func (c *LinuxContainer) Attach(processID string, processIO garden.ProcessIO) (garden.Process, error) {
return c.processTracker.Attach(processID, processIO)
}
func setRLimitsEnv(cmd *exec.Cmd, rlimits garden.ResourceLimits) {
if rlimits.As != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_AS=%d", *rlimits.As))
}
if rlimits.Core != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_CORE=%d", *rlimits.Core))
}
if rlimits.Cpu != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_CPU=%d", *rlimits.Cpu))
}
if rlimits.Data != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_DATA=%d", *rlimits.Data))
}
if rlimits.Fsize != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_FSIZE=%d", *rlimits.Fsize))
}
if rlimits.Locks != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_LOCKS=%d", *rlimits.Locks))
}
if rlimits.Memlock != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_MEMLOCK=%d", *rlimits.Memlock))
}
if rlimits.Msgqueue != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_MSGQUEUE=%d", *rlimits.Msgqueue))
}
if rlimits.Nice != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_NICE=%d", *rlimits.Nice))
}
if rlimits.Nofile != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_NOFILE=%d", *rlimits.Nofile))
}
if rlimits.Nproc != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_NPROC=%d", *rlimits.Nproc))
}
if rlimits.Rss != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_RSS=%d", *rlimits.Rss))
}
if rlimits.Rtprio != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_RTPRIO=%d", *rlimits.Rtprio))
}
if rlimits.Sigpending != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_SIGPENDING=%d", *rlimits.Sigpending))
}
if rlimits.Stack != nil {
cmd.Env = append(cmd.Env, fmt.Sprintf("RLIMIT_STACK=%d", *rlimits.Stack))
}
}