Update vendored dependencies

This commit is contained in:
Nick Sardo 2017-07-31 13:35:10 -07:00
parent 65e8cecbac
commit 9b22796383
666 changed files with 38921 additions and 47120 deletions

View file

@ -1,93 +0,0 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"template.go",
"util.go",
],
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = [
"template_test.go",
"util_test.go",
],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//pkg/util/async:all-srcs",
"//pkg/util/bandwidth:all-srcs",
"//pkg/util/config:all-srcs",
"//pkg/util/configz:all-srcs",
"//pkg/util/dbus:all-srcs",
"//pkg/util/ebtables:all-srcs",
"//pkg/util/env:all-srcs",
"//pkg/util/exec:all-srcs",
"//pkg/util/flock:all-srcs",
"//pkg/util/goroutinemap:all-srcs",
"//pkg/util/hash:all-srcs",
"//pkg/util/i18n:all-srcs",
"//pkg/util/initsystem:all-srcs",
"//pkg/util/interrupt:all-srcs",
"//pkg/util/io:all-srcs",
"//pkg/util/ipconfig:all-srcs",
"//pkg/util/iptables:all-srcs",
"//pkg/util/keymutex:all-srcs",
"//pkg/util/labels:all-srcs",
"//pkg/util/limitwriter:all-srcs",
"//pkg/util/logs:all-srcs",
"//pkg/util/maps:all-srcs",
"//pkg/util/metrics:all-srcs",
"//pkg/util/mount:all-srcs",
"//pkg/util/net:all-srcs",
"//pkg/util/netsh:all-srcs",
"//pkg/util/node:all-srcs",
"//pkg/util/oom:all-srcs",
"//pkg/util/parsers:all-srcs",
"//pkg/util/procfs:all-srcs",
"//pkg/util/removeall:all-srcs",
"//pkg/util/resourcecontainer:all-srcs",
"//pkg/util/rlimit:all-srcs",
"//pkg/util/selinux:all-srcs",
"//pkg/util/slice:all-srcs",
"//pkg/util/strings:all-srcs",
"//pkg/util/sysctl:all-srcs",
"//pkg/util/system:all-srcs",
"//pkg/util/tail:all-srcs",
"//pkg/util/taints:all-srcs",
"//pkg/util/term:all-srcs",
"//pkg/util/threading:all-srcs",
"//pkg/util/tolerations:all-srcs",
"//pkg/util/version:all-srcs",
"//pkg/util/workqueue/prometheus:all-srcs",
],
tags = ["automanaged"],
)

View file

@ -1,20 +0,0 @@
/*
Copyright 2014 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 util implements various utility functions used in both testing and implementation
// of Kubernetes. Package util may not depend on any other package in the Kubernetes
// package tree.
package util

View file

@ -1,18 +0,0 @@
/*
Copyright 2014 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 exec provides an injectable interface and implementations for running commands.
package exec

View file

@ -1,200 +0,0 @@
/*
Copyright 2014 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 exec
import (
"io"
osexec "os/exec"
"syscall"
"time"
)
// ErrExecutableNotFound is returned if the executable is not found.
var ErrExecutableNotFound = osexec.ErrNotFound
// Interface is an interface that presents a subset of the os/exec API. Use this
// when you want to inject fakeable/mockable exec behavior.
type Interface interface {
// Command returns a Cmd instance which can be used to run a single command.
// This follows the pattern of package os/exec.
Command(cmd string, args ...string) Cmd
// LookPath wraps os/exec.LookPath
LookPath(file string) (string, error)
}
// Cmd is an interface that presents an API that is very similar to Cmd from os/exec.
// As more functionality is needed, this can grow. Since Cmd is a struct, we will have
// to replace fields with get/set method pairs.
type Cmd interface {
// Run runs the command to the completion.
Run() error
// CombinedOutput runs the command and returns its combined standard output
// and standard error. This follows the pattern of package os/exec.
CombinedOutput() ([]byte, error)
// Output runs the command and returns standard output, but not standard err
Output() ([]byte, error)
SetDir(dir string)
SetStdin(in io.Reader)
SetStdout(out io.Writer)
SetStderr(out io.Writer)
// Stops the command by sending SIGTERM. It is not guaranteed the
// process will stop before this function returns. If the process is not
// responding, an internal timer function will send a SIGKILL to force
// terminate after 10 seconds.
Stop()
}
// ExitError is an interface that presents an API similar to os.ProcessState, which is
// what ExitError from os/exec is. This is designed to make testing a bit easier and
// probably loses some of the cross-platform properties of the underlying library.
type ExitError interface {
String() string
Error() string
Exited() bool
ExitStatus() int
}
// Implements Interface in terms of really exec()ing.
type executor struct{}
// New returns a new Interface which will os/exec to run commands.
func New() Interface {
return &executor{}
}
// Command is part of the Interface interface.
func (executor *executor) Command(cmd string, args ...string) Cmd {
return (*cmdWrapper)(osexec.Command(cmd, args...))
}
// LookPath is part of the Interface interface
func (executor *executor) LookPath(file string) (string, error) {
return osexec.LookPath(file)
}
// Wraps exec.Cmd so we can capture errors.
type cmdWrapper osexec.Cmd
func (cmd *cmdWrapper) SetDir(dir string) {
cmd.Dir = dir
}
func (cmd *cmdWrapper) SetStdin(in io.Reader) {
cmd.Stdin = in
}
func (cmd *cmdWrapper) SetStdout(out io.Writer) {
cmd.Stdout = out
}
func (cmd *cmdWrapper) SetStderr(out io.Writer) {
cmd.Stderr = out
}
// Run is part of the Cmd interface.
func (cmd *cmdWrapper) Run() error {
return (*osexec.Cmd)(cmd).Run()
}
// CombinedOutput is part of the Cmd interface.
func (cmd *cmdWrapper) CombinedOutput() ([]byte, error) {
out, err := (*osexec.Cmd)(cmd).CombinedOutput()
if err != nil {
return out, handleError(err)
}
return out, nil
}
func (cmd *cmdWrapper) Output() ([]byte, error) {
out, err := (*osexec.Cmd)(cmd).Output()
if err != nil {
return out, handleError(err)
}
return out, nil
}
// Stop is part of the Cmd interface.
func (cmd *cmdWrapper) Stop() {
c := (*osexec.Cmd)(cmd)
if c.ProcessState.Exited() {
return
}
c.Process.Signal(syscall.SIGTERM)
time.AfterFunc(10*time.Second, func() {
if c.ProcessState.Exited() {
return
}
c.Process.Signal(syscall.SIGKILL)
})
}
func handleError(err error) error {
if ee, ok := err.(*osexec.ExitError); ok {
// Force a compile fail if exitErrorWrapper can't convert to ExitError.
var x ExitError = &ExitErrorWrapper{ee}
return x
}
if ee, ok := err.(*osexec.Error); ok {
if ee.Err == osexec.ErrNotFound {
return ErrExecutableNotFound
}
}
return err
}
// ExitErrorWrapper is an implementation of ExitError in terms of os/exec ExitError.
// Note: standard exec.ExitError is type *os.ProcessState, which already implements Exited().
type ExitErrorWrapper struct {
*osexec.ExitError
}
var _ ExitError = ExitErrorWrapper{}
// ExitStatus is part of the ExitError interface.
func (eew ExitErrorWrapper) ExitStatus() int {
ws, ok := eew.Sys().(syscall.WaitStatus)
if !ok {
panic("can't call ExitStatus() on a non-WaitStatus exitErrorWrapper")
}
return ws.ExitStatus()
}
// CodeExitError is an implementation of ExitError consisting of an error object
// and an exit code (the upper bits of os.exec.ExitStatus).
type CodeExitError struct {
Err error
Code int
}
var _ ExitError = CodeExitError{}
func (e CodeExitError) Error() string {
return e.Err.Error()
}
func (e CodeExitError) String() string {
return e.Err.Error()
}
func (e CodeExitError) Exited() bool {
return true
}
func (e CodeExitError) ExitStatus() int {
return e.Code
}

View file

@ -1,145 +0,0 @@
/*
Copyright 2014 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 exec
import (
"fmt"
"io"
)
// A simple scripted Interface type.
type FakeExec struct {
CommandScript []FakeCommandAction
CommandCalls int
LookPathFunc func(string) (string, error)
}
type FakeCommandAction func(cmd string, args ...string) Cmd
func (fake *FakeExec) Command(cmd string, args ...string) Cmd {
if fake.CommandCalls > len(fake.CommandScript)-1 {
panic(fmt.Sprintf("ran out of Command() actions. Could not handle command [%d]: %s args: %v", fake.CommandCalls, cmd, args))
}
i := fake.CommandCalls
fake.CommandCalls++
return fake.CommandScript[i](cmd, args...)
}
func (fake *FakeExec) LookPath(file string) (string, error) {
return fake.LookPathFunc(file)
}
// A simple scripted Cmd type.
type FakeCmd struct {
Argv []string
CombinedOutputScript []FakeCombinedOutputAction
CombinedOutputCalls int
CombinedOutputLog [][]string
RunScript []FakeRunAction
RunCalls int
RunLog [][]string
Dirs []string
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
}
func InitFakeCmd(fake *FakeCmd, cmd string, args ...string) Cmd {
fake.Argv = append([]string{cmd}, args...)
return fake
}
type FakeCombinedOutputAction func() ([]byte, error)
type FakeRunAction func() ([]byte, []byte, error)
func (fake *FakeCmd) SetDir(dir string) {
fake.Dirs = append(fake.Dirs, dir)
}
func (fake *FakeCmd) SetStdin(in io.Reader) {
fake.Stdin = in
}
func (fake *FakeCmd) SetStdout(out io.Writer) {
fake.Stdout = out
}
func (fake *FakeCmd) SetStderr(out io.Writer) {
fake.Stderr = out
}
func (fake *FakeCmd) Run() error {
if fake.RunCalls > len(fake.RunScript)-1 {
panic("ran out of Run() actions")
}
if fake.RunLog == nil {
fake.RunLog = [][]string{}
}
i := fake.RunCalls
fake.RunLog = append(fake.RunLog, append([]string{}, fake.Argv...))
fake.RunCalls++
stdout, stderr, err := fake.RunScript[i]()
if stdout != nil {
fake.Stdout.Write(stdout)
}
if stderr != nil {
fake.Stderr.Write(stderr)
}
return err
}
func (fake *FakeCmd) CombinedOutput() ([]byte, error) {
if fake.CombinedOutputCalls > len(fake.CombinedOutputScript)-1 {
panic("ran out of CombinedOutput() actions")
}
if fake.CombinedOutputLog == nil {
fake.CombinedOutputLog = [][]string{}
}
i := fake.CombinedOutputCalls
fake.CombinedOutputLog = append(fake.CombinedOutputLog, append([]string{}, fake.Argv...))
fake.CombinedOutputCalls++
return fake.CombinedOutputScript[i]()
}
func (fake *FakeCmd) Output() ([]byte, error) {
return nil, fmt.Errorf("unimplemented")
}
func (fake *FakeCmd) Stop() {
// no-op
}
// A simple fake ExitError type.
type FakeExitError struct {
Status int
}
func (fake *FakeExitError) String() string {
return fmt.Sprintf("exit %d", fake.Status)
}
func (fake *FakeExitError) Error() string {
return fake.String()
}
func (fake *FakeExitError) Exited() bool {
return true
}
func (fake *FakeExitError) ExitStatus() int {
return fake.Status
}

27
vendor/k8s.io/kubernetes/pkg/util/file/BUILD generated vendored Normal file
View file

@ -0,0 +1,27 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["file.go"],
tags = ["automanaged"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

57
vendor/k8s.io/kubernetes/pkg/util/file/file.go generated vendored Normal file
View file

@ -0,0 +1,57 @@
/*
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 file
import (
"os"
)
// FileExists checks if specified file exists.
func FileExists(filename string) (bool, error) {
if _, err := os.Stat(filename); os.IsNotExist(err) {
return false, nil
} else if err != nil {
return false, err
}
return true, nil
}
// FileOrSymlinkExists checks if specified file or symlink exists.
func FileOrSymlinkExists(filename string) (bool, error) {
if _, err := os.Lstat(filename); os.IsNotExist(err) {
return false, nil
} else if err != nil {
return false, err
}
return true, nil
}
// ReadDirNoStat returns a string of files/directories contained
// in dirname without calling lstat on them.
func ReadDirNoStat(dirname string) ([]string, error) {
if dirname == "" {
dirname = "."
}
f, err := os.Open(dirname)
if err != nil {
return nil, err
}
defer f.Close()
return f.Readdirnames(-1)
}

View file

@ -19,9 +19,9 @@ go_library(
],
tags = ["automanaged"],
deps = [
"//pkg/util/exec:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
],
)
@ -29,11 +29,15 @@ go_test(
name = "go_default_test",
srcs = [
"mount_linux_test.go",
"nsenter_mount_test.go",
"safe_format_and_mount_test.go",
],
library = ":go_default_library",
tags = ["automanaged"],
deps = ["//pkg/util/exec:go_default_library"],
deps = [
"//vendor/k8s.io/utils/exec:go_default_library",
"//vendor/k8s.io/utils/exec/testing:go_default_library",
],
)
filegroup(

View file

@ -25,7 +25,7 @@ import (
"strings"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/util/exec"
"k8s.io/utils/exec"
)
const (

View file

@ -31,7 +31,7 @@ import (
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/util/sets"
utilexec "k8s.io/kubernetes/pkg/util/exec"
utilexec "k8s.io/utils/exec"
)
const (

View file

@ -25,7 +25,7 @@ import (
"strings"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/util/exec"
"k8s.io/utils/exec"
)
// NsenterMounter is part of experimental support for running the kubelet
@ -201,8 +201,11 @@ func (n *NsenterMounter) IsLikelyNotMountPoint(file string) (bool, error) {
// It's safer to assume that it's not a mount point.
return true, nil
}
mountTarget := strings.Split(string(out), " ")[0]
mountTarget = strings.TrimSuffix(mountTarget, "\n")
mountTarget, err := parseFindMnt(string(out))
if err != nil {
return false, err
}
glog.V(5).Infof("IsLikelyNotMountPoint findmnt output for path %s: %v:", file, mountTarget)
if mountTarget == file {
@ -213,6 +216,18 @@ func (n *NsenterMounter) IsLikelyNotMountPoint(file string) (bool, error) {
return true, nil
}
// parse output of "findmnt -o target,fstype" and return just the target
func parseFindMnt(out string) (string, error) {
// cut trailing newline
out = strings.TrimSuffix(out, "\n")
// cut everything after the last space - it's the filesystem type
i := strings.LastIndex(out, " ")
if i == -1 {
return "", fmt.Errorf("error parsing findmnt output, expected at least one space: %q", out)
}
return out[:i], nil
}
// DeviceOpened checks if block device in use by calling Open with O_EXCL flag.
// Returns true if open returns errno EBUSY, and false if errno is nil.
// Returns an error if errno is any error other than EBUSY.

View file

@ -8,20 +8,16 @@ load(
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"exec.go",
"fake_exec.go",
],
go_test(
name = "go_default_test",
srcs = ["pointer_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["exec_test.go"],
library = ":go_default_library",
go_library(
name = "go_default_library",
srcs = ["pointer.go"],
tags = ["automanaged"],
)

62
vendor/k8s.io/kubernetes/pkg/util/pointer/pointer.go generated vendored Normal file
View file

@ -0,0 +1,62 @@
/*
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 pointer
import (
"fmt"
"reflect"
)
// AllPtrFieldsNil tests whether all pointer fields in a struct are nil. This is useful when,
// for example, an API struct is handled by plugins which need to distinguish
// "no plugin accepted this spec" from "this spec is empty".
//
// This function is only valid for structs and pointers to structs. Any other
// type will cause a panic. Passing a typed nil pointer will return true.
func AllPtrFieldsNil(obj interface{}) bool {
v := reflect.ValueOf(obj)
if !v.IsValid() {
panic(fmt.Sprintf("reflect.ValueOf() produced a non-valid Value for %#v", obj))
}
if v.Kind() == reflect.Ptr {
if v.IsNil() {
return true
}
v = v.Elem()
}
for i := 0; i < v.NumField(); i++ {
if v.Field(i).Kind() == reflect.Ptr && !v.Field(i).IsNil() {
return false
}
}
return true
}
// Int32Ptr returns a pointer to an int32
func Int32Ptr(i int32) *int32 {
o := i
return &o
}
// Int32PtrDerefOr dereference the int32 ptr and returns it i not nil,
// else returns def.
func Int32PtrDerefOr(ptr *int32, def int32) int32 {
if ptr != nil {
return *ptr
}
return def
}

47
vendor/k8s.io/kubernetes/pkg/util/taints/BUILD generated vendored Normal file
View file

@ -0,0 +1,47 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = ["taints.go"],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/helper:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["taints_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//vendor/github.com/spf13/pflag:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

301
vendor/k8s.io/kubernetes/pkg/util/taints/taints.go generated vendored Normal file
View file

@ -0,0 +1,301 @@
/*
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 taints implements utilites for working with taints
package taints
import (
"fmt"
"k8s.io/apimachinery/pkg/util/sets"
"strings"
"k8s.io/api/core/v1"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/helper"
)
const (
MODIFIED = "modified"
TAINTED = "tainted"
UNTAINTED = "untainted"
)
// parseTaint parses a taint from a string. Taint must be off the format '<key>=<value>:<effect>'.
func parseTaint(st string) (v1.Taint, error) {
var taint v1.Taint
parts := strings.Split(st, "=")
if len(parts) != 2 || len(parts[1]) == 0 || len(validation.IsQualifiedName(parts[0])) > 0 {
return taint, fmt.Errorf("invalid taint spec: %v", st)
}
parts2 := strings.Split(parts[1], ":")
effect := v1.TaintEffect(parts2[1])
errs := validation.IsValidLabelValue(parts2[0])
if len(parts2) != 2 || len(errs) != 0 {
return taint, fmt.Errorf("invalid taint spec: %v, %s", st, strings.Join(errs, "; "))
}
if effect != v1.TaintEffectNoSchedule && effect != v1.TaintEffectPreferNoSchedule && effect != v1.TaintEffectNoExecute {
return taint, fmt.Errorf("invalid taint spec: %v, unsupported taint effect", st)
}
taint.Key = parts[0]
taint.Value = parts2[0]
taint.Effect = effect
return taint, nil
}
// NewTaintsVar wraps []api.Taint in a struct that implements flag.Value to allow taints to be
// bound to command line flags.
func NewTaintsVar(ptr *[]api.Taint) taintsVar {
return taintsVar{
ptr: ptr,
}
}
type taintsVar struct {
ptr *[]api.Taint
}
func (t taintsVar) Set(s string) error {
sts := strings.Split(s, ",")
var taints []api.Taint
for _, st := range sts {
taint, err := parseTaint(st)
if err != nil {
return err
}
taints = append(taints, api.Taint{Key: taint.Key, Value: taint.Value, Effect: api.TaintEffect(taint.Effect)})
}
*t.ptr = taints
return nil
}
func (t taintsVar) String() string {
if len(*t.ptr) == 0 {
return "<nil>"
}
var taints []string
for _, taint := range *t.ptr {
taints = append(taints, fmt.Sprintf("%s=%s:%s", taint.Key, taint.Value, taint.Effect))
}
return strings.Join(taints, ",")
}
func (t taintsVar) Type() string {
return "[]api.Taint"
}
// ParseTaints takes a spec which is an array and creates slices for new taints to be added, taints to be deleted.
func ParseTaints(spec []string) ([]v1.Taint, []v1.Taint, error) {
var taints, taintsToRemove []v1.Taint
uniqueTaints := map[v1.TaintEffect]sets.String{}
for _, taintSpec := range spec {
if strings.Index(taintSpec, "=") != -1 && strings.Index(taintSpec, ":") != -1 {
newTaint, err := parseTaint(taintSpec)
if err != nil {
return nil, nil, err
}
// validate if taint is unique by <key, effect>
if len(uniqueTaints[newTaint.Effect]) > 0 && uniqueTaints[newTaint.Effect].Has(newTaint.Key) {
return nil, nil, fmt.Errorf("duplicated taints with the same key and effect: %v", newTaint)
}
// add taint to existingTaints for uniqueness check
if len(uniqueTaints[newTaint.Effect]) == 0 {
uniqueTaints[newTaint.Effect] = sets.String{}
}
uniqueTaints[newTaint.Effect].Insert(newTaint.Key)
taints = append(taints, newTaint)
} else if strings.HasSuffix(taintSpec, "-") {
taintKey := taintSpec[:len(taintSpec)-1]
var effect v1.TaintEffect
if strings.Index(taintKey, ":") != -1 {
parts := strings.Split(taintKey, ":")
taintKey = parts[0]
effect = v1.TaintEffect(parts[1])
}
taintsToRemove = append(taintsToRemove, v1.Taint{Key: taintKey, Effect: effect})
} else {
return nil, nil, fmt.Errorf("unknown taint spec: %v", taintSpec)
}
}
return taints, taintsToRemove, nil
}
// ReorganizeTaints returns the updated set of taints, taking into account old taints that were not updated,
// old taints that were updated, old taints that were deleted, and new taints.
func ReorganizeTaints(node *v1.Node, overwrite bool, taintsToAdd []v1.Taint, taintsToRemove []v1.Taint) (string, []v1.Taint, error) {
newTaints := append([]v1.Taint{}, taintsToAdd...)
oldTaints := node.Spec.Taints
// add taints that already existing but not updated to newTaints
added := addTaints(oldTaints, &newTaints)
allErrs, deleted := deleteTaints(taintsToRemove, &newTaints)
if (added && deleted) || overwrite {
return MODIFIED, newTaints, utilerrors.NewAggregate(allErrs)
} else if added {
return TAINTED, newTaints, utilerrors.NewAggregate(allErrs)
}
return UNTAINTED, newTaints, utilerrors.NewAggregate(allErrs)
}
// deleteTaints deletes the given taints from the node's taintlist.
func deleteTaints(taintsToRemove []v1.Taint, newTaints *[]v1.Taint) ([]error, bool) {
allErrs := []error{}
var removed bool
for _, taintToRemove := range taintsToRemove {
removed = false
if len(taintToRemove.Effect) > 0 {
*newTaints, removed = DeleteTaint(*newTaints, &taintToRemove)
} else {
*newTaints, removed = DeleteTaintsByKey(*newTaints, taintToRemove.Key)
}
if !removed {
allErrs = append(allErrs, fmt.Errorf("taint %q not found", taintToRemove.ToString()))
}
}
return allErrs, removed
}
// addTaints adds the newTaints list to existing ones and updates the newTaints List.
// TODO: This needs a rewrite to take only the new values instead of appended newTaints list to be consistent.
func addTaints(oldTaints []v1.Taint, newTaints *[]v1.Taint) bool {
for _, oldTaint := range oldTaints {
existsInNew := false
for _, taint := range *newTaints {
if taint.MatchTaint(&oldTaint) {
existsInNew = true
break
}
}
if !existsInNew {
*newTaints = append(*newTaints, oldTaint)
}
}
return len(oldTaints) != len(*newTaints)
}
// CheckIfTaintsAlreadyExists checks if the node already has taints that we want to add and returns a string with taint keys.
func CheckIfTaintsAlreadyExists(oldTaints []v1.Taint, taints []v1.Taint) string {
var existingTaintList = make([]string, 0)
for _, taint := range taints {
for _, oldTaint := range oldTaints {
if taint.Key == oldTaint.Key && taint.Effect == oldTaint.Effect {
existingTaintList = append(existingTaintList, taint.Key)
}
}
}
return strings.Join(existingTaintList, ",")
}
// DeleteTaintsByKey removes all the taints that have the same key to given taintKey
func DeleteTaintsByKey(taints []v1.Taint, taintKey string) ([]v1.Taint, bool) {
newTaints := []v1.Taint{}
deleted := false
for i := range taints {
if taintKey == taints[i].Key {
deleted = true
continue
}
newTaints = append(newTaints, taints[i])
}
return newTaints, deleted
}
// DeleteTaint removes all the the taints that have the same key and effect to given taintToDelete.
func DeleteTaint(taints []v1.Taint, taintToDelete *v1.Taint) ([]v1.Taint, bool) {
newTaints := []v1.Taint{}
deleted := false
for i := range taints {
if taintToDelete.MatchTaint(&taints[i]) {
deleted = true
continue
}
newTaints = append(newTaints, taints[i])
}
return newTaints, deleted
}
// RemoveTaint tries to remove a taint from annotations list. Returns a new copy of updated Node and true if something was updated
// false otherwise.
func RemoveTaint(node *v1.Node, taint *v1.Taint) (*v1.Node, bool, error) {
objCopy, err := api.Scheme.DeepCopy(node)
if err != nil {
return nil, false, err
}
newNode := objCopy.(*v1.Node)
nodeTaints := newNode.Spec.Taints
if len(nodeTaints) == 0 {
return newNode, false, nil
}
if !TaintExists(nodeTaints, taint) {
return newNode, false, nil
}
newTaints, _ := DeleteTaint(nodeTaints, taint)
newNode.Spec.Taints = newTaints
return newNode, true, nil
}
// AddOrUpdateTaint tries to add a taint to annotations list. Returns a new copy of updated Node and true if something was updated
// false otherwise.
func AddOrUpdateTaint(node *v1.Node, taint *v1.Taint) (*v1.Node, bool, error) {
objCopy, err := api.Scheme.DeepCopy(node)
if err != nil {
return nil, false, err
}
newNode := objCopy.(*v1.Node)
nodeTaints := newNode.Spec.Taints
var newTaints []v1.Taint
updated := false
for i := range nodeTaints {
if taint.MatchTaint(&nodeTaints[i]) {
if helper.Semantic.DeepEqual(taint, nodeTaints[i]) {
return newNode, false, nil
}
newTaints = append(newTaints, *taint)
updated = true
continue
}
newTaints = append(newTaints, nodeTaints[i])
}
if !updated {
newTaints = append(newTaints, *taint)
}
newNode.Spec.Taints = newTaints
return newNode, true, nil
}
// TaintExists checks if the given taint exists in list of taints. Returns true if exists false otherwise.
func TaintExists(taints []v1.Taint, taintToFind *v1.Taint) bool {
for _, taint := range taints {
if taint.MatchTaint(taintToFind) {
return true
}
}
return false
}

View file

@ -1,48 +0,0 @@
/*
Copyright 2015 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 util
import (
"bytes"
"go/doc"
"io"
"strings"
"text/template"
)
func wrap(indent string, s string) string {
var buf bytes.Buffer
doc.ToText(&buf, s, indent, indent+" ", 80-len(indent))
return buf.String()
}
// ExecuteTemplate executes templateText with data and output written to w.
func ExecuteTemplate(w io.Writer, templateText string, data interface{}) error {
t := template.New("top")
t.Funcs(template.FuncMap{
"trim": strings.TrimSpace,
"wrap": wrap,
})
template.Must(t.Parse(templateText))
return t.Execute(w, data)
}
func ExecuteTemplateToString(templateText string, data interface{}) (string, error) {
b := bytes.Buffer{}
err := ExecuteTemplate(&b, templateText, data)
return b.String(), err
}

View file

@ -1,140 +0,0 @@
/*
Copyright 2014 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 util
import (
"fmt"
"os"
"reflect"
"regexp"
)
// Takes a list of strings and compiles them into a list of regular expressions
func CompileRegexps(regexpStrings []string) ([]*regexp.Regexp, error) {
regexps := []*regexp.Regexp{}
for _, regexpStr := range regexpStrings {
r, err := regexp.Compile(regexpStr)
if err != nil {
return []*regexp.Regexp{}, err
}
regexps = append(regexps, r)
}
return regexps, nil
}
// Detects if using systemd as the init system
// Please note that simply reading /proc/1/cmdline can be misleading because
// some installation of various init programs can automatically make /sbin/init
// a symlink or even a renamed version of their main program.
// TODO(dchen1107): realiably detects the init system using on the system:
// systemd, upstart, initd, etc.
func UsingSystemdInitSystem() bool {
if _, err := os.Stat("/run/systemd/system"); err == nil {
return true
}
return false
}
// Tests whether all pointer fields in a struct are nil. This is useful when,
// for example, an API struct is handled by plugins which need to distinguish
// "no plugin accepted this spec" from "this spec is empty".
//
// This function is only valid for structs and pointers to structs. Any other
// type will cause a panic. Passing a typed nil pointer will return true.
func AllPtrFieldsNil(obj interface{}) bool {
v := reflect.ValueOf(obj)
if !v.IsValid() {
panic(fmt.Sprintf("reflect.ValueOf() produced a non-valid Value for %#v", obj))
}
if v.Kind() == reflect.Ptr {
if v.IsNil() {
return true
}
v = v.Elem()
}
for i := 0; i < v.NumField(); i++ {
if v.Field(i).Kind() == reflect.Ptr && !v.Field(i).IsNil() {
return false
}
}
return true
}
func FileExists(filename string) (bool, error) {
if _, err := os.Stat(filename); os.IsNotExist(err) {
return false, nil
} else if err != nil {
return false, err
}
return true, nil
}
func FileOrSymlinkExists(filename string) (bool, error) {
if _, err := os.Lstat(filename); os.IsNotExist(err) {
return false, nil
} else if err != nil {
return false, err
}
return true, nil
}
// ReadDirNoStat returns a string of files/directories contained
// in dirname without calling lstat on them.
func ReadDirNoStat(dirname string) ([]string, error) {
if dirname == "" {
dirname = "."
}
f, err := os.Open(dirname)
if err != nil {
return nil, err
}
defer f.Close()
return f.Readdirnames(-1)
}
// IntPtr returns a pointer to an int
func IntPtr(i int) *int {
o := i
return &o
}
// Int32Ptr returns a pointer to an int32
func Int32Ptr(i int32) *int32 {
o := i
return &o
}
// IntPtrDerefOr dereference the int ptr and returns it i not nil,
// else returns def.
func IntPtrDerefOr(ptr *int, def int) int {
if ptr != nil {
return *ptr
}
return def
}
// Int32PtrDerefOr dereference the int32 ptr and returns it i not nil,
// else returns def.
func Int32PtrDerefOr(ptr *int32, def int32) int32 {
if ptr != nil {
return *ptr
}
return def
}