Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move and fix GetContainerRuntime check from bpfd proc #1996

Merged
merged 4 commits into from
Mar 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/executor/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ import (
"github.com/GoogleContainerTools/kaniko/pkg/logging"
"github.com/GoogleContainerTools/kaniko/pkg/timing"
"github.com/GoogleContainerTools/kaniko/pkg/util"
"github.com/GoogleContainerTools/kaniko/pkg/util/proc"
"github.com/containerd/containerd/platforms"
"github.com/genuinetools/bpfd/proc"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ require (
github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21
github.com/containerd/cgroups v1.0.3 // indirect
github.com/docker/docker v20.10.13+incompatible
github.com/genuinetools/bpfd v0.0.2-0.20190525234658-c12d8cd9aac8
github.com/go-git/go-billy/v5 v5.3.1
github.com/go-git/go-git/v5 v5.4.2
github.com/godbus/dbus/v5 v5.0.6 // indirect
Expand Down
3 changes: 0 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -653,9 +653,6 @@ github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXt
github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM=
github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E=
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/genuinetools/bpfd v0.0.2-0.20190525234658-c12d8cd9aac8 h1:4gvqvgeXA3WeVPFfudNMwxdSLT2o7ZOQQUFPeEa86aM=
github.com/genuinetools/bpfd v0.0.2-0.20190525234658-c12d8cd9aac8/go.mod h1:O3IeOSRt7TXBSKb3hmOpQdlusALsEbNF+niGBqgKCs0=
github.com/genuinetools/pkg v0.0.0-20181004225747-e152a0f47ee4/go.mod h1:XTcrCYlXPxnxL2UpnwuRn7tcaTn9HAhxFoFJucootk8=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
Expand Down
204 changes: 204 additions & 0 deletions pkg/util/proc/proc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/*
Copyright 2022 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Ported from https://github.com/genuinetools/bpfd/blob/a4bfa5e3e9d1bfdbc56268a36a0714911ae9b6bf/proc/proc.go

package proc

import (
"fmt"
"io/ioutil"
"os"
"strings"
)

// ContainerRuntime is the type for the various container runtime strings.
type ContainerRuntime string

const (
// RuntimeDocker is the string for the docker runtime.
RuntimeDocker ContainerRuntime = "docker"
// RuntimeRkt is the string for the rkt runtime.
RuntimeRkt ContainerRuntime = "rkt"
// RuntimeNspawn is the string for the systemd-nspawn runtime.
RuntimeNspawn ContainerRuntime = "systemd-nspawn"
// RuntimeLXC is the string for the lxc runtime.
RuntimeLXC ContainerRuntime = "lxc"
// RuntimeLXCLibvirt is the string for the lxc-libvirt runtime.
RuntimeLXCLibvirt ContainerRuntime = "lxc-libvirt"
// RuntimeOpenVZ is the string for the openvz runtime.
RuntimeOpenVZ ContainerRuntime = "openvz"
// RuntimeKubernetes is the string for the kubernetes runtime.
RuntimeKubernetes ContainerRuntime = "kube"
// RuntimeGarden is the string for the garden runtime.
RuntimeGarden ContainerRuntime = "garden"
// RuntimePodman is the string for the podman runtime.
RuntimePodman ContainerRuntime = "podman"
// RuntimeGVisor is the string for the gVisor (runsc) runtime.
RuntimeGVisor ContainerRuntime = "gvisor"
// RuntimeFirejail is the string for the firejail runtime.
RuntimeFirejail ContainerRuntime = "firejail"
// RuntimeWSL is the string for the Windows Subsystem for Linux runtime.
RuntimeWSL ContainerRuntime = "wsl"
// RuntimeNotFound is the string for when no container runtime is found.
RuntimeNotFound ContainerRuntime = "not-found"
)

var (
// ContainerRuntimes contains all the container runtimes.
ContainerRuntimes = []ContainerRuntime{
RuntimeDocker,
RuntimeRkt,
RuntimeNspawn,
RuntimeLXC,
RuntimeLXCLibvirt,
RuntimeOpenVZ,
RuntimeKubernetes,
RuntimeGarden,
RuntimePodman,
RuntimeGVisor,
RuntimeFirejail,
RuntimeWSL,
}
)

// GetContainerRuntime returns the container runtime the process is running in.
// If pid is less than one, it returns the runtime for "self".
func GetContainerRuntime(tgid, pid int) ContainerRuntime {
file := "/proc/self/cgroup"
if pid > 0 {
if tgid > 0 {
file = fmt.Sprintf("/proc/%d/task/%d/cgroup", tgid, pid)
} else {
file = fmt.Sprintf("/proc/%d/cgroup", pid)
}
}

// read the cgroups file
a := readFileString(file)
runtime := getContainerRuntime(a)
if runtime != RuntimeNotFound {
return runtime
}

// /proc/vz exists in container and outside of the container, /proc/bc only outside of the container.
if osFileExists("/proc/vz") && !osFileExists("/proc/bc") {
return RuntimeOpenVZ
}

// /__runsc_containers__ directory is present in gVisor containers.
if osFileExists("/__runsc_containers__") {
return RuntimeGVisor
}

// firejail runs with `firejail` as pid 1.
// As firejail binary cannot be run with argv[0] != "firejail"
// it's okay to rely on cmdline.
a = readFileString("/proc/1/cmdline")
runtime = getContainerRuntime(a)
if runtime != RuntimeNotFound {
return runtime
}

// WSL has /proc/version_signature starting with "Microsoft".
a = readFileString("/proc/version_signature")
if strings.HasPrefix(a, "Microsoft") {
return RuntimeWSL
}

a = os.Getenv("container")
runtime = getContainerRuntime(a)
if runtime != RuntimeNotFound {
return runtime
}

// PID 1 might have dropped this information into a file in /run.
// Read from /run/systemd/container since it is better than accessing /proc/1/environ,
// which needs CAP_SYS_PTRACE
a = readFileString("/run/systemd/container")
runtime = getContainerRuntime(a)
if runtime != RuntimeNotFound {
return runtime
}

// Check for container specific files
runtime = detectContainerFiles()
if runtime != RuntimeNotFound {
return runtime
}

return RuntimeNotFound
}

// Related implementation: https://github.com/systemd/systemd/blob/6604fb0207ee10e8dc05d67f6fe45de0b193b5c4/src/basic/virt.c#L523-L549
func detectContainerFiles() ContainerRuntime {
files := []struct {
runtime ContainerRuntime
location string
}{
// https://github.com/containers/podman/issues/6192
// https://github.com/containers/podman/issues/3586#issuecomment-661918679
{RuntimePodman, "/run/.containerenv"},
// https://github.com/moby/moby/issues/18355
{RuntimeDocker, "/.dockerenv"},
}

for i := range files {
if osFileExists(files[i].location) {
return files[i].runtime
}
}

return RuntimeNotFound
}

func getContainerRuntime(input string) ContainerRuntime {
if len(strings.TrimSpace(input)) < 1 {
return RuntimeNotFound
}

for _, runtime := range ContainerRuntimes {
if strings.Contains(input, string(runtime)) {
return runtime
}
}

return RuntimeNotFound
}

func osFileExists(file string) bool {
if _, err := os.Stat(file); !os.IsNotExist(err) {
return true
}
return false
}

func readFile(file string) []byte {
if !osFileExists(file) {
return nil
}

b, _ := ioutil.ReadFile(file)
return b
}

func readFileString(file string) string {
b := readFile(file)
if b == nil {
return ""
}
return strings.TrimSpace(string(b))
}
136 changes: 136 additions & 0 deletions pkg/util/proc/proc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
Copyright 2022 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package proc

import (
"testing"
)

func TestGetContainerRuntime(t *testing.T) {
testcases := map[string]struct {
expectedRuntime ContainerRuntime
input string
}{
"empty": {
expectedRuntime: RuntimeNotFound,
},
"typical docker": {
expectedRuntime: RuntimeDocker,
input: `11:pids:/docker/68fad1f9e0985989408aff30e7b83e7dada1d235ff46a22c5465ca193ddf0fac
10:devices:/docker/68fad1f9e0985989408aff30e7b83e7dada1d235ff46a22c5465ca193ddf0fac
9:freezer:/docker/68fad1f9e0985989408aff30e7b83e7dada1d235ff46a22c5465ca193ddf0fac
8:net_cls,net_prio:/docker/68fad1f9e0985989408aff30e7b83e7dada1d235ff46a22c5465ca193ddf0fac
7:perf_event:/docker/68fad1f9e0985989408aff30e7b83e7dada1d235ff46a22c5465ca193ddf0fac
6:cpuset:/docker/68fad1f9e0985989408aff30e7b83e7dada1d235ff46a22c5465ca193ddf0fac
5:memory:/docker/68fad1f9e0985989408aff30e7b83e7dada1d235ff46a22c5465ca193ddf0fac
4:blkio:/docker/68fad1f9e0985989408aff30e7b83e7dada1d235ff46a22c5465ca193ddf0fac
3:cpu,cpuacct:/docker/68fad1f9e0985989408aff30e7b83e7dada1d235ff46a22c5465ca193ddf0fac
2:hugetlb:/docker/68fad1f9e0985989408aff30e7b83e7dada1d235ff46a22c5465ca193ddf0fac
1:name=systemd:/docker/68fad1f9e0985989408aff30e7b83e7dada1d235ff46a22c5465ca193ddf0fac
0::/system.slice/containerd.service`,
},
"uncontainerized process": {
expectedRuntime: RuntimeNotFound,
input: `11:pids:/system.slice/ssh.service
10:devices:/system.slice/ssh.service
9:freezer:/
8:net_cls,net_prio:/
7:perf_event:/
6:cpuset:/
5:memory:/system.slice/ssh.service
4:blkio:/system.slice/ssh.service
3:cpu,cpuacct:/system.slice/ssh.service
2:hugetlb:/
1:name=systemd:/system.slice/ssh.service
0::/system.slice/ssh.service`,
},
"kubernetes": {
expectedRuntime: RuntimeKubernetes,
input: `12:perf_event:/kubepods/burstable/pod98051bd2-a5fa-11e8-9bb9-0a58ac1f31f2/74998d19bd3c7423744214c344c6e814d19b7908a92f165f9d58243073a27a47
11:freezer:/kubepods/burstable/pod98051bd2-a5fa-11e8-9bb9-0a58ac1f31f2/74998d19bd3c7423744214c344c6e814d19b7908a92f165f9d58243073a27a47
10:pids:/kubepods/burstable/pod98051bd2-a5fa-11e8-9bb9-0a58ac1f31f2/74998d19bd3c7423744214c344c6e814d19b7908a92f165f9d58243073a27a47
9:net_cls,net_prio:/kubepods/burstable/pod98051bd2-a5fa-11e8-9bb9-0a58ac1f31f2/74998d19bd3c7423744214c344c6e814d19b7908a92f165f9d58243073a27a47
8:memory:/kubepods/burstable/pod98051bd2-a5fa-11e8-9bb9-0a58ac1f31f2/74998d19bd3c7423744214c344c6e814d19b7908a92f165f9d58243073a27a47
7:cpuset:/kubepods/burstable/pod98051bd2-a5fa-11e8-9bb9-0a58ac1f31f2/74998d19bd3c7423744214c344c6e814d19b7908a92f165f9d58243073a27a47
6:devices:/kubepods/burstable/pod98051bd2-a5fa-11e8-9bb9-0a58ac1f31f2/74998d19bd3c7423744214c344c6e814d19b7908a92f165f9d58243073a27a47
5:blkio:/kubepods/burstable/pod98051bd2-a5fa-11e8-9bb9-0a58ac1f31f2/74998d19bd3c7423744214c344c6e814d19b7908a92f165f9d58243073a27a47
4:rdma:/
3:hugetlb:/kubepods/burstable/pod98051bd2-a5fa-11e8-9bb9-0a58ac1f31f2/74998d19bd3c7423744214c344c6e814d19b7908a92f165f9d58243073a27a47
2:cpu,cpuacct:/kubepods/burstable/pod98051bd2-a5fa-11e8-9bb9-0a58ac1f31f2/74998d19bd3c7423744214c344c6e814d19b7908a92f165f9d58243073a27a47
1:name=systemd:/kubepods/burstable/pod98051bd2-a5fa-11e8-9bb9-0a58ac1f31f2/74998d19bd3c7423744214c344c6e814d19b7908a92f165f9d58243073a27a47`,
},
"lxc": {
expectedRuntime: RuntimeLXC, // this is usually in $container for lxc
input: `10:cpuset:/lxc/debian2
9:pids:/lxc/debian2
8:devices:/lxc/debian2
7:net_cls,net_prio:/lxc/debian2
6:freezer:/lxc/debian2
5:blkio:/lxc/debian2
4:memory:/lxc/debian2
3:cpu,cpuacct:/lxc/debian2
2:perf_event:/lxc/debian2
1:name=systemd:/lxc/debian2`,
},
"nspawn": {
expectedRuntime: RuntimeNotFound, // since this variable is in $container
input: `10:cpuset:/
9:pids:/machine.slice/machine-nspawntest.scope
8:devices:/machine.slice/machine-nspawntest.scope
7:net_cls,net_prio:/
6:freezer:/user/root/0
5:blkio:/machine.slice/machine-nspawntest.scope
4:memory:/machine.slice/machine-nspawntest.scope
3:cpu,cpuacct:/machine.slice/machine-nspawntest.scope
2:perf_event:/
1:name=systemd:/machine.slice/machine-nspawntest.scope`,
},
"rkt": {
expectedRuntime: RuntimeRkt,
input: `10:cpuset:/
9:pids:/machine.slice/machine-rkt\x2dbfb7d57e\x2d80ff\x2d4ef8\x2db602\x2d9b907b3f3a38.scope/system.slice/debian.service
8:devices:/machine.slice/machine-rkt\x2dbfb7d57e\x2d80ff\x2d4ef8\x2db602\x2d9b907b3f3a38.scope/system.slice/debian.service
7:net_cls,net_prio:/
6:freezer:/user/root/0
5:blkio:/machine.slice/machine-rkt\x2dbfb7d57e\x2d80ff\x2d4ef8\x2db602\x2d9b907b3f3a38.scope/system.slice
4:memory:/machine.slice/machine-rkt\x2dbfb7d57e\x2d80ff\x2d4ef8\x2db602\x2d9b907b3f3a38.scope/system.slice
3:cpu,cpuacct:/machine.slice/machine-rkt\x2dbfb7d57e\x2d80ff\x2d4ef8\x2db602\x2d9b907b3f3a38.scope/system.slice
2:perf_event:/
1:name=systemd:/machine.slice/machine-rkt\x2dbfb7d57e\x2d80ff\x2d4ef8\x2db602\x2d9b907b3f3a38.scope/system.slice/debian.service`,
},
"rkt host": {
expectedRuntime: RuntimeRkt,
input: `10:cpuset:/
9:pids:/machine.slice/machine-rkt\x2dbfb7d57e\x2d80ff\x2d4ef8\x2db602\x2d9b907b3f3a38.scope/system.slice/debian.service
8:devices:/machine.slice/machine-rkt\x2dbfb7d57e\x2d80ff\x2d4ef8\x2db602\x2d9b907b3f3a38.scope/system.slice/debian.service
7:net_cls,net_prio:/
6:freezer:/user/root/0
5:blkio:/machine.slice/machine-rkt\x2dbfb7d57e\x2d80ff\x2d4ef8\x2db602\x2d9b907b3f3a38.scope/system.slice
4:memory:/machine.slice/machine-rkt\x2dbfb7d57e\x2d80ff\x2d4ef8\x2db602\x2d9b907b3f3a38.scope/system.slice
3:cpu,cpuacct:/machine.slice/machine-rkt\x2dbfb7d57e\x2d80ff\x2d4ef8\x2db602\x2d9b907b3f3a38.scope/system.slice
2:perf_event:/
1:name=systemd:/machine.slice/machine-rkt\x2dbfb7d57e\x2d80ff\x2d4ef8\x2db602\x2d9b907b3f3a38.scope/system.slice/debian.service`,
},
}

for key, tc := range testcases {
runtime := getContainerRuntime(tc.input)
if runtime != tc.expectedRuntime {
t.Errorf("[%s]: expected runtime %q, got %q", key, tc.expectedRuntime, runtime)
}
}
}
21 changes: 0 additions & 21 deletions vendor/github.com/genuinetools/bpfd/LICENSE

This file was deleted.

Loading