mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 02:43:36 +00:00
vendor files
This commit is contained in:
68
vendor/k8s.io/kubernetes/test/e2e_node/system/BUILD
generated
vendored
Normal file
68
vendor/k8s.io/kubernetes/test/e2e_node/system/BUILD
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"cgroup_validator.go",
|
||||
"docker_validator.go",
|
||||
"kernel_validator.go",
|
||||
"kernel_validator_helper.go",
|
||||
"os_validator.go",
|
||||
"package_validator.go",
|
||||
"report.go",
|
||||
"types.go",
|
||||
"types_unix.go",
|
||||
"validators.go",
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:windows_amd64": [
|
||||
"types_windows.go",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
importpath = "k8s.io/kubernetes/test/e2e_node/system",
|
||||
deps = [
|
||||
"//vendor/github.com/blang/semver:go_default_library",
|
||||
"//vendor/github.com/docker/docker/api/types:go_default_library",
|
||||
"//vendor/github.com/docker/docker/client:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/golang.org/x/net/context:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"cgroup_validator_test.go",
|
||||
"docker_validator_test.go",
|
||||
"kernel_validator_test.go",
|
||||
"os_validator_test.go",
|
||||
"package_validator_test.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/test/e2e_node/system",
|
||||
library = ":go_default_library",
|
||||
tags = ["e2e"],
|
||||
deps = [
|
||||
"//vendor/github.com/docker/docker/api/types:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
95
vendor/k8s.io/kubernetes/test/e2e_node/system/cgroup_validator.go
generated
vendored
Normal file
95
vendor/k8s.io/kubernetes/test/e2e_node/system/cgroup_validator.go
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var _ Validator = &CgroupsValidator{}
|
||||
|
||||
type CgroupsValidator struct {
|
||||
Reporter Reporter
|
||||
}
|
||||
|
||||
func (c *CgroupsValidator) Name() string {
|
||||
return "cgroups"
|
||||
}
|
||||
|
||||
const (
|
||||
cgroupsConfigPrefix = "CGROUPS_"
|
||||
)
|
||||
|
||||
func (c *CgroupsValidator) Validate(spec SysSpec) (error, error) {
|
||||
subsystems, err := c.getCgroupSubsystems()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get cgroup subsystems: %v", err)
|
||||
}
|
||||
return nil, c.validateCgroupSubsystems(spec.Cgroups, subsystems)
|
||||
}
|
||||
|
||||
func (c *CgroupsValidator) validateCgroupSubsystems(cgroupSpec, subsystems []string) error {
|
||||
missing := []string{}
|
||||
for _, cgroup := range cgroupSpec {
|
||||
found := false
|
||||
for _, subsystem := range subsystems {
|
||||
if cgroup == subsystem {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
item := cgroupsConfigPrefix + strings.ToUpper(cgroup)
|
||||
if found {
|
||||
c.Reporter.Report(item, "enabled", good)
|
||||
} else {
|
||||
c.Reporter.Report(item, "missing", bad)
|
||||
missing = append(missing, cgroup)
|
||||
}
|
||||
}
|
||||
if len(missing) > 0 {
|
||||
return fmt.Errorf("missing cgroups: %s", strings.Join(missing, " "))
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (c *CgroupsValidator) getCgroupSubsystems() ([]string, error) {
|
||||
f, err := os.Open("/proc/cgroups")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
subsystems := []string{}
|
||||
s := bufio.NewScanner(f)
|
||||
for s.Scan() {
|
||||
if err := s.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
text := s.Text()
|
||||
if text[0] != '#' {
|
||||
parts := strings.Fields(text)
|
||||
if len(parts) >= 4 && parts[3] != "0" {
|
||||
subsystems = append(subsystems, parts[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
return subsystems, nil
|
||||
}
|
56
vendor/k8s.io/kubernetes/test/e2e_node/system/cgroup_validator_test.go
generated
vendored
Normal file
56
vendor/k8s.io/kubernetes/test/e2e_node/system/cgroup_validator_test.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestValidateCgroupSubsystem(t *testing.T) {
|
||||
v := &CgroupsValidator{
|
||||
Reporter: DefaultReporter,
|
||||
}
|
||||
cgroupSpec := []string{"system1", "system2"}
|
||||
for desc, test := range map[string]struct {
|
||||
cgroupSpec []string
|
||||
subsystems []string
|
||||
err bool
|
||||
}{
|
||||
"missing cgroup subsystem should report error": {
|
||||
subsystems: []string{"system1"},
|
||||
err: true,
|
||||
},
|
||||
"extra cgroup subsystems should not report error": {
|
||||
subsystems: []string{"system1", "system2", "system3"},
|
||||
err: false,
|
||||
},
|
||||
"subsystems the same with spec should not report error": {
|
||||
subsystems: []string{"system1", "system2"},
|
||||
err: false,
|
||||
},
|
||||
} {
|
||||
err := v.validateCgroupSubsystems(cgroupSpec, test.subsystems)
|
||||
if !test.err {
|
||||
assert.Nil(t, err, "%q: Expect error not to occur with cgroup", desc)
|
||||
} else {
|
||||
assert.NotNil(t, err, "%q: Expect error to occur with docker info", desc)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
100
vendor/k8s.io/kubernetes/test/e2e_node/system/docker_validator.go
generated
vendored
Normal file
100
vendor/k8s.io/kubernetes/test/e2e_node/system/docker_validator.go
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/client"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
var _ Validator = &DockerValidator{}
|
||||
|
||||
// DockerValidator validates docker configuration.
|
||||
type DockerValidator struct {
|
||||
Reporter Reporter
|
||||
}
|
||||
|
||||
func (d *DockerValidator) Name() string {
|
||||
return "docker"
|
||||
}
|
||||
|
||||
const (
|
||||
dockerConfigPrefix = "DOCKER_"
|
||||
maxDockerValidatedVersion = "17.03"
|
||||
)
|
||||
|
||||
// TODO(random-liu): Add more validating items.
|
||||
func (d *DockerValidator) Validate(spec SysSpec) (error, error) {
|
||||
if spec.RuntimeSpec.DockerSpec == nil {
|
||||
// If DockerSpec is not specified, assume current runtime is not
|
||||
// docker, skip the docker configuration validation.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
c, err := client.NewClient(dockerEndpoint, "", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create docker client: %v", err)
|
||||
}
|
||||
info, err := c.Info(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get docker info: %v", err)
|
||||
}
|
||||
return d.validateDockerInfo(spec.RuntimeSpec.DockerSpec, info)
|
||||
}
|
||||
|
||||
func (d *DockerValidator) validateDockerInfo(spec *DockerSpec, info types.Info) (error, error) {
|
||||
// Validate docker version.
|
||||
matched := false
|
||||
for _, v := range spec.Version {
|
||||
r := regexp.MustCompile(v)
|
||||
if r.MatchString(info.ServerVersion) {
|
||||
d.Reporter.Report(dockerConfigPrefix+"VERSION", info.ServerVersion, good)
|
||||
matched = true
|
||||
}
|
||||
}
|
||||
if !matched {
|
||||
// If it's of the new Docker version scheme but didn't match above, it
|
||||
// must be a newer version than the most recently validated one.
|
||||
ver := `\d{2}\.\d+\.\d+-[a-z]{2}`
|
||||
r := regexp.MustCompile(ver)
|
||||
if r.MatchString(info.ServerVersion) {
|
||||
d.Reporter.Report(dockerConfigPrefix+"VERSION", info.ServerVersion, good)
|
||||
w := fmt.Errorf(
|
||||
"docker version is greater than the most recently validated version. Docker version: %s. Max validated version: %s",
|
||||
info.ServerVersion,
|
||||
maxDockerValidatedVersion,
|
||||
)
|
||||
return w, nil
|
||||
}
|
||||
d.Reporter.Report(dockerConfigPrefix+"VERSION", info.ServerVersion, bad)
|
||||
return nil, fmt.Errorf("unsupported docker version: %s", info.ServerVersion)
|
||||
}
|
||||
// Validate graph driver.
|
||||
item := dockerConfigPrefix + "GRAPH_DRIVER"
|
||||
for _, gd := range spec.GraphDriver {
|
||||
if info.Driver == gd {
|
||||
d.Reporter.Report(item, info.Driver, good)
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
d.Reporter.Report(item, info.Driver, bad)
|
||||
return nil, fmt.Errorf("unsupported graph driver: %s", info.Driver)
|
||||
}
|
88
vendor/k8s.io/kubernetes/test/e2e_node/system/docker_validator_test.go
generated
vendored
Normal file
88
vendor/k8s.io/kubernetes/test/e2e_node/system/docker_validator_test.go
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestValidateDockerInfo(t *testing.T) {
|
||||
v := &DockerValidator{
|
||||
Reporter: DefaultReporter,
|
||||
}
|
||||
spec := &DockerSpec{
|
||||
Version: []string{`1\.1[1-3]\..*`, `17\.03\..*`}, // Requires [1.11, 17.03].
|
||||
GraphDriver: []string{"driver_1", "driver_2"},
|
||||
}
|
||||
for _, test := range []struct {
|
||||
info types.Info
|
||||
err bool
|
||||
warn bool
|
||||
}{
|
||||
{
|
||||
info: types.Info{Driver: "driver_1", ServerVersion: "1.10.1"},
|
||||
err: true,
|
||||
warn: false,
|
||||
},
|
||||
{
|
||||
info: types.Info{Driver: "bad_driver", ServerVersion: "1.11.1"},
|
||||
err: true,
|
||||
warn: false,
|
||||
},
|
||||
{
|
||||
info: types.Info{Driver: "driver_1", ServerVersion: "1.11.1"},
|
||||
err: false,
|
||||
warn: false,
|
||||
},
|
||||
{
|
||||
info: types.Info{Driver: "driver_2", ServerVersion: "1.12.1"},
|
||||
err: false,
|
||||
warn: false,
|
||||
},
|
||||
{
|
||||
info: types.Info{Driver: "driver_2", ServerVersion: "1.13.1"},
|
||||
err: false,
|
||||
warn: false,
|
||||
},
|
||||
{
|
||||
info: types.Info{Driver: "driver_2", ServerVersion: "17.03.0-ce"},
|
||||
err: false,
|
||||
warn: false,
|
||||
},
|
||||
{
|
||||
info: types.Info{Driver: "driver_2", ServerVersion: "17.06.0-ce"},
|
||||
err: false,
|
||||
warn: true,
|
||||
},
|
||||
} {
|
||||
warn, err := v.validateDockerInfo(spec, test.info)
|
||||
if !test.err {
|
||||
assert.Nil(t, err, "Expect error not to occur with docker info %+v", test.info)
|
||||
} else {
|
||||
assert.NotNil(t, err, "Expect error to occur with docker info %+v", test.info)
|
||||
}
|
||||
if !test.warn {
|
||||
assert.Nil(t, warn, "Expect error not to occur with docker info %+v", test.info)
|
||||
} else {
|
||||
assert.NotNil(t, warn, "Expect error to occur with docker info %+v", test.info)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
259
vendor/k8s.io/kubernetes/test/e2e_node/system/kernel_validator.go
generated
vendored
Normal file
259
vendor/k8s.io/kubernetes/test/e2e_node/system/kernel_validator.go
generated
vendored
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/apimachinery/pkg/util/errors"
|
||||
)
|
||||
|
||||
var _ Validator = &KernelValidator{}
|
||||
|
||||
// KernelValidator validates kernel. Currently only validate kernel version
|
||||
// and kernel configuration.
|
||||
type KernelValidator struct {
|
||||
kernelRelease string
|
||||
Reporter Reporter
|
||||
}
|
||||
|
||||
func (k *KernelValidator) Name() string {
|
||||
return "kernel"
|
||||
}
|
||||
|
||||
// kConfigOption is the possible kernel config option.
|
||||
type kConfigOption string
|
||||
|
||||
const (
|
||||
builtIn kConfigOption = "y"
|
||||
asModule kConfigOption = "m"
|
||||
leftOut kConfigOption = "n"
|
||||
|
||||
// validKConfigRegex is the regex matching kernel configuration line.
|
||||
validKConfigRegex = "^CONFIG_[A-Z0-9_]+=[myn]"
|
||||
// kConfigPrefix is the prefix of kernel configuration.
|
||||
kConfigPrefix = "CONFIG_"
|
||||
)
|
||||
|
||||
func (k *KernelValidator) Validate(spec SysSpec) (error, error) {
|
||||
helper := KernelValidatorHelperImpl{}
|
||||
release, err := helper.GetKernelReleaseVersion()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get kernel release: %v", err)
|
||||
}
|
||||
k.kernelRelease = release
|
||||
var errs []error
|
||||
errs = append(errs, k.validateKernelVersion(spec.KernelSpec))
|
||||
// only validate kernel config when necessary (currently no kernel config for windows)
|
||||
if len(spec.KernelSpec.Required) > 0 || len(spec.KernelSpec.Forbidden) > 0 || len(spec.KernelSpec.Optional) > 0 {
|
||||
errs = append(errs, k.validateKernelConfig(spec.KernelSpec))
|
||||
}
|
||||
return nil, errors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
// validateKernelVersion validates the kernel version.
|
||||
func (k *KernelValidator) validateKernelVersion(kSpec KernelSpec) error {
|
||||
glog.Infof("Validating kernel version")
|
||||
versionRegexps := kSpec.Versions
|
||||
for _, versionRegexp := range versionRegexps {
|
||||
r := regexp.MustCompile(versionRegexp)
|
||||
if r.MatchString(k.kernelRelease) {
|
||||
k.Reporter.Report("KERNEL_VERSION", k.kernelRelease, good)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
k.Reporter.Report("KERNEL_VERSION", k.kernelRelease, bad)
|
||||
return fmt.Errorf("unsupported kernel release: %s", k.kernelRelease)
|
||||
}
|
||||
|
||||
// validateKernelConfig validates the kernel configurations.
|
||||
func (k *KernelValidator) validateKernelConfig(kSpec KernelSpec) error {
|
||||
glog.Infof("Validating kernel config")
|
||||
allConfig, err := k.getKernelConfig()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse kernel config: %v", err)
|
||||
}
|
||||
return k.validateCachedKernelConfig(allConfig, kSpec)
|
||||
}
|
||||
|
||||
// validateCachedKernelConfig validates the kernel confgiurations cached in internal data type.
|
||||
func (k *KernelValidator) validateCachedKernelConfig(allConfig map[string]kConfigOption, kSpec KernelSpec) error {
|
||||
badConfigs := []string{}
|
||||
// reportAndRecord is a helper function to record bad config when
|
||||
// report.
|
||||
reportAndRecord := func(name, msg, desc string, result ValidationResultType) {
|
||||
if result == bad {
|
||||
badConfigs = append(badConfigs, name)
|
||||
}
|
||||
// report description when the config is bad or warn.
|
||||
if result != good && desc != "" {
|
||||
msg = msg + " - " + desc
|
||||
}
|
||||
k.Reporter.Report(name, msg, result)
|
||||
}
|
||||
const (
|
||||
required = iota
|
||||
optional
|
||||
forbidden
|
||||
)
|
||||
validateOpt := func(config KernelConfig, expect int) {
|
||||
var found, missing ValidationResultType
|
||||
switch expect {
|
||||
case required:
|
||||
found, missing = good, bad
|
||||
case optional:
|
||||
found, missing = good, warn
|
||||
case forbidden:
|
||||
found, missing = bad, good
|
||||
}
|
||||
var name string
|
||||
var opt kConfigOption
|
||||
var ok bool
|
||||
for _, name = range append([]string{config.Name}, config.Aliases...) {
|
||||
name = kConfigPrefix + name
|
||||
if opt, ok = allConfig[name]; ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
reportAndRecord(name, "not set", config.Description, missing)
|
||||
return
|
||||
}
|
||||
switch opt {
|
||||
case builtIn:
|
||||
reportAndRecord(name, "enabled", config.Description, found)
|
||||
case asModule:
|
||||
reportAndRecord(name, "enabled (as module)", config.Description, found)
|
||||
case leftOut:
|
||||
reportAndRecord(name, "disabled", config.Description, missing)
|
||||
default:
|
||||
reportAndRecord(name, fmt.Sprintf("unknown option: %s", opt), config.Description, missing)
|
||||
}
|
||||
}
|
||||
for _, config := range kSpec.Required {
|
||||
validateOpt(config, required)
|
||||
}
|
||||
for _, config := range kSpec.Optional {
|
||||
validateOpt(config, optional)
|
||||
}
|
||||
for _, config := range kSpec.Forbidden {
|
||||
validateOpt(config, forbidden)
|
||||
}
|
||||
if len(badConfigs) > 0 {
|
||||
return fmt.Errorf("unexpected kernel config: %s", strings.Join(badConfigs, " "))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getKernelConfigReader search kernel config file in a predefined list. Once the kernel config
|
||||
// file is found it will read the configurations into a byte buffer and return. If the kernel
|
||||
// config file is not found, it will try to load kernel config module and retry again.
|
||||
func (k *KernelValidator) getKernelConfigReader() (io.Reader, error) {
|
||||
possibePaths := []string{
|
||||
"/proc/config.gz",
|
||||
"/boot/config-" + k.kernelRelease,
|
||||
"/usr/src/linux-" + k.kernelRelease + "/.config",
|
||||
"/usr/src/linux/.config",
|
||||
}
|
||||
configsModule := "configs"
|
||||
modprobeCmd := "modprobe"
|
||||
// loadModule indicates whether we've tried to load kernel config module ourselves.
|
||||
loadModule := false
|
||||
for {
|
||||
for _, path := range possibePaths {
|
||||
_, err := os.Stat(path)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
// Buffer the whole file, so that we can close the file and unload
|
||||
// kernel config module in this function.
|
||||
b, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var r io.Reader
|
||||
r = bytes.NewReader(b)
|
||||
// This is a gzip file (config.gz), unzip it.
|
||||
if filepath.Ext(path) == ".gz" {
|
||||
r, err = gzip.NewReader(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
// If we've tried to load kernel config module, break and return error.
|
||||
if loadModule {
|
||||
break
|
||||
}
|
||||
// If the kernel config file is not found, try to load the kernel
|
||||
// config module and check again.
|
||||
output, err := exec.Command(modprobeCmd, configsModule).CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to load kernel module %q: output - %q, err - %v",
|
||||
configsModule, output, err)
|
||||
}
|
||||
// Unload the kernel config module to make sure the validation have no side effect.
|
||||
defer exec.Command(modprobeCmd, "-r", configsModule).Run()
|
||||
loadModule = true
|
||||
}
|
||||
return nil, fmt.Errorf("no config path in %v is available", possibePaths)
|
||||
}
|
||||
|
||||
// getKernelConfig gets kernel config from kernel config file and convert kernel config to internal type.
|
||||
func (k *KernelValidator) getKernelConfig() (map[string]kConfigOption, error) {
|
||||
r, err := k.getKernelConfigReader()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return k.parseKernelConfig(r)
|
||||
}
|
||||
|
||||
// parseKernelConfig converts kernel config to internal type.
|
||||
func (k *KernelValidator) parseKernelConfig(r io.Reader) (map[string]kConfigOption, error) {
|
||||
config := map[string]kConfigOption{}
|
||||
regex := regexp.MustCompile(validKConfigRegex)
|
||||
s := bufio.NewScanner(r)
|
||||
for s.Scan() {
|
||||
if err := s.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
line := strings.TrimSpace(s.Text())
|
||||
if !regex.MatchString(line) {
|
||||
continue
|
||||
}
|
||||
fields := strings.Split(line, "=")
|
||||
if len(fields) != 2 {
|
||||
glog.Errorf("Unexpected fields number in config %q", line)
|
||||
continue
|
||||
}
|
||||
config[fields[0]] = kConfigOption(fields[1])
|
||||
}
|
||||
return config, nil
|
||||
|
||||
}
|
23
vendor/k8s.io/kubernetes/test/e2e_node/system/kernel_validator_helper.go
generated
vendored
Normal file
23
vendor/k8s.io/kubernetes/test/e2e_node/system/kernel_validator_helper.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
// KernelValidatorHelper is an interface intended to help with os specific kernel validation
|
||||
type KernelValidatorHelper interface {
|
||||
// GetKernelReleaseVersion gets the current kernel release version of the system
|
||||
GetKernelReleaseVersion() (string, error)
|
||||
}
|
197
vendor/k8s.io/kubernetes/test/e2e_node/system/kernel_validator_test.go
generated
vendored
Normal file
197
vendor/k8s.io/kubernetes/test/e2e_node/system/kernel_validator_test.go
generated
vendored
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestValidateKernelVersion(t *testing.T) {
|
||||
v := &KernelValidator{
|
||||
Reporter: DefaultReporter,
|
||||
}
|
||||
// Currently, testRegex is align with DefaultSysSpec.KernelVersion, but in the future
|
||||
// they may be different.
|
||||
// This is fine, because the test mainly tests the kernel version validation logic,
|
||||
// not the DefaultSysSpec. The DefaultSysSpec should be tested with node e2e.
|
||||
testRegex := []string{`3\.[1-9][0-9].*`, `4\..*`}
|
||||
for _, test := range []struct {
|
||||
version string
|
||||
err bool
|
||||
}{
|
||||
// first version regex matches
|
||||
{
|
||||
version: "3.19.9-99-test",
|
||||
err: false,
|
||||
},
|
||||
// one of version regexes matches
|
||||
{
|
||||
version: "4.4.14+",
|
||||
err: false,
|
||||
},
|
||||
// no version regex matches
|
||||
{
|
||||
version: "2.0.0",
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
version: "5.0.0",
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
version: "3.9.0",
|
||||
err: true,
|
||||
},
|
||||
} {
|
||||
v.kernelRelease = test.version
|
||||
err := v.validateKernelVersion(KernelSpec{Versions: testRegex})
|
||||
if !test.err {
|
||||
assert.Nil(t, err, "Expect error not to occur with kernel version %q", test.version)
|
||||
} else {
|
||||
assert.NotNil(t, err, "Expect error to occur with kenrel version %q", test.version)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateCachedKernelConfig(t *testing.T) {
|
||||
v := &KernelValidator{
|
||||
Reporter: DefaultReporter,
|
||||
}
|
||||
testKernelSpec := KernelSpec{
|
||||
Required: []KernelConfig{{Name: "REQUIRED_1"}, {Name: "REQUIRED_2", Aliases: []string{"ALIASE_REQUIRED_2"}}},
|
||||
Optional: []KernelConfig{{Name: "OPTIONAL_1"}, {Name: "OPTIONAL_2"}},
|
||||
Forbidden: []KernelConfig{
|
||||
{Name: "FORBIDDEN_1", Description: "TEST FORBIDDEN"},
|
||||
{Name: "FORBIDDEN_2", Aliases: []string{"ALIASE_FORBIDDEN_2"}},
|
||||
},
|
||||
}
|
||||
for c, test := range []struct {
|
||||
desc string
|
||||
config map[string]kConfigOption
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
desc: "meet all required configurations should not report error.",
|
||||
config: map[string]kConfigOption{
|
||||
"REQUIRED_1": builtIn,
|
||||
"REQUIRED_2": asModule,
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
desc: "one required configuration disabled should report error.",
|
||||
config: map[string]kConfigOption{
|
||||
"REQUIRED_1": leftOut,
|
||||
"REQUIRED_2": builtIn,
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
desc: "one required configuration missing should report error.",
|
||||
config: map[string]kConfigOption{
|
||||
"REQUIRED_1": builtIn,
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
desc: "alias of required configuration should not report error.",
|
||||
config: map[string]kConfigOption{
|
||||
"REQUIRED_1": builtIn,
|
||||
"ALIASE_REQUIRED_2": asModule,
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
desc: "optional configuration set or not should not report error.",
|
||||
config: map[string]kConfigOption{
|
||||
"REQUIRED_1": builtIn,
|
||||
"REQUIRED_2": asModule,
|
||||
"OPTIONAL_1": builtIn,
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
desc: "forbidden configuration disabled should not report error.",
|
||||
config: map[string]kConfigOption{
|
||||
"REQUIRED_1": builtIn,
|
||||
"REQUIRED_2": asModule,
|
||||
"FORBIDDEN_1": leftOut,
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
desc: "forbidden configuration built-in should report error.",
|
||||
config: map[string]kConfigOption{
|
||||
"REQUIRED_1": builtIn,
|
||||
"REQUIRED_2": asModule,
|
||||
"FORBIDDEN_1": builtIn,
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
desc: "forbidden configuration built as module should report error.",
|
||||
config: map[string]kConfigOption{
|
||||
"REQUIRED_1": builtIn,
|
||||
"REQUIRED_2": asModule,
|
||||
"FORBIDDEN_1": asModule,
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
desc: "alias of forbidden configuration should report error.",
|
||||
config: map[string]kConfigOption{
|
||||
"REQUIRED_1": builtIn,
|
||||
"REQUIRED_2": asModule,
|
||||
"ALIASE_FORBIDDEN_2": asModule,
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
} {
|
||||
t.Logf("TestCase #%d %s", c, test.desc)
|
||||
// Add kernel config prefix.
|
||||
for k, v := range test.config {
|
||||
delete(test.config, k)
|
||||
test.config[kConfigPrefix+k] = v
|
||||
}
|
||||
err := v.validateCachedKernelConfig(test.config, testKernelSpec)
|
||||
if !test.err {
|
||||
assert.Nil(t, err, "Expect error not to occur with kernel config %q", test.config)
|
||||
} else {
|
||||
assert.NotNil(t, err, "Expect error to occur with kenrel config %q", test.config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateParseKernelConfig(t *testing.T) {
|
||||
config := `CONFIG_1=y
|
||||
CONFIG_2=m
|
||||
CONFIG_3=n`
|
||||
expected := map[string]kConfigOption{
|
||||
"CONFIG_1": builtIn,
|
||||
"CONFIG_2": asModule,
|
||||
"CONFIG_3": leftOut,
|
||||
}
|
||||
v := &KernelValidator{
|
||||
Reporter: DefaultReporter,
|
||||
}
|
||||
got, err := v.parseKernelConfig(bytes.NewReader([]byte(config)))
|
||||
assert.Nil(t, err, "Expect error not to occur when parse kernel configuration %q", config)
|
||||
assert.Equal(t, expected, got)
|
||||
}
|
50
vendor/k8s.io/kubernetes/test/e2e_node/system/os_validator.go
generated
vendored
Normal file
50
vendor/k8s.io/kubernetes/test/e2e_node/system/os_validator.go
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var _ Validator = &OSValidator{}
|
||||
|
||||
type OSValidator struct {
|
||||
Reporter Reporter
|
||||
}
|
||||
|
||||
func (o *OSValidator) Name() string {
|
||||
return "os"
|
||||
}
|
||||
|
||||
func (o *OSValidator) Validate(spec SysSpec) (error, error) {
|
||||
os, err := exec.Command("uname").CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get os name: %v", err)
|
||||
}
|
||||
return nil, o.validateOS(strings.TrimSpace(string(os)), spec.OS)
|
||||
}
|
||||
|
||||
func (o *OSValidator) validateOS(os, specOS string) error {
|
||||
if os != specOS {
|
||||
o.Reporter.Report("OS", os, bad)
|
||||
return fmt.Errorf("unsupported operating system: %s", os)
|
||||
}
|
||||
o.Reporter.Report("OS", os, good)
|
||||
return nil
|
||||
}
|
54
vendor/k8s.io/kubernetes/test/e2e_node/system/os_validator_test.go
generated
vendored
Normal file
54
vendor/k8s.io/kubernetes/test/e2e_node/system/os_validator_test.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestValidateOS(t *testing.T) {
|
||||
v := &OSValidator{
|
||||
Reporter: DefaultReporter,
|
||||
}
|
||||
specOS := "Linux"
|
||||
for _, test := range []struct {
|
||||
os string
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
os: "Linux",
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
os: "Windows",
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
os: "Darwin",
|
||||
err: true,
|
||||
},
|
||||
} {
|
||||
err := v.validateOS(test.os, specOS)
|
||||
if !test.err {
|
||||
assert.Nil(t, err, "Expect error not to occur with os %q", test.os)
|
||||
} else {
|
||||
assert.NotNil(t, err, "Expect error to occur with os %q", test.os)
|
||||
}
|
||||
}
|
||||
}
|
325
vendor/k8s.io/kubernetes/test/e2e_node/system/package_validator.go
generated
vendored
Normal file
325
vendor/k8s.io/kubernetes/test/e2e_node/system/package_validator.go
generated
vendored
Normal file
@ -0,0 +1,325 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/errors"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// semVerDotsCount is the number of dots in a valid semantic version.
|
||||
const semVerDotsCount int = 2
|
||||
|
||||
// packageManager is an interface that abstracts the basic operations of a
|
||||
// package manager.
|
||||
type packageManager interface {
|
||||
// getPackageVersion returns the version of the package given the
|
||||
// packageName, or an error if no such package exists.
|
||||
getPackageVersion(packageName string) (string, error)
|
||||
}
|
||||
|
||||
// newPackageManager returns the package manager on the running machine, and an
|
||||
// error if no package managers is available.
|
||||
func newPackageManager() (packageManager, error) {
|
||||
if m, ok := newDPKG(); ok {
|
||||
return m, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to find package manager")
|
||||
}
|
||||
|
||||
// dpkg implements packageManager. It uses "dpkg-query" to retrieve package
|
||||
// information.
|
||||
type dpkg struct{}
|
||||
|
||||
// newDPKG returns a Debian package manager. It returns (nil, false) if no such
|
||||
// package manager exists on the running machine.
|
||||
func newDPKG() (packageManager, bool) {
|
||||
_, err := exec.LookPath("dpkg-query")
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return dpkg{}, true
|
||||
}
|
||||
|
||||
// getPackageVersion returns the upstream package version for the package given
|
||||
// the packageName, and an error if no such package exists.
|
||||
func (_ dpkg) getPackageVersion(packageName string) (string, error) {
|
||||
output, err := exec.Command("dpkg-query", "--show", "--showformat='${Version}'", packageName).Output()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("dpkg-query failed: %s", err)
|
||||
}
|
||||
version := extractUpstreamVersion(string(output))
|
||||
if version == "" {
|
||||
return "", fmt.Errorf("no version information")
|
||||
}
|
||||
return version, nil
|
||||
}
|
||||
|
||||
// packageValidator implements the Validator interface. It validates packages
|
||||
// and their versions.
|
||||
type packageValidator struct {
|
||||
reporter Reporter
|
||||
kernelRelease string
|
||||
osDistro string
|
||||
}
|
||||
|
||||
// Name returns the name of the package validator.
|
||||
func (self *packageValidator) Name() string {
|
||||
return "package"
|
||||
}
|
||||
|
||||
// Validate checks packages and their versions against the spec using the
|
||||
// package manager on the running machine, and returns an error on any
|
||||
// package/version mismatch.
|
||||
func (self *packageValidator) Validate(spec SysSpec) (error, error) {
|
||||
if len(spec.PackageSpecs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
if self.kernelRelease, err = getKernelRelease(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if self.osDistro, err = getOSDistro(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
manager, err := newPackageManager()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specs := applyPackageSpecOverride(spec.PackageSpecs, spec.PackageSpecOverrides, self.osDistro)
|
||||
return self.validate(specs, manager)
|
||||
}
|
||||
|
||||
// Validate checks packages and their versions against the packageSpecs using
|
||||
// the packageManager, and returns an error on any package/version mismatch.
|
||||
func (self *packageValidator) validate(packageSpecs []PackageSpec, manager packageManager) (error, error) {
|
||||
var errs []error
|
||||
for _, spec := range packageSpecs {
|
||||
// Substitute variables in package name.
|
||||
packageName := resolvePackageName(spec.Name, self.kernelRelease)
|
||||
|
||||
nameWithVerRange := fmt.Sprintf("%s (%s)", packageName, spec.VersionRange)
|
||||
|
||||
// Get the version of the package on the running machine.
|
||||
version, err := manager.getPackageVersion(packageName)
|
||||
if err != nil {
|
||||
glog.V(1).Infof("Failed to get the version for the package %q: %s\n", packageName, err)
|
||||
errs = append(errs, err)
|
||||
self.reporter.Report(nameWithVerRange, "not installed", bad)
|
||||
continue
|
||||
}
|
||||
|
||||
// Version requirement will not be enforced if version range is
|
||||
// not specified in the spec.
|
||||
if spec.VersionRange == "" {
|
||||
self.reporter.Report(packageName, version, good)
|
||||
continue
|
||||
}
|
||||
|
||||
// Convert both the version range in the spec and the version returned
|
||||
// from package manager to semantic version format, and then check if
|
||||
// the version is in the range.
|
||||
sv, err := semver.Make(toSemVer(version))
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to convert %q to semantic version: %s\n", version, err)
|
||||
errs = append(errs, err)
|
||||
self.reporter.Report(nameWithVerRange, "internal error", bad)
|
||||
continue
|
||||
}
|
||||
versionRange := semver.MustParseRange(toSemVerRange(spec.VersionRange))
|
||||
if versionRange(sv) {
|
||||
self.reporter.Report(nameWithVerRange, version, good)
|
||||
} else {
|
||||
errs = append(errs, fmt.Errorf("package \"%s %s\" does not meet the spec \"%s (%s)\"", packageName, sv, packageName, spec.VersionRange))
|
||||
self.reporter.Report(nameWithVerRange, version, bad)
|
||||
}
|
||||
}
|
||||
return nil, errors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
// getKernelRelease returns the kernel release of the local machine.
|
||||
func getKernelRelease() (string, error) {
|
||||
output, err := exec.Command("uname", "-r").Output()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get kernel release: %s", err)
|
||||
}
|
||||
return strings.TrimSpace(string(output)), nil
|
||||
}
|
||||
|
||||
// getOSDistro returns the OS distro of the local machine.
|
||||
func getOSDistro() (string, error) {
|
||||
f := "/etc/lsb-release"
|
||||
b, err := ioutil.ReadFile(f)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to read %q: %s", f, err)
|
||||
}
|
||||
content := string(b)
|
||||
switch {
|
||||
case strings.Contains(content, "Ubuntu"):
|
||||
return "ubuntu", nil
|
||||
case strings.Contains(content, "Chrome OS"):
|
||||
return "cos", nil
|
||||
case strings.Contains(content, "CoreOS"):
|
||||
return "coreos", nil
|
||||
default:
|
||||
return "", fmt.Errorf("failed to get OS distro: %s", content)
|
||||
}
|
||||
}
|
||||
|
||||
// resolvePackageName substitutes the variables in the packageName with the
|
||||
// local information.
|
||||
// E.g., "linux-headers-${KERNEL_RELEASE}" -> "linux-headers-4.4.0-75-generic".
|
||||
func resolvePackageName(packageName string, kernelRelease string) string {
|
||||
packageName = strings.Replace(packageName, "${KERNEL_RELEASE}", kernelRelease, -1)
|
||||
return packageName
|
||||
}
|
||||
|
||||
// applyPackageSpecOverride applies the package spec overrides for the given
|
||||
// osDistro to the packageSpecs and returns the applied result.
|
||||
func applyPackageSpecOverride(packageSpecs []PackageSpec, overrides []PackageSpecOverride, osDistro string) []PackageSpec {
|
||||
var override *PackageSpecOverride
|
||||
for _, o := range overrides {
|
||||
if o.OSDistro == osDistro {
|
||||
override = &o
|
||||
break
|
||||
}
|
||||
}
|
||||
if override == nil {
|
||||
return packageSpecs
|
||||
}
|
||||
|
||||
// Remove packages in the spec that matches the overrides in
|
||||
// Subtractions.
|
||||
var out []PackageSpec
|
||||
subtractions := make(map[string]bool)
|
||||
for _, spec := range override.Subtractions {
|
||||
subtractions[spec.Name] = true
|
||||
}
|
||||
for _, spec := range packageSpecs {
|
||||
if _, ok := subtractions[spec.Name]; !ok {
|
||||
out = append(out, spec)
|
||||
}
|
||||
}
|
||||
|
||||
// Add packages in the spec that matches the overrides in Additions.
|
||||
return append(out, override.Additions...)
|
||||
}
|
||||
|
||||
// extractUpstreamVersion returns the upstream version of the given full
|
||||
// version in dpkg format. E.g., "1:1.0.6-2ubuntu2.1" -> "1.0.6".
|
||||
func extractUpstreamVersion(version string) string {
|
||||
// The full version is in the format of
|
||||
// "[epoch:]upstream_version[-debian_revision]". See
|
||||
// https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version.
|
||||
version = strings.Trim(version, " '")
|
||||
if i := strings.Index(version, ":"); i != -1 {
|
||||
version = version[i+1:]
|
||||
}
|
||||
if i := strings.Index(version, "-"); i != -1 {
|
||||
version = version[:i]
|
||||
}
|
||||
return version
|
||||
}
|
||||
|
||||
// toSemVerRange converts the input to a semantic version range.
|
||||
// E.g., ">=1.0" -> ">=1.0.x"
|
||||
// ">=1" -> ">=1.x"
|
||||
// ">=1 <=2.3" -> ">=1.x <=2.3.x"
|
||||
// ">1 || >3.1.0 !4.2" -> ">1.x || >3.1.0 !4.2.x"
|
||||
func toSemVerRange(input string) string {
|
||||
var output []string
|
||||
fields := strings.Fields(input)
|
||||
for _, f := range fields {
|
||||
numDots, hasDigits := 0, false
|
||||
for _, c := range f {
|
||||
switch {
|
||||
case c == '.':
|
||||
numDots++
|
||||
case c >= '0' && c <= '9':
|
||||
hasDigits = true
|
||||
}
|
||||
}
|
||||
if hasDigits && numDots < semVerDotsCount {
|
||||
f = strings.TrimRight(f, " ")
|
||||
f += ".x"
|
||||
}
|
||||
output = append(output, f)
|
||||
}
|
||||
return strings.Join(output, " ")
|
||||
}
|
||||
|
||||
// toSemVer converts the input to a semantic version, and an empty string on
|
||||
// error.
|
||||
func toSemVer(version string) string {
|
||||
// Remove the first non-digit and non-dot character as well as the ones
|
||||
// following it.
|
||||
// E.g., "1.8.19p1" -> "1.8.19".
|
||||
if i := strings.IndexFunc(version, func(c rune) bool {
|
||||
if (c < '0' || c > '9') && c != '.' {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}); i != -1 {
|
||||
version = version[:i]
|
||||
}
|
||||
|
||||
// Remove the trailing dots if there's any, and then returns an empty
|
||||
// string if nothing left.
|
||||
version = strings.TrimRight(version, ".")
|
||||
if version == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
numDots := strings.Count(version, ".")
|
||||
switch {
|
||||
case numDots < semVerDotsCount:
|
||||
// Add minor version and patch version.
|
||||
// E.g. "1.18" -> "1.18.0" and "481" -> "481.0.0".
|
||||
version += strings.Repeat(".0", semVerDotsCount-numDots)
|
||||
case numDots > semVerDotsCount:
|
||||
// Remove anything beyond the patch version
|
||||
// E.g. "2.0.10.4" -> "2.0.10".
|
||||
for numDots != semVerDotsCount {
|
||||
if i := strings.LastIndex(version, "."); i != -1 {
|
||||
version = version[:i]
|
||||
numDots--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove leading zeros in major/minor/patch version.
|
||||
// E.g., "2.02" -> "2.2"
|
||||
// "8.0.0095" -> "8.0.95"
|
||||
var subs []string
|
||||
for _, s := range strings.Split(version, ".") {
|
||||
s := strings.TrimLeft(s, "0")
|
||||
if s == "" {
|
||||
s = "0"
|
||||
}
|
||||
subs = append(subs, s)
|
||||
}
|
||||
return strings.Join(subs, ".")
|
||||
}
|
266
vendor/k8s.io/kubernetes/test/e2e_node/system/package_validator_test.go
generated
vendored
Normal file
266
vendor/k8s.io/kubernetes/test/e2e_node/system/package_validator_test.go
generated
vendored
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExtractUpstreamVersion(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
input: "",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
input: "1.0.6",
|
||||
expected: "1.0.6",
|
||||
},
|
||||
{
|
||||
input: "1:1.0.6",
|
||||
expected: "1.0.6",
|
||||
},
|
||||
{
|
||||
input: "1.0.6-2ubuntu2.1",
|
||||
expected: "1.0.6",
|
||||
},
|
||||
{
|
||||
input: "1:1.0.6-2ubuntu2.1",
|
||||
expected: "1.0.6",
|
||||
},
|
||||
} {
|
||||
got := extractUpstreamVersion(test.input)
|
||||
if test.expected != got {
|
||||
t.Errorf("extractUpstreamVersion(%q) = %q, want %q", test.input, got, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestToSemVer(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
input: "",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
input: "1.2.3",
|
||||
expected: "1.2.3",
|
||||
},
|
||||
{
|
||||
input: "1.8.19p1",
|
||||
expected: "1.8.19",
|
||||
},
|
||||
{
|
||||
input: "1.8.19.p1",
|
||||
expected: "1.8.19",
|
||||
},
|
||||
{
|
||||
input: "p1",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
input: "1.18",
|
||||
expected: "1.18.0",
|
||||
},
|
||||
{
|
||||
input: "481",
|
||||
expected: "481.0.0",
|
||||
},
|
||||
{
|
||||
input: "2.0.10.4",
|
||||
expected: "2.0.10",
|
||||
},
|
||||
{
|
||||
input: "03",
|
||||
expected: "3.0.0",
|
||||
},
|
||||
{
|
||||
input: "2.02",
|
||||
expected: "2.2.0",
|
||||
},
|
||||
{
|
||||
input: "8.0.0095",
|
||||
expected: "8.0.95",
|
||||
},
|
||||
} {
|
||||
got := toSemVer(test.input)
|
||||
if test.expected != got {
|
||||
t.Errorf("toSemVer(%q) = %q, want %q", test.input, got, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestToSemVerRange(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
input: "",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
input: ">=1.0.0",
|
||||
expected: ">=1.0.0",
|
||||
},
|
||||
{
|
||||
input: ">=1.0",
|
||||
expected: ">=1.0.x",
|
||||
},
|
||||
{
|
||||
input: ">=1",
|
||||
expected: ">=1.x",
|
||||
},
|
||||
{
|
||||
input: ">=1 || !2.3",
|
||||
expected: ">=1.x || !2.3.x",
|
||||
},
|
||||
{
|
||||
input: ">1 || >3.1.0 !4.2",
|
||||
expected: ">1.x || >3.1.0 !4.2.x",
|
||||
},
|
||||
} {
|
||||
got := toSemVerRange(test.input)
|
||||
if test.expected != got {
|
||||
t.Errorf("toSemVerRange(%q) = %q, want %q", test.input, got, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// testPackageManager implements the packageManager interface.
|
||||
type testPackageManager struct {
|
||||
packageVersions map[string]string
|
||||
}
|
||||
|
||||
func (m testPackageManager) getPackageVersion(packageName string) (string, error) {
|
||||
if v, ok := m.packageVersions[packageName]; ok {
|
||||
return v, nil
|
||||
}
|
||||
return "", fmt.Errorf("package %q does not exist", packageName)
|
||||
}
|
||||
|
||||
func TestValidatePackageVersion(t *testing.T) {
|
||||
testKernelRelease := "test-kernel-release"
|
||||
manager := testPackageManager{
|
||||
packageVersions: map[string]string{
|
||||
"foo": "1.0.0",
|
||||
"bar": "2.1.0",
|
||||
"bar-" + testKernelRelease: "3.0.0",
|
||||
},
|
||||
}
|
||||
v := &packageValidator{
|
||||
reporter: DefaultReporter,
|
||||
kernelRelease: testKernelRelease,
|
||||
}
|
||||
for _, test := range []struct {
|
||||
desc string
|
||||
specs []PackageSpec
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "all packages meet the spec",
|
||||
specs: []PackageSpec{
|
||||
{Name: "foo", VersionRange: ">=1.0"},
|
||||
{Name: "bar", VersionRange: ">=2.0 <= 3.0"},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "package version does not meet the spec",
|
||||
specs: []PackageSpec{
|
||||
{Name: "foo", VersionRange: ">=1.0"},
|
||||
{Name: "bar", VersionRange: ">=3.0"},
|
||||
},
|
||||
err: errors.New("package \"bar 2.1.0\" does not meet the spec \"bar (>=3.0)\""),
|
||||
},
|
||||
{
|
||||
desc: "package not installed",
|
||||
specs: []PackageSpec{
|
||||
{Name: "baz"},
|
||||
},
|
||||
err: errors.New("package \"baz\" does not exist"),
|
||||
},
|
||||
{
|
||||
desc: "use variable in package name",
|
||||
specs: []PackageSpec{
|
||||
{Name: "bar-${KERNEL_RELEASE}", VersionRange: ">=3.0"},
|
||||
},
|
||||
},
|
||||
} {
|
||||
_, err := v.validate(test.specs, manager)
|
||||
if test.err == nil && err != nil {
|
||||
t.Errorf("%s: v.validate(): err = %s", test.desc, err)
|
||||
}
|
||||
if test.err != nil {
|
||||
if err == nil {
|
||||
t.Errorf("%s: v.validate() is expected to fail.", test.desc)
|
||||
} else if test.err.Error() != err.Error() {
|
||||
t.Errorf("%s: v.validate(): err = %q, want = %q", test.desc, err, test.err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyPackageOverride(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
overrides []PackageSpecOverride
|
||||
osDistro string
|
||||
specs []PackageSpec
|
||||
expected []PackageSpec
|
||||
}{
|
||||
{
|
||||
specs: []PackageSpec{{Name: "foo", VersionRange: ">=1.0"}},
|
||||
expected: []PackageSpec{{Name: "foo", VersionRange: ">=1.0"}},
|
||||
},
|
||||
{
|
||||
osDistro: "ubuntu",
|
||||
overrides: []PackageSpecOverride{
|
||||
{
|
||||
OSDistro: "ubuntu",
|
||||
Subtractions: []PackageSpec{{Name: "foo"}},
|
||||
Additions: []PackageSpec{{Name: "bar", VersionRange: ">=2.0"}},
|
||||
},
|
||||
},
|
||||
specs: []PackageSpec{{Name: "foo", VersionRange: ">=1.0"}},
|
||||
expected: []PackageSpec{{Name: "bar", VersionRange: ">=2.0"}},
|
||||
},
|
||||
{
|
||||
osDistro: "ubuntu",
|
||||
overrides: []PackageSpecOverride{
|
||||
{
|
||||
OSDistro: "debian",
|
||||
Subtractions: []PackageSpec{{Name: "foo"}},
|
||||
},
|
||||
},
|
||||
specs: []PackageSpec{{Name: "foo", VersionRange: ">=1.0"}},
|
||||
expected: []PackageSpec{{Name: "foo", VersionRange: ">=1.0"}},
|
||||
},
|
||||
} {
|
||||
got := applyPackageSpecOverride(test.specs, test.overrides, test.osDistro)
|
||||
if !reflect.DeepEqual(test.expected, got) {
|
||||
t.Errorf("applyPackageSpecOverride(%+v, %+v, %s) = %+v, want = %+v", test.specs, test.overrides, test.osDistro, got, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
78
vendor/k8s.io/kubernetes/test/e2e_node/system/report.go
generated
vendored
Normal file
78
vendor/k8s.io/kubernetes/test/e2e_node/system/report.go
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// ValidationResultType is type of the validation result. Different validation results
|
||||
// corresponds to different colors.
|
||||
type ValidationResultType int32
|
||||
|
||||
const (
|
||||
good ValidationResultType = iota
|
||||
bad
|
||||
warn
|
||||
)
|
||||
|
||||
// color is the color of the message.
|
||||
type color int32
|
||||
|
||||
const (
|
||||
red color = 31
|
||||
green = 32
|
||||
yellow = 33
|
||||
white = 37
|
||||
)
|
||||
|
||||
func colorize(s string, c color) string {
|
||||
return fmt.Sprintf("\033[0;%dm%s\033[0m", c, s)
|
||||
}
|
||||
|
||||
// The default reporter for the system verification test
|
||||
type StreamReporter struct {
|
||||
// The stream that this reporter is writing to
|
||||
WriteStream io.Writer
|
||||
}
|
||||
|
||||
func (dr *StreamReporter) Report(key, value string, resultType ValidationResultType) error {
|
||||
var c color
|
||||
switch resultType {
|
||||
case good:
|
||||
c = green
|
||||
case bad:
|
||||
c = red
|
||||
case warn:
|
||||
c = yellow
|
||||
default:
|
||||
c = white
|
||||
}
|
||||
if dr.WriteStream == nil {
|
||||
return fmt.Errorf("WriteStream has to be defined for this reporter")
|
||||
}
|
||||
|
||||
fmt.Fprintf(dr.WriteStream, "%s: %s\n", colorize(key, white), colorize(value, c))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultReporter is the default Reporter
|
||||
var DefaultReporter = &StreamReporter{
|
||||
WriteStream: os.Stdout,
|
||||
}
|
272
vendor/k8s.io/kubernetes/test/e2e_node/system/specs/gke.yaml
generated
vendored
Normal file
272
vendor/k8s.io/kubernetes/test/e2e_node/system/specs/gke.yaml
generated
vendored
Normal file
@ -0,0 +1,272 @@
|
||||
# This is the system spec that must be satisfied by the images running on GKE.
|
||||
|
||||
os: Linux
|
||||
|
||||
kernelSpec:
|
||||
versions:
|
||||
# GKE requires kernel version 4.4+.
|
||||
- '4\.[4-9].*'
|
||||
- '4\.[1-9][0-9].*'
|
||||
- '[5-9].*'
|
||||
|
||||
# Required kernel configurations -- the configuration must be set to "y" or
|
||||
# "m".
|
||||
required:
|
||||
# The configurations required by virtual machine or cloud provider.
|
||||
|
||||
- name: BOOTPARAM_HARDLOCKUP_PANIC
|
||||
description: 'Enable the kernel to panic on "hard lockups".'
|
||||
- name: BOOTPARAM_SOFTLOCKUP_PANIC
|
||||
description: 'Enable the kernel to panic on "soft lockups".'
|
||||
- name: PANIC_ON_OOPS
|
||||
description: 'Enable the kernel to panic when it oops.'
|
||||
- name: PVPANIC
|
||||
description: 'Enable the VM (guest) to communicate panic events with the
|
||||
host.'
|
||||
- name: DMIID
|
||||
description: 'Make sure /sys/class/dmi is exported - cAdvisor currently
|
||||
uses this to determine which the cloud provider it is: aws, azure, or
|
||||
gce, etc'
|
||||
- name: ACPI_BUTTON
|
||||
description: 'Enable the software-controlled power management, and required
|
||||
by reset or stop button of GCE console.'
|
||||
|
||||
# The configurations required by network.
|
||||
|
||||
- name: INET
|
||||
description: 'Enable TCP/IP networking.'
|
||||
- name: VXLAN
|
||||
description: 'Required by the overlay networking in Kubernetes.'
|
||||
- name: IP_SET
|
||||
description: 'Required by Kubernetes network policy.'
|
||||
- name: IP_SET_HASH_IP
|
||||
description: 'This introduces hash:ip set type support, which is required
|
||||
by Kubernetes Calico networking.'
|
||||
- name: IPVLAN
|
||||
description: 'Required by IPVLAN feature.'
|
||||
- name: IPV6
|
||||
description: 'Required by IPVLAN feature.'
|
||||
- name: IP6_NF_IPTABLES
|
||||
description: 'Required by kube-proxy.'
|
||||
- name: IP_NF_TARGET_REDIRECT
|
||||
alias:
|
||||
- NETFILTER_XT_TARGET_REDIRECT
|
||||
description: 'Enabled REDIRECT: all incoming connections are mapped onto
|
||||
the incoming interface''s address, causing the packets to come to the
|
||||
local machine instead of passing through. This is required by
|
||||
kube-proxy.'
|
||||
- name: NETFILTER_XT_MATCH_COMMENT
|
||||
description: 'This option adds a "comment" dummy-match, which allows you to
|
||||
put comments in your iptables ruleset. Today''s kube-proxy implementation
|
||||
depends on this feature.'
|
||||
# This is not critical, but debian-based container-vm kernel module study
|
||||
# shows that many customers' nodes have loaded those kernel modules. We
|
||||
# suspect sysdig module depends on these set of kernel modules for
|
||||
# monitoring.
|
||||
- name: PACKET_DIAG
|
||||
description: 'Required by ss (similar to netstat) tools to display Linux
|
||||
TCP / UDP network and socket information.'
|
||||
- name: UNIX_DIAG
|
||||
description: 'Required by ss (similar to netstat) tools to display Linux
|
||||
TCP / UDP network and socket information.'
|
||||
- name: INET_DIAG
|
||||
description: 'Required by ss (similar to netstat) tools to display Linux
|
||||
TCP / UDP network and socket information.'
|
||||
- name: INET_TCP_DIAG
|
||||
description: 'Required by ss (similar to netstat) tools to display Linux
|
||||
TCP / UDP network and socket information.'
|
||||
- name: INET_UDP_DIAG
|
||||
description: 'Required by ss (similar to netstat) tools to display Linux
|
||||
TCP / UDP network and socket information.'
|
||||
- name: NETLINK_DIAG
|
||||
description: 'Required by ss (similar to netstat) tools to display Linux
|
||||
TCP / UDP network and socket information.'
|
||||
|
||||
# The configurations are required by filesystem.
|
||||
|
||||
- name: EXT4_FS
|
||||
- name: DEBUG_FS
|
||||
- name: PROC_FS
|
||||
- name: XFS_FS
|
||||
- name: SCSI_PROC_FS
|
||||
# Currently Kubelet supports three docker graph drivers: overlay, aufs, and
|
||||
# devicemapper due to the legacy reason. But for GKE, we plan to only support
|
||||
# overlayfs.
|
||||
- name: OVERLAY_FS
|
||||
description: 'Enable OverlayFS, which will be the only docker graph driver
|
||||
supported on GKE.'
|
||||
- name: NFS_FS
|
||||
description: 'Required by NFS support.'
|
||||
- name: AUTOFS4_FS
|
||||
description: 'Required by NFS support.'
|
||||
- name: NFS_FSCACHE
|
||||
description: 'Required by NFS support.'
|
||||
- name: FSCACHE
|
||||
description: 'Required by NFS support.'
|
||||
- name: CACHEFILES
|
||||
description: 'Required by NFS support.'
|
||||
- name: FUSE_FS
|
||||
description: 'Required by GlusterFS support.'
|
||||
- name: BCACHE
|
||||
# TODO(yguo0905): Add a description for BCACHE.
|
||||
|
||||
# The configuration required by the resource isolation, accounting, and
|
||||
# management.
|
||||
|
||||
- name: NAMESPACES
|
||||
description: 'Required by kubelet and docker. Enabling it allows the
|
||||
processes within a pod or a container to have their own view of the
|
||||
system.'
|
||||
- name: IPC_NS
|
||||
description: 'Required by kubelet and docker. Enabling it allows the
|
||||
processes within a pod or a container to have their own view of the
|
||||
system.'
|
||||
- name: NET_NS
|
||||
description: 'Required by kubelet and docker. Enabling it allows the
|
||||
processes within a pod or a container to have their own view of the
|
||||
system.'
|
||||
- name: PID_NS
|
||||
description: 'Required by kubelet and docker. Enabling it allows the
|
||||
processes within a pod or a container to have their own view of the
|
||||
system.'
|
||||
- name: UTS_NS
|
||||
description: 'Required by kubelet and docker. Enabling it allows the
|
||||
processes within a pod or a container to have their own view of the
|
||||
system.'
|
||||
- name: CGROUPS
|
||||
description: 'Required by kubelet and docker. The resource usage of the
|
||||
processes within a pod or a container can be monitored, accounted, and
|
||||
controlled.'
|
||||
- name: CGROUP_CPUACCT
|
||||
description: 'Required by kubelet and docker. The resource usage of the
|
||||
processes within a pod or a container can be monitored, accounted, and
|
||||
controlled.'
|
||||
- name: CGROUP_DEVICE
|
||||
description: 'Required by kubelet and docker. The resource usage of the
|
||||
processes within a pod or a container can be monitored, accounted, and
|
||||
controlled.'
|
||||
- name: CGROUP_SCHED
|
||||
description: 'Required by kubelet and docker. The resource usage of the
|
||||
processes within a pod or a container can be monitored, accounted, and
|
||||
controlled.'
|
||||
- name: CPUSETS
|
||||
description: 'Required by kubelet and docker. The resource usage of the
|
||||
processes within a pod or a container can be monitored, accounted, and
|
||||
controlled.'
|
||||
- name: MEMCG
|
||||
description: 'Required by kubelet and docker. The resource usage of the
|
||||
processes within a pod or a container can be monitored, accounted, and
|
||||
controlled.'
|
||||
- name: QUOTA
|
||||
description: 'Required by kubelet to have an accurate and efficient disk
|
||||
space and inode accounting, and eventually to limit the usage.'
|
||||
|
||||
# The security-related configurations
|
||||
|
||||
- name: SECCOMP
|
||||
description: 'Enabled the SECCOMP application API.'
|
||||
- name: SECURITY_APPARMOR
|
||||
description: 'Enable for AppArmor support.'
|
||||
- name: CC_STACKPROTECTOR_STRONG
|
||||
alias:
|
||||
- CONFIG_CC_STACKPROTECTOR_REGULAR
|
||||
CONFIG_CC_STACKPROTECTOR_ALL
|
||||
description: 'Add the stack buffer overflow protections.'
|
||||
- name: STRICT_DEVMEM
|
||||
description: 'Required for blocking the direct physical memory access.'
|
||||
- name: IMA
|
||||
description: 'Required for security-related logging and auditing.'
|
||||
- name: AUDIT
|
||||
description: 'Required for security-related logging and auditing.'
|
||||
- name: AUDITSYSCALL
|
||||
description: 'Required for security-related logging and auditing.'
|
||||
|
||||
# Misc. configurations
|
||||
|
||||
- name: MODULES
|
||||
description: 'Required for loadable module support.'
|
||||
- name: PRINTK
|
||||
description: 'Required for kernel logging message.'
|
||||
- name: MMU
|
||||
description: 'Required for memory management hardware and mmap() system
|
||||
call.'
|
||||
|
||||
packageSpecs:
|
||||
- name: apparmor
|
||||
versionRange: '>=2.10.1'
|
||||
- name: apparmor-profiles
|
||||
versionRange: '>=2.10.1'
|
||||
- name: audit
|
||||
versionRange: '>=2.5.0'
|
||||
- name: autofs
|
||||
versionRange: '>=5.0.7'
|
||||
- name: bash
|
||||
versionRange: '>=4.3'
|
||||
- name: bridge-utils
|
||||
versionRange: '>=1.5'
|
||||
- name: cloud-init
|
||||
versionRange: '>=0.7.6'
|
||||
- name: coreutils
|
||||
versionRange: '>=8.24'
|
||||
- name: dbus
|
||||
versionRange: '>=1.6.8'
|
||||
- name: e2fsprogs
|
||||
versionRange: '>=1.4.3'
|
||||
- name: ebtables
|
||||
versionRange: '>=2.0.10'
|
||||
- name: ethtool
|
||||
versionRange: '>=3.18'
|
||||
- name: iproute2
|
||||
versionRange: '>=4.2.0'
|
||||
- name: less
|
||||
versionRange: '>=481'
|
||||
- name: linux-headers-${KERNEL_RELEASE}
|
||||
- name: netcat-openbsd
|
||||
versionRange: '>=1.10'
|
||||
- name: python
|
||||
versionRange: '>=2.7.10'
|
||||
- name: pv
|
||||
versionRange: '>=1.3.4'
|
||||
- name: sudo
|
||||
versionRange: '>=1.8.12'
|
||||
- name: systemd
|
||||
versionRange: '>=225'
|
||||
- name: tar
|
||||
versionRange: '>=1.28'
|
||||
- name: util-linux
|
||||
versionRange: '>=2.27.1'
|
||||
- name: vim
|
||||
versionRange: '>=7.4.712'
|
||||
- name: wget
|
||||
versionRange: '>=1.18'
|
||||
- name: gce-compute-image-packages
|
||||
versionRange: '>=20170227'
|
||||
# TODO(yguo0905): Figure out whether watchdog is required.
|
||||
|
||||
# packageSpecOverrides contains the OS distro specific package requirements.
|
||||
packageSpecOverrides:
|
||||
# The following overrides apply to all Ubuntu images.
|
||||
- osDistro: ubuntu
|
||||
subtractions:
|
||||
- name: apparmor-profiles
|
||||
description: 'On Ubuntu the apparmor profiles are shipped with individual
|
||||
application package, so the "apparmor-profiles" package is not required.'
|
||||
- name: audit
|
||||
description: 'On Ubuntu the equivalent package is called "auditd", so the
|
||||
"audit" package is not required and "auditd" exists in the additions.'
|
||||
- name: wget
|
||||
description: 'The Ubuntu 1604-xenial image includes wget 1.17.1, which does
|
||||
not satisfy the spec (>=1.18), but meets the functionality requirements.
|
||||
Therefore, it is removed from the base spec. See wget in the additions.'
|
||||
additions:
|
||||
- name: auditd
|
||||
versionRange: '>=2.4.5'
|
||||
description: 'auditd 2.4.5 currently satisfies the requirements because the
|
||||
GKE features that require auditd 2.5 are not yet available.'
|
||||
- name: grub-common
|
||||
versionRange: '>=2.2'
|
||||
description: 'grub is the bootloader on Ubuntu.'
|
||||
- name: wget
|
||||
versionRange: '>=1.17.1'
|
||||
description: 'wget 1.17.1 satisfies the functionality requirements but does
|
||||
not meet the spec, which is fine'
|
124
vendor/k8s.io/kubernetes/test/e2e_node/system/types.go
generated
vendored
Normal file
124
vendor/k8s.io/kubernetes/test/e2e_node/system/types.go
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
// KernelConfig defines one kernel configration item.
|
||||
type KernelConfig struct {
|
||||
// Name is the general name of the kernel configuration. It is used to
|
||||
// match kernel configuration.
|
||||
Name string `json:"name,omitempty"`
|
||||
// TODO(yguo0905): Support the "or" operation, which will be the same
|
||||
// as the "aliases".
|
||||
//
|
||||
// Aliases are aliases of the kernel configuration. Some configuration
|
||||
// has different names in different kernel version. Names of different
|
||||
// versions will be treated as aliases.
|
||||
Aliases []string `json:"aliases,omitempty"`
|
||||
// Description is the description of the kernel configuration, for example:
|
||||
// * What is it used for?
|
||||
// * Why is it needed?
|
||||
// * Who needs it?
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// KernelSpec defines the specification for the kernel. Currently, it contains
|
||||
// specification for:
|
||||
// * Kernel Version
|
||||
// * Kernel Configuration
|
||||
type KernelSpec struct {
|
||||
// Versions define supported kernel version. It is a group of regexps.
|
||||
Versions []string `json:"versions,omitempty"`
|
||||
// Required contains all kernel configurations required to be enabled
|
||||
// (built in or as module).
|
||||
Required []KernelConfig `json:"required,omitempty"`
|
||||
// Optional contains all kernel configurations are required for optional
|
||||
// features.
|
||||
Optional []KernelConfig `json:"optional,omitempty"`
|
||||
// Forbidden contains all kernel configurations which areforbidden (disabled
|
||||
// or not set)
|
||||
Forbidden []KernelConfig `json:"forbidden,omitempty"`
|
||||
}
|
||||
|
||||
// DockerSpec defines the requirement configuration for docker. Currently, it only
|
||||
// contains spec for graph driver.
|
||||
type DockerSpec struct {
|
||||
// Version is a group of regex matching supported docker versions.
|
||||
Version []string `json:"version,omitempty"`
|
||||
// GraphDriver is the graph drivers supported by kubelet.
|
||||
GraphDriver []string `json:"graphDriver,omitempty"`
|
||||
}
|
||||
|
||||
// RuntimeSpec is the abstract layer for different runtimes. Different runtimes
|
||||
// should put their spec inside the RuntimeSpec.
|
||||
type RuntimeSpec struct {
|
||||
*DockerSpec `json:",inline"`
|
||||
}
|
||||
|
||||
// PackageSpec defines the required packages and their versions.
|
||||
// PackageSpec is only supported on OS distro with Debian package manager.
|
||||
//
|
||||
// TODO(yguo0905): Support operator OR of multiple packages for the case where
|
||||
// either "foo (>=1.0)" or "bar (>=2.0)" is required.
|
||||
type PackageSpec struct {
|
||||
// Name is the name of the package to be checked.
|
||||
Name string `json:"name,omitempty"`
|
||||
// VersionRange represents a range of versions that the package must
|
||||
// satisfy. Note that the version requirement will not be enforced if
|
||||
// the version range is empty. For example,
|
||||
// - "" would match any versions but the package must be installed.
|
||||
// - ">=1" would match "1.0.0", "1.0.1", "1.1.0", and "2.0".
|
||||
// - ">1.0 <2.0" would match between both ranges, so "1.1.1" and "1.8.7"
|
||||
// but not "1.0.0" or "2.0.0".
|
||||
// - "<2.0.0 || >=3.0.0" would match "1.0.0" and "3.0.0" but not "2.0.0".
|
||||
VersionRange string `json:"versionRange,omitempty"`
|
||||
// Description explains the reason behind this package requirements.
|
||||
//
|
||||
// TODO(yguo0905): Print the description where necessary.
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// PackageSpecOverride defines the overrides on the PackageSpec for an OS
|
||||
// distro.
|
||||
type PackageSpecOverride struct {
|
||||
// OSDistro identifies to which OS distro this override applies.
|
||||
// Must be "ubuntu", "cos" or "coreos".
|
||||
OSDistro string `json:"osDistro,omitempty"`
|
||||
// Subtractions is a list of package names that are excluded from the
|
||||
// package spec.
|
||||
Subtractions []PackageSpec `json:"subtractions,omitempty"`
|
||||
// Additions is a list of additional package requirements included the
|
||||
// package spec.
|
||||
Additions []PackageSpec `json:"additions,omitempty"`
|
||||
}
|
||||
|
||||
// SysSpec defines the requirement of supported system. Currently, it only contains
|
||||
// spec for OS, Kernel and Cgroups.
|
||||
type SysSpec struct {
|
||||
// OS is the operating system of the SysSpec.
|
||||
OS string `json:"os,omitempty"`
|
||||
// KernelConfig defines the spec for kernel.
|
||||
KernelSpec KernelSpec `json:"kernelSpec,omitempty"`
|
||||
// Cgroups is the required cgroups.
|
||||
Cgroups []string `json:"cgroups,omitempty"`
|
||||
// RuntimeSpec defines the spec for runtime.
|
||||
RuntimeSpec RuntimeSpec `json:"runtimeSpec,omitempty"`
|
||||
// PackageSpec defines the required packages and their versions.
|
||||
PackageSpecs []PackageSpec `json:"packageSpecs,omitempty"`
|
||||
// PackageSpec defines the overrides of the required packages and their
|
||||
// versions for an OS distro.
|
||||
PackageSpecOverrides []PackageSpecOverride `json:"packageSpecOverrides,omitempty"`
|
||||
}
|
83
vendor/k8s.io/kubernetes/test/e2e_node/system/types_unix.go
generated
vendored
Normal file
83
vendor/k8s.io/kubernetes/test/e2e_node/system/types_unix.go
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// dockerEndpoint is the os specific endpoint for docker communication
|
||||
const dockerEndpoint = "unix:///var/run/docker.sock"
|
||||
|
||||
// DefaultSysSpec is the default SysSpec for Linux
|
||||
var DefaultSysSpec = SysSpec{
|
||||
OS: "Linux",
|
||||
KernelSpec: KernelSpec{
|
||||
Versions: []string{`3\.[1-9][0-9].*`, `4\..*`}, // Requires 3.10+ or 4+
|
||||
// TODO(random-liu): Add more config
|
||||
// TODO(random-liu): Add description for each kernel configuration:
|
||||
Required: []KernelConfig{
|
||||
{Name: "NAMESPACES"},
|
||||
{Name: "NET_NS"},
|
||||
{Name: "PID_NS"},
|
||||
{Name: "IPC_NS"},
|
||||
{Name: "UTS_NS"},
|
||||
{Name: "CGROUPS"},
|
||||
{Name: "CGROUP_CPUACCT"},
|
||||
{Name: "CGROUP_DEVICE"},
|
||||
{Name: "CGROUP_FREEZER"},
|
||||
{Name: "CGROUP_SCHED"},
|
||||
{Name: "CPUSETS"},
|
||||
{Name: "MEMCG"},
|
||||
{Name: "INET"},
|
||||
{Name: "EXT4_FS"},
|
||||
{Name: "PROC_FS"},
|
||||
{Name: "NETFILTER_XT_TARGET_REDIRECT", Aliases: []string{"IP_NF_TARGET_REDIRECT"}},
|
||||
{Name: "NETFILTER_XT_MATCH_COMMENT"},
|
||||
},
|
||||
Optional: []KernelConfig{
|
||||
{Name: "OVERLAY_FS", Aliases: []string{"OVERLAYFS_FS"}, Description: "Required for overlayfs."},
|
||||
{Name: "AUFS_FS", Description: "Required for aufs."},
|
||||
{Name: "BLK_DEV_DM", Description: "Required for devicemapper."},
|
||||
},
|
||||
Forbidden: []KernelConfig{},
|
||||
},
|
||||
Cgroups: []string{"cpu", "cpuacct", "cpuset", "devices", "freezer", "memory"},
|
||||
RuntimeSpec: RuntimeSpec{
|
||||
DockerSpec: &DockerSpec{
|
||||
Version: []string{`1\.1[1-3]\..*`, `17\.03\..*`}, // Requires [1.11, 17.03]
|
||||
GraphDriver: []string{"aufs", "overlay", "overlay2", "devicemapper"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// KernelValidatorHelperImpl is the 'linux' implementation of KernelValidatorHelper
|
||||
type KernelValidatorHelperImpl struct{}
|
||||
|
||||
var _ KernelValidatorHelper = &KernelValidatorHelperImpl{}
|
||||
|
||||
// GetKernelReleaseVersion returns the kernel release version (ex. 4.4.0-96-generic) as a string
|
||||
func (o *KernelValidatorHelperImpl) GetKernelReleaseVersion() (string, error) {
|
||||
releaseVersion, err := exec.Command("uname", "-r").CombinedOutput()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSpace(string(releaseVersion)), nil
|
||||
}
|
60
vendor/k8s.io/kubernetes/test/e2e_node/system/types_windows.go
generated
vendored
Normal file
60
vendor/k8s.io/kubernetes/test/e2e_node/system/types_windows.go
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
// +build windows
|
||||
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// dockerEndpoint is the os specific endpoint for docker communication
|
||||
const dockerEndpoint = "npipe:////./pipe/docker_engine"
|
||||
|
||||
// DefaultSysSpec is the default SysSpec for Windows
|
||||
var DefaultSysSpec = SysSpec{
|
||||
OS: "Microsoft Windows Server 2016",
|
||||
KernelSpec: KernelSpec{
|
||||
Versions: []string{`10\.0\.1439[3-9]`, `10\.0\.14[4-9][0-9]{2}`, `10\.0\.1[5-9][0-9]{3}`, `10\.0\.[2-9][0-9]{4}`, `10\.[1-9]+\.[0-9]+`}, //requires >= '10.0.14393'
|
||||
Required: []KernelConfig{},
|
||||
Optional: []KernelConfig{},
|
||||
Forbidden: []KernelConfig{},
|
||||
},
|
||||
Cgroups: []string{},
|
||||
RuntimeSpec: RuntimeSpec{
|
||||
DockerSpec: &DockerSpec{
|
||||
Version: []string{`17\.03\..*`}, //Requires [17.03] or later
|
||||
GraphDriver: []string{"windowsfilter"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// KernelValidatorHelperImpl is the 'windows' implementation of KernelValidatorHelper
|
||||
type KernelValidatorHelperImpl struct{}
|
||||
|
||||
var _ KernelValidatorHelper = &KernelValidatorHelperImpl{}
|
||||
|
||||
// GetKernelRelease returns the windows release version (ex. 10.0.14393) as a string
|
||||
func (o *KernelValidatorHelperImpl) GetKernelReleaseVersion() (string, error) {
|
||||
args := []string{"(Get-CimInstance Win32_OperatingSystem).Version"}
|
||||
releaseVersion, err := exec.Command("powershell", args...).Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSpace(string(releaseVersion)), nil
|
||||
}
|
72
vendor/k8s.io/kubernetes/test/e2e_node/system/validators.go
generated
vendored
Normal file
72
vendor/k8s.io/kubernetes/test/e2e_node/system/validators.go
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 system
|
||||
|
||||
import (
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/apimachinery/pkg/util/errors"
|
||||
)
|
||||
|
||||
// Validator is the interface for all validators.
|
||||
type Validator interface {
|
||||
// Name is the name of the validator.
|
||||
Name() string
|
||||
// Validate is the validate function.
|
||||
Validate(SysSpec) (error, error)
|
||||
}
|
||||
|
||||
// Reporter is the interface for the reporters for the validators.
|
||||
type Reporter interface {
|
||||
// Report reports the results of the system verification
|
||||
Report(string, string, ValidationResultType) error
|
||||
}
|
||||
|
||||
// Validate uses validators to validate the system and returns a warning or error.
|
||||
func Validate(spec SysSpec, validators []Validator) (error, error) {
|
||||
var errs []error
|
||||
var warns []error
|
||||
|
||||
for _, v := range validators {
|
||||
glog.Infof("Validating %s...", v.Name())
|
||||
warn, err := v.Validate(spec)
|
||||
errs = append(errs, err)
|
||||
warns = append(warns, warn)
|
||||
}
|
||||
return errors.NewAggregate(warns), errors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
// ValidateSpec uses all default validators to validate the system and writes to stdout.
|
||||
func ValidateSpec(spec SysSpec, runtime string) (error, error) {
|
||||
// OS-level validators.
|
||||
var osValidators = []Validator{
|
||||
&OSValidator{Reporter: DefaultReporter},
|
||||
&KernelValidator{Reporter: DefaultReporter},
|
||||
&CgroupsValidator{Reporter: DefaultReporter},
|
||||
&packageValidator{reporter: DefaultReporter},
|
||||
}
|
||||
// Docker-specific validators.
|
||||
var dockerValidators = []Validator{
|
||||
&DockerValidator{Reporter: DefaultReporter},
|
||||
}
|
||||
|
||||
validators := osValidators
|
||||
switch runtime {
|
||||
case "docker":
|
||||
validators = append(validators, dockerValidators...)
|
||||
}
|
||||
return Validate(spec, validators)
|
||||
}
|
Reference in New Issue
Block a user