|
17 | 17 | package containerd |
18 | 18 |
|
19 | 19 | import ( |
| 20 | + "bufio" |
20 | 21 | "bytes" |
21 | 22 | "context" |
| 23 | + "fmt" |
22 | 24 | "io/ioutil" |
23 | 25 | "os" |
24 | 26 | "os/exec" |
25 | 27 | "path/filepath" |
| 28 | + "strings" |
26 | 29 | "syscall" |
27 | 30 | "testing" |
28 | 31 | "time" |
@@ -170,3 +173,81 @@ func TestDaemonRuntimeRoot(t *testing.T) { |
170 | 173 | } |
171 | 174 | <-status |
172 | 175 | } |
| 176 | + |
| 177 | +// code most copy from https://github.com/opencontainers/runc |
| 178 | +func getCgroupPath() (map[string]string, error) { |
| 179 | + cgroupPath := make(map[string]string) |
| 180 | + f, err := os.Open("/proc/self/mountinfo") |
| 181 | + if err != nil { |
| 182 | + return nil, err |
| 183 | + } |
| 184 | + defer f.Close() |
| 185 | + |
| 186 | + scanner := bufio.NewScanner(f) |
| 187 | + for scanner.Scan() { |
| 188 | + text := scanner.Text() |
| 189 | + fields := strings.Split(text, " ") |
| 190 | + // Safe as mountinfo encodes mountpoints with spaces as \040. |
| 191 | + index := strings.Index(text, " - ") |
| 192 | + postSeparatorFields := strings.Fields(text[index+3:]) |
| 193 | + numPostFields := len(postSeparatorFields) |
| 194 | + |
| 195 | + // This is an error as we can't detect if the mount is for "cgroup" |
| 196 | + if numPostFields == 0 { |
| 197 | + continue |
| 198 | + } |
| 199 | + |
| 200 | + if postSeparatorFields[0] == "cgroup" { |
| 201 | + // Check that the mount is properly formatted. |
| 202 | + if numPostFields < 3 { |
| 203 | + continue |
| 204 | + } |
| 205 | + cgroupPath[filepath.Base(fields[4])] = fields[4] |
| 206 | + } |
| 207 | + } |
| 208 | + |
| 209 | + return cgroupPath, nil |
| 210 | +} |
| 211 | + |
| 212 | +// TestDaemonCustomCgroup ensures plugin.cgroup.path is not ignored |
| 213 | +func TestDaemonCustomCgroup(t *testing.T) { |
| 214 | + cgroupPath, err := getCgroupPath() |
| 215 | + if err != nil { |
| 216 | + t.Fatal(err) |
| 217 | + } |
| 218 | + if len(cgroupPath) == 0 { |
| 219 | + t.Skip("skip TestDaemonCustomCgroup since no cgroup path available") |
| 220 | + } |
| 221 | + |
| 222 | + customCgroup := fmt.Sprintf("%d", time.Now().Nanosecond()) |
| 223 | + configTOML := ` |
| 224 | +[cgroup] |
| 225 | + path = "` + customCgroup + `"` |
| 226 | + |
| 227 | + _, _, cleanup := newDaemonWithConfig(t, configTOML) |
| 228 | + |
| 229 | + defer func() { |
| 230 | + // do cgroup path clean |
| 231 | + for _, v := range cgroupPath { |
| 232 | + if _, err := os.Stat(filepath.Join(v, customCgroup)); err == nil { |
| 233 | + if err := os.RemoveAll(filepath.Join(v, customCgroup)); err != nil { |
| 234 | + t.Logf("failed to remove cgroup path %s", filepath.Join(v, customCgroup)) |
| 235 | + } |
| 236 | + } |
| 237 | + } |
| 238 | + }() |
| 239 | + |
| 240 | + defer cleanup() |
| 241 | + |
| 242 | + for k, v := range cgroupPath { |
| 243 | + if k == "rmda" { |
| 244 | + continue |
| 245 | + } |
| 246 | + path := filepath.Join(v, customCgroup) |
| 247 | + if _, err := os.Stat(path); err != nil { |
| 248 | + if os.IsNotExist(err) { |
| 249 | + t.Fatalf("custom cgroup path %s should exist, actually not", path) |
| 250 | + } |
| 251 | + } |
| 252 | + } |
| 253 | +} |
0 commit comments