Skip to content

Commit 2ba7392

Browse files
committed
fix container detection to work with sysbox containers
1 parent 4c081dc commit 2ba7392

File tree

2 files changed

+61
-10
lines changed

2 files changed

+61
-10
lines changed

cli/clistat/stat.go

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
package clistat
22

33
import (
4-
"github.com/elastic/go-sysinfo"
5-
"golang.org/x/xerrors"
4+
"bufio"
5+
"bytes"
6+
"os"
67
"runtime"
78
"strconv"
89
"strings"
9-
"tailscale.com/types/ptr"
1010
"time"
1111

12+
"github.com/elastic/go-sysinfo"
13+
"golang.org/x/xerrors"
14+
"tailscale.com/types/ptr"
15+
1216
sysinfotypes "github.com/elastic/go-sysinfo/types"
1317
)
1418

19+
const procOneCgroup = "/proc/1/cgroup"
20+
1521
// Result is a generic result type for a statistic.
1622
// Total is the total amount of the resource available.
1723
// It is nil if the resource is not a finite quantity.
@@ -125,7 +131,7 @@ func (s *Statter) Uptime() (*Result, error) {
125131
Total: nil, // Is time a finite quantity? For this purpose, no.
126132
}
127133

128-
if ok := IsContainerized(); ok != nil && *ok {
134+
if ok, err := IsContainerized(); err == nil && ok {
129135
procStat, err := sysinfo.Process(1)
130136
if err != nil {
131137
return nil, xerrors.Errorf("get pid 1 info: %w", err)
@@ -152,11 +158,43 @@ func (s *Statter) ContainerMemory() (*Result, error) {
152158
}
153159

154160
// IsContainerized returns whether the host is containerized.
155-
// This wraps the elastic/go-sysinfo library.
156-
func IsContainerized() *bool {
157-
hi, err := sysinfo.Host()
161+
// This is adapted from https://github.com/elastic/go-sysinfo/tree/main/providers/linux/container.go#L31
162+
// with modifications to support Sysbox containers.
163+
func IsContainerized() (bool, error) {
164+
data, err := os.ReadFile(procOneCgroup)
165+
if err != nil {
166+
if os.IsNotExist(err) { // how?
167+
return false, nil
168+
}
169+
return false, xerrors.Errorf("read process cgroups: %w", err)
170+
}
171+
172+
s := bufio.NewScanner(bytes.NewReader(data))
173+
for s.Scan() {
174+
line := s.Bytes()
175+
if bytes.Contains(line, []byte("docker")) ||
176+
bytes.Contains(line, []byte(".slice")) ||
177+
bytes.Contains(line, []byte("lxc")) ||
178+
bytes.Contains(line, []byte("kubepods")) {
179+
return true, nil
180+
}
181+
}
182+
183+
// Last-ditch effort to detect Sysbox containers.
184+
// Check if we have anything mounted as type sysboxfs in /proc/mounts
185+
data, err = os.ReadFile("/proc/mounts")
158186
if err != nil {
159-
return nil
187+
return false, xerrors.Errorf("read /proc/mounts: %w", err)
160188
}
161-
return hi.Info().Containerized
189+
190+
s = bufio.NewScanner(bytes.NewReader(data))
191+
for s.Scan() {
192+
line := s.Bytes()
193+
if bytes.HasPrefix(line, []byte("sysboxfs")) {
194+
return true, nil
195+
}
196+
}
197+
198+
// If we get here, we are _probably_ not running in a container.
199+
return false, nil
162200
}

cli/stat.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212

1313
func (*RootCmd) stat() *clibase.Cmd {
1414
defaultCols := []string{"host_cpu", "host_memory", "home_disk", "uptime"}
15-
if ok := clistat.IsContainerized(); ok != nil && *ok {
15+
if ok, err := clistat.IsContainerized(); err == nil && ok {
1616
// If running in a container, we assume that users want to see these first. Prepend.
1717
defaultCols = append([]string{"container_cpu", "container_memory"}, defaultCols...)
1818
}
@@ -70,6 +70,19 @@ func (*RootCmd) stat() *clibase.Cmd {
7070
sr.Uptime = us
7171
}
7272

73+
if ok, err := clistat.IsContainerized(); err == nil && ok {
74+
if cs, err := s.ContainerCPU(); err != nil {
75+
return err
76+
} else {
77+
sr.ContainerCPU = cs
78+
}
79+
if ms, err := s.ContainerMemory(); err != nil {
80+
return err
81+
} else {
82+
sr.ContainerMemory = ms
83+
}
84+
}
85+
7386
out, err := formatter.Format(inv.Context(), []statsRow{sr})
7487
if err != nil {
7588
return err

0 commit comments

Comments
 (0)