From af0bc55d7d5b9c931dc875c73bcc2f4eb5ec46ce Mon Sep 17 00:00:00 2001 From: Mario Macias Date: Sat, 21 Sep 2019 10:33:32 +0200 Subject: [PATCH] Allow overriding the default /proc folder in blkioController A host may share its /proc FS folder with a privileged container, mounted in an alternative folder (e.g. /host/proc), as some users prefer to run their monitoring software inside a container instead of as a host process. This patch allows overriding the default /proc folder to allow the blkio Controller working inside containerized monitoring software. The /proc root can be overriden via an optional function (ProcRoot) to avoid introducing a new NewBlkio constructor or introducing breaking changes in the current API. Then, the NewBlkio constructor can be invoked as usual, or in the following form, to override the /proc path: ctrl := NewBlkio("/sys/fs/cgroup", ProcRoot("/host/proc")) Signed-off-by: Mario Macias --- blkio.go | 25 ++++++++++++++++++++----- blkio_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/blkio.go b/blkio.go index 5be154c8..c198c528 100644 --- a/blkio.go +++ b/blkio.go @@ -30,14 +30,29 @@ import ( specs "github.com/opencontainers/runtime-spec/specs-go" ) -func NewBlkio(root string) *blkioController { - return &blkioController{ - root: filepath.Join(root, string(Blkio)), +// NewBlkio returns a Blkio controller given the root folder of cgroups. +// It may optionally accept other configuration options, such as ProcRoot(path) +func NewBlkio(root string, options ...func(controller *blkioController)) *blkioController { + ctrl := &blkioController{ + root: filepath.Join(root, string(Blkio)), + procRoot: "/proc", + } + for _, opt := range options { + opt(ctrl) + } + return ctrl +} + +// ProcRoot overrides the default location of the "/proc" filesystem +func ProcRoot(path string) func(controller *blkioController) { + return func(c *blkioController) { + c.procRoot = path } } type blkioController struct { - root string + root string + procRoot string } func (b *blkioController) Name() Name { @@ -123,7 +138,7 @@ func (b *blkioController) Stat(path string, stats *v1.Metrics) error { }, ) } - f, err := os.Open("/proc/diskstats") + f, err := os.Open(filepath.Join(b.procRoot, "diskstats")) if err != nil { return err } diff --git a/blkio_test.go b/blkio_test.go index b63f5c30..da463d9b 100644 --- a/blkio_test.go +++ b/blkio_test.go @@ -49,3 +49,31 @@ func TestGetDevices(t *testing.T) { t.Fatalf("expected device name %q but received %q", expected, name) } } + +func TestNewBlkio(t *testing.T) { + const root = "/test/folder" + const expected = "/test/folder/blkio" + const expectedProc = "/proc" + + ctrl := NewBlkio(root) + if ctrl.root != expected { + t.Fatalf("expected cgroups root %q but received %q", expected, ctrl.root) + } + if ctrl.procRoot != expectedProc { + t.Fatalf("expected proc FS root %q but received %q", expectedProc, ctrl.procRoot) + } +} + +func TestNewBlkio_Proc(t *testing.T) { + const root = "/test/folder" + const expected = "/test/folder/blkio" + const expectedProc = "/test/proc" + + ctrl := NewBlkio(root, ProcRoot(expectedProc)) + if ctrl.root != expected { + t.Fatalf("expected cgroups root %q but received %q", expected, ctrl.root) + } + if ctrl.procRoot != expectedProc { + t.Fatalf("expected proc FS root %q but received %q", expectedProc, ctrl.procRoot) + } +}