Skip to content

Commit bcbb471

Browse files
authored
fix cgroup handling for Incus containers (#224)
1 parent 3254ce1 commit bcbb471

File tree

3 files changed

+51
-21
lines changed

3 files changed

+51
-21
lines changed

cgroup/cgroup.go

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ var (
2525
lxcIdRegexp = regexp.MustCompile(`/lxc/([^/]+)`)
2626
systemSliceIdRegexp = regexp.MustCompile(`(/(system|runtime|reserved)\.slice/([^/]+))`)
2727
talosIdRegexp = regexp.MustCompile(`/(system|podruntime)/([^/]+)`)
28+
lxcPayloadRegexp = regexp.MustCompile(`/lxc\.payload\.([^/]+)`)
2829
)
2930

3031
type ContainerType uint8
@@ -129,7 +130,14 @@ func NewFromProcessCgroupFile(filePath string) (*Cgroup, error) {
129130
continue
130131
}
131132
for _, cgType := range strings.Split(parts[1], ",") {
132-
p := path.Join(baseCgroupPath, parts[2])
133+
cgPath := parts[2]
134+
if strings.HasPrefix(parts[2], "/lxc.payload.") {
135+
pp := strings.Split(cgPath, "/")
136+
if len(parts) > 2 {
137+
cgPath = "/" + pp[1]
138+
}
139+
}
140+
p := path.Join(baseCgroupPath, cgPath)
133141
switch p {
134142
case "/", "/init.scope":
135143
continue
@@ -147,24 +155,22 @@ func NewFromProcessCgroupFile(filePath string) (*Cgroup, error) {
147155

148156
func containerByCgroup(cgroupPath string) (ContainerType, string, error) {
149157
parts := strings.Split(strings.TrimLeft(cgroupPath, "/"), "/")
150-
if cgroupPath == "/init" {
151-
return ContainerTypeTalosRuntime, "/talos/init", nil
152-
}
153-
if len(parts) < 2 {
158+
if len(parts) == 0 {
154159
return ContainerTypeStandaloneProcess, "", nil
155160
}
156161
prefix := parts[0]
157-
if prefix == "user.slice" || prefix == "init.scope" {
162+
switch {
163+
case cgroupPath == "/init":
164+
return ContainerTypeTalosRuntime, "/talos/init", nil
165+
case prefix == "user.slice" || prefix == "init.scope":
158166
return ContainerTypeStandaloneProcess, "", nil
159-
}
160-
if prefix == "docker" || (prefix == "system.slice" && strings.HasPrefix(parts[1], "docker-")) {
167+
case prefix == "docker" || (prefix == "system.slice" && len(parts) > 1 && strings.HasPrefix(parts[1], "docker-")):
161168
matches := dockerIdRegexp.FindStringSubmatch(cgroupPath)
162169
if matches == nil {
163170
return ContainerTypeUnknown, "", fmt.Errorf("invalid docker cgroup %s", cgroupPath)
164171
}
165172
return ContainerTypeDocker, matches[1], nil
166-
}
167-
if strings.Contains(cgroupPath, "kubepods") {
173+
case strings.Contains(cgroupPath, "kubepods"):
168174
crioMatches := crioIdRegexp.FindStringSubmatch(cgroupPath)
169175
if crioMatches != nil {
170176
return ContainerTypeCrio, crioMatches[1], nil
@@ -181,27 +187,33 @@ func containerByCgroup(cgroupPath string) (ContainerType, string, error) {
181187
return ContainerTypeSandbox, "", nil
182188
}
183189
return ContainerTypeDocker, matches[1], nil
184-
}
185-
if prefix == "lxc" {
186-
matches := lxcIdRegexp.FindStringSubmatch(cgroupPath)
187-
if matches == nil {
188-
return ContainerTypeUnknown, "", fmt.Errorf("invalid lxc cgroup %s", cgroupPath)
189-
}
190-
return ContainerTypeLxc, matches[1], nil
191-
}
192-
if prefix == "system" || prefix == "podruntime" {
190+
case prefix == "system" || prefix == "podruntime":
193191
matches := talosIdRegexp.FindStringSubmatch(cgroupPath)
194192
if matches == nil {
195193
return ContainerTypeUnknown, "", fmt.Errorf("invalid talos runtime cgroup %s", cgroupPath)
196194
}
197195
return ContainerTypeTalosRuntime, path.Join("/talos/", matches[2]), nil
198-
}
199-
if prefix == "system.slice" || prefix == "runtime.slice" || prefix == "reserved.slice" {
196+
case prefix == "system.slice" || prefix == "runtime.slice" || prefix == "reserved.slice":
200197
matches := systemSliceIdRegexp.FindStringSubmatch(cgroupPath)
201198
if matches == nil {
202199
return ContainerTypeUnknown, "", fmt.Errorf("invalid systemd cgroup %s", cgroupPath)
203200
}
204201
return ContainerTypeSystemdService, strings.Replace(matches[1], "\\x2d", "-", -1), nil
202+
case prefix == "lxc":
203+
matches := lxcIdRegexp.FindStringSubmatch(cgroupPath)
204+
if matches == nil {
205+
return ContainerTypeUnknown, "", fmt.Errorf("invalid lxc cgroup %s", cgroupPath)
206+
}
207+
return ContainerTypeLxc, matches[1], nil
208+
case strings.HasPrefix(prefix, "lxc.payload."):
209+
matches := lxcPayloadRegexp.FindStringSubmatch(cgroupPath)
210+
if matches == nil {
211+
return ContainerTypeUnknown, "", fmt.Errorf("invalid lxc payload cgroup %s", cgroupPath)
212+
}
213+
return ContainerTypeLxc, "/lxc/" + matches[1], nil
214+
case len(parts) < 2:
215+
return ContainerTypeStandaloneProcess, "", nil
205216
}
217+
206218
return ContainerTypeUnknown, "", fmt.Errorf("unknown container: %s", cgroupPath)
207219
}

cgroup/cgroup_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"testing"
66

77
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
89
)
910

1011
func TestNewFromProcessCgroupFile(t *testing.T) {
@@ -75,6 +76,12 @@ func TestNewFromProcessCgroupFile(t *testing.T) {
7576
assert.Equal(t, "95cbe853416f52d927dec41f1406dd75015ea131244a1ca875a7cd4ebe927ac8", cg.ContainerId)
7677
assert.Equal(t, ContainerTypeDocker, cg.ContainerType)
7778

79+
cg, err = NewFromProcessCgroupFile(path.Join("fixtures/proc/3000/cgroup"))
80+
require.Nil(t, err)
81+
assert.Equal(t, "/lxc.payload.first", cg.Id)
82+
assert.Equal(t, "/lxc/first", cg.ContainerId)
83+
assert.Equal(t, ContainerTypeLxc, cg.ContainerType)
84+
7885
baseCgroupPath = "/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-podc83d0428_58af_41eb_8dba_b9e6eddffe7b.slice/docker-0e612005fd07e7f47e2cd07df99a2b4e909446814d71d0b5e4efc7159dd51252.scope"
7986
defer func() {
8087
baseCgroupPath = ""
@@ -178,4 +185,14 @@ func TestContainerByCgroup(t *testing.T) {
178185
as.Equal(typ, ContainerTypeTalosRuntime)
179186
as.Equal("/talos/init", id)
180187
as.Nil(err)
188+
189+
typ, id, err = containerByCgroup("/lxc.payload.first")
190+
as.Equal(typ, ContainerTypeLxc)
191+
as.Equal("/lxc/first", id)
192+
as.Nil(err)
193+
194+
typ, id, err = containerByCgroup("/lxc.monitor.first")
195+
as.Equal(ContainerTypeStandaloneProcess, typ)
196+
as.Equal("", id)
197+
as.Nil(err)
181198
}

cgroup/fixtures/proc/3000/cgroup

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0::/lxc.payload.first/system.slice/systemd-logind.service

0 commit comments

Comments
 (0)