Files
troubleshoot/pkg/collect/host_cgroup.go

104 lines
2.7 KiB
Go

// This Control Groups collector is heavily based on k0s'
// probes implementation https://github.com/k0sproject/k0s/blob/main/internal/pkg/sysinfo/probes/linux/cgroups.go
package collect
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"io"
"strings"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"k8s.io/klog/v2"
)
const hostCGroupsPath = `host-collectors/system/cgroups.json`
type CollectHostCGroups struct {
hostCollector *troubleshootv1beta2.HostCGroups
BundlePath string
}
type cgroupResult struct {
Enabled bool `json:"enabled"`
MountPoint string `json:"mountPoint"`
Controllers []string `json:"controllers"`
}
type cgroupsResult struct {
CGroupEnabled bool `json:"cgroup-enabled"`
CGroupV1 cgroupResult `json:"cgroup-v1"`
CGroupV2 cgroupResult `json:"cgroup-v2"`
// AllControllers is a list of all cgroup controllers found in the system
AllControllers []string `json:"allControllers"`
}
func (c *CollectHostCGroups) Title() string {
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "cgroups")
}
func (c *CollectHostCGroups) IsExcluded() (bool, error) {
return isExcluded(c.hostCollector.Exclude)
}
func (c *CollectHostCGroups) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
// https://man7.org/linux/man-pages/man7/cgroups.7.html
// Implementation is based on https://github.com/k0sproject/k0s/blob/main/internal/pkg/sysinfo/probes/linux/cgroups.go
if c.hostCollector.MountPoint == "" {
c.hostCollector.MountPoint = "/sys/fs/cgroup"
}
results, err := discoverConfiguration(c.hostCollector.MountPoint)
if err != nil {
return nil, err
}
// Save the results
resultsJson, err := json.MarshalIndent(results, "", " ")
if err != nil {
return nil, err
}
output := NewResult()
err = output.SaveResult(c.BundlePath, hostCGroupsPath, bytes.NewBuffer(resultsJson))
if err != nil {
return nil, err
}
return output, nil
}
func parseV1ControllerNames(r io.Reader) ([]string, error) {
names := []string{}
var lineNo uint
lines := bufio.NewScanner(r)
for lines.Scan() {
lineNo = lineNo + 1
if err := lines.Err(); err != nil {
return nil, fmt.Errorf("failed to parse /proc/cgroups at line %d: %w ", lineNo, err)
}
text := lines.Text()
if len(text) == 0 {
continue
}
if text[0] != '#' {
parts := strings.Fields(text)
if len(parts) >= 4 && parts[3] != "0" {
names = append(names, parts[0])
}
}
}
klog.V(2).Info("cgroup v1 controllers loaded")
return names, nil
}
func (c *CollectHostCGroups) RemoteCollect(progressChan chan<- interface{}) (map[string][]byte, error) {
return nil, ErrRemoteCollectorNotImplemented
}