Update go dependencies
This commit is contained in:
parent
14a9e9f3fa
commit
14f4a7b8e8
1349 changed files with 128369 additions and 32627 deletions
3
vendor/k8s.io/utils/OWNERS
generated
vendored
3
vendor/k8s.io/utils/OWNERS
generated
vendored
|
|
@ -1,4 +1,5 @@
|
|||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
approvers:
|
||||
- apelisse
|
||||
- dashpole
|
||||
|
|
@ -6,6 +7,7 @@ approvers:
|
|||
- lavalamp
|
||||
- mengqiy
|
||||
- thockin
|
||||
- dims
|
||||
reviewers:
|
||||
- apelisse
|
||||
- dashpole
|
||||
|
|
@ -16,3 +18,4 @@ reviewers:
|
|||
- andrewsykim
|
||||
- cheftako
|
||||
- mcrute
|
||||
- dims
|
||||
|
|
|
|||
13
vendor/k8s.io/utils/SECURITY_CONTACTS
generated
vendored
Normal file
13
vendor/k8s.io/utils/SECURITY_CONTACTS
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Defined below are the security contacts for this repo.
|
||||
#
|
||||
# They are the contact point for the Product Security Committee to reach out
|
||||
# to for triaging and handling of incoming issues.
|
||||
#
|
||||
# The below names agree to abide by the
|
||||
# [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy)
|
||||
# and will be removed and replaced if they violate that agreement.
|
||||
#
|
||||
# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
|
||||
# INSTRUCTIONS AT https://kubernetes.io/security/
|
||||
|
||||
liggitt
|
||||
72
vendor/k8s.io/utils/buffer/ring_growing.go
generated
vendored
Normal file
72
vendor/k8s.io/utils/buffer/ring_growing.go
generated
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
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 buffer
|
||||
|
||||
// RingGrowing is a growing ring buffer.
|
||||
// Not thread safe.
|
||||
type RingGrowing struct {
|
||||
data []interface{}
|
||||
n int // Size of Data
|
||||
beg int // First available element
|
||||
readable int // Number of data items available
|
||||
}
|
||||
|
||||
// NewRingGrowing constructs a new RingGrowing instance with provided parameters.
|
||||
func NewRingGrowing(initialSize int) *RingGrowing {
|
||||
return &RingGrowing{
|
||||
data: make([]interface{}, initialSize),
|
||||
n: initialSize,
|
||||
}
|
||||
}
|
||||
|
||||
// ReadOne reads (consumes) first item from the buffer if it is available, otherwise returns false.
|
||||
func (r *RingGrowing) ReadOne() (data interface{}, ok bool) {
|
||||
if r.readable == 0 {
|
||||
return nil, false
|
||||
}
|
||||
r.readable--
|
||||
element := r.data[r.beg]
|
||||
r.data[r.beg] = nil // Remove reference to the object to help GC
|
||||
if r.beg == r.n-1 {
|
||||
// Was the last element
|
||||
r.beg = 0
|
||||
} else {
|
||||
r.beg++
|
||||
}
|
||||
return element, true
|
||||
}
|
||||
|
||||
// WriteOne adds an item to the end of the buffer, growing it if it is full.
|
||||
func (r *RingGrowing) WriteOne(data interface{}) {
|
||||
if r.readable == r.n {
|
||||
// Time to grow
|
||||
newN := r.n * 2
|
||||
newData := make([]interface{}, newN)
|
||||
to := r.beg + r.readable
|
||||
if to <= r.n {
|
||||
copy(newData, r.data[r.beg:to])
|
||||
} else {
|
||||
copied := copy(newData, r.data[r.beg:])
|
||||
copy(newData[copied:], r.data[:(to%r.n)])
|
||||
}
|
||||
r.beg = 0
|
||||
r.data = newData
|
||||
r.n = newN
|
||||
}
|
||||
r.data[(r.readable+r.beg)%r.n] = data
|
||||
r.readable++
|
||||
}
|
||||
73
vendor/k8s.io/utils/integer/integer.go
generated
vendored
Normal file
73
vendor/k8s.io/utils/integer/integer.go
generated
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
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 integer
|
||||
|
||||
// IntMax returns the maximum of the params
|
||||
func IntMax(a, b int) int {
|
||||
if b > a {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// IntMin returns the minimum of the params
|
||||
func IntMin(a, b int) int {
|
||||
if b < a {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// Int32Max returns the maximum of the params
|
||||
func Int32Max(a, b int32) int32 {
|
||||
if b > a {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// Int32Min returns the minimum of the params
|
||||
func Int32Min(a, b int32) int32 {
|
||||
if b < a {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// Int64Max returns the maximum of the params
|
||||
func Int64Max(a, b int64) int64 {
|
||||
if b > a {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// Int64Min returns the minimum of the params
|
||||
func Int64Min(a, b int64) int64 {
|
||||
if b < a {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// RoundToInt32 rounds floats into integer numbers.
|
||||
func RoundToInt32(a float64) int32 {
|
||||
if a < 0 {
|
||||
return int32(a - 0.5)
|
||||
}
|
||||
return int32(a + 0.5)
|
||||
}
|
||||
55
vendor/k8s.io/utils/io/consistentread.go
generated
vendored
Normal file
55
vendor/k8s.io/utils/io/consistentread.go
generated
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
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 io
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// ConsistentRead repeatedly reads a file until it gets the same content twice.
|
||||
// This is useful when reading files in /proc that are larger than page size
|
||||
// and kernel may modify them between individual read() syscalls.
|
||||
func ConsistentRead(filename string, attempts int) ([]byte, error) {
|
||||
return consistentReadSync(filename, attempts, nil)
|
||||
}
|
||||
|
||||
// consistentReadSync is the main functionality of ConsistentRead but
|
||||
// introduces a sync callback that can be used by the tests to mutate the file
|
||||
// from which the test data is being read
|
||||
func consistentReadSync(filename string, attempts int, sync func(int)) ([]byte, error) {
|
||||
oldContent, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < attempts; i++ {
|
||||
if sync != nil {
|
||||
sync(i)
|
||||
}
|
||||
newContent, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if bytes.Compare(oldContent, newContent) == 0 {
|
||||
return newContent, nil
|
||||
}
|
||||
// Files are different, continue reading
|
||||
oldContent = newContent
|
||||
}
|
||||
return nil, fmt.Errorf("could not get consistent content of %s after %d attempts", filename, attempts)
|
||||
}
|
||||
58
vendor/k8s.io/utils/keymutex/hashed.go
generated
vendored
Normal file
58
vendor/k8s.io/utils/keymutex/hashed.go
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Copyright 2018 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 keymutex
|
||||
|
||||
import (
|
||||
"hash/fnv"
|
||||
"runtime"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// NewHashed returns a new instance of KeyMutex which hashes arbitrary keys to
|
||||
// a fixed set of locks. `n` specifies number of locks, if n <= 0, we use
|
||||
// number of cpus.
|
||||
// Note that because it uses fixed set of locks, different keys may share same
|
||||
// lock, so it's possible to wait on same lock.
|
||||
func NewHashed(n int) KeyMutex {
|
||||
if n <= 0 {
|
||||
n = runtime.NumCPU()
|
||||
}
|
||||
return &hashedKeyMutex{
|
||||
mutexes: make([]sync.Mutex, n),
|
||||
}
|
||||
}
|
||||
|
||||
type hashedKeyMutex struct {
|
||||
mutexes []sync.Mutex
|
||||
}
|
||||
|
||||
// Acquires a lock associated with the specified ID.
|
||||
func (km *hashedKeyMutex) LockKey(id string) {
|
||||
km.mutexes[km.hash(id)%uint32(len(km.mutexes))].Lock()
|
||||
}
|
||||
|
||||
// Releases the lock associated with the specified ID.
|
||||
func (km *hashedKeyMutex) UnlockKey(id string) error {
|
||||
km.mutexes[km.hash(id)%uint32(len(km.mutexes))].Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (km *hashedKeyMutex) hash(id string) uint32 {
|
||||
h := fnv.New32a()
|
||||
h.Write([]byte(id))
|
||||
return h.Sum32()
|
||||
}
|
||||
27
vendor/k8s.io/utils/keymutex/keymutex.go
generated
vendored
Normal file
27
vendor/k8s.io/utils/keymutex/keymutex.go
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
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 keymutex
|
||||
|
||||
// KeyMutex is a thread-safe interface for acquiring locks on arbitrary strings.
|
||||
type KeyMutex interface {
|
||||
// Acquires a lock associated with the specified ID, creates the lock if one doesn't already exist.
|
||||
LockKey(id string)
|
||||
|
||||
// Releases the lock associated with the specified ID.
|
||||
// Returns an error if the specified ID doesn't exist.
|
||||
UnlockKey(id string) error
|
||||
}
|
||||
10
vendor/k8s.io/utils/nsenter/OWNERS
generated
vendored
Normal file
10
vendor/k8s.io/utils/nsenter/OWNERS
generated
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
reviewers:
|
||||
- jsafrane
|
||||
- msau42
|
||||
- cofyc
|
||||
approvers:
|
||||
- jsafrane
|
||||
- msau42
|
||||
- cofyc
|
||||
258
vendor/k8s.io/utils/nsenter/nsenter.go
generated
vendored
Normal file
258
vendor/k8s.io/utils/nsenter/nsenter.go
generated
vendored
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
// +build linux
|
||||
|
||||
/*
|
||||
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 nsenter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"k8s.io/klog"
|
||||
"k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultHostRootFsPath is path to host's filesystem mounted into container
|
||||
// with kubelet.
|
||||
DefaultHostRootFsPath = "/rootfs"
|
||||
// mountNsPath is the default mount namespace of the host
|
||||
mountNsPath = "/proc/1/ns/mnt"
|
||||
// nsenterPath is the default nsenter command
|
||||
nsenterPath = "nsenter"
|
||||
)
|
||||
|
||||
// Nsenter is a type alias for backward compatibility
|
||||
type Nsenter = NSEnter
|
||||
|
||||
// NSEnter is part of experimental support for running the kubelet
|
||||
// in a container.
|
||||
//
|
||||
// NSEnter requires:
|
||||
//
|
||||
// 1. Docker >= 1.6 due to the dependency on the slave propagation mode
|
||||
// of the bind-mount of the kubelet root directory in the container.
|
||||
// Docker 1.5 used a private propagation mode for bind-mounts, so mounts
|
||||
// performed in the host's mount namespace do not propagate out to the
|
||||
// bind-mount in this docker version.
|
||||
// 2. The host's root filesystem must be available at /rootfs
|
||||
// 3. The nsenter binary must be on the Kubelet process' PATH in the container's
|
||||
// filesystem.
|
||||
// 4. The Kubelet process must have CAP_SYS_ADMIN (required by nsenter); at
|
||||
// the present, this effectively means that the kubelet is running in a
|
||||
// privileged container.
|
||||
// 5. The volume path used by the Kubelet must be the same inside and outside
|
||||
// the container and be writable by the container (to initialize volume)
|
||||
// contents. TODO: remove this requirement.
|
||||
// 6. The host image must have "mount", "findmnt", "umount", "stat", "touch",
|
||||
// "mkdir", "ls", "sh" and "chmod" binaries in /bin, /usr/sbin, or /usr/bin
|
||||
// 7. The host image should have systemd-run in /bin, /usr/sbin, or /usr/bin if
|
||||
// systemd is installed/enabled in the operating system.
|
||||
// For more information about mount propagation modes, see:
|
||||
// https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
|
||||
type NSEnter struct {
|
||||
// a map of commands to their paths on the host filesystem
|
||||
paths map[string]string
|
||||
|
||||
// Path to the host filesystem, typically "/rootfs". Used only for testing.
|
||||
hostRootFsPath string
|
||||
|
||||
// Exec implementation
|
||||
executor exec.Interface
|
||||
}
|
||||
|
||||
// NewNsenter constructs a new instance of NSEnter
|
||||
func NewNsenter(hostRootFsPath string, executor exec.Interface) (*NSEnter, error) {
|
||||
ne := &NSEnter{
|
||||
hostRootFsPath: hostRootFsPath,
|
||||
executor: executor,
|
||||
}
|
||||
if err := ne.initPaths(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ne, nil
|
||||
}
|
||||
|
||||
func (ne *NSEnter) initPaths() error {
|
||||
ne.paths = map[string]string{}
|
||||
binaries := []string{
|
||||
"mount",
|
||||
"findmnt",
|
||||
"umount",
|
||||
"systemd-run",
|
||||
"stat",
|
||||
"touch",
|
||||
"mkdir",
|
||||
"sh",
|
||||
"chmod",
|
||||
"realpath",
|
||||
}
|
||||
// search for the required commands in other locations besides /usr/bin
|
||||
for _, binary := range binaries {
|
||||
// check for binary under the following directories
|
||||
for _, path := range []string{"/", "/bin", "/usr/sbin", "/usr/bin"} {
|
||||
binPath := filepath.Join(path, binary)
|
||||
if _, err := os.Stat(filepath.Join(ne.hostRootFsPath, binPath)); err != nil {
|
||||
continue
|
||||
}
|
||||
ne.paths[binary] = binPath
|
||||
break
|
||||
}
|
||||
// systemd-run is optional, bailout if we don't find any of the other binaries
|
||||
if ne.paths[binary] == "" && binary != "systemd-run" {
|
||||
return fmt.Errorf("unable to find %v", binary)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Exec executes nsenter commands in hostProcMountNsPath mount namespace
|
||||
func (ne *NSEnter) Exec(cmd string, args []string) exec.Cmd {
|
||||
hostProcMountNsPath := filepath.Join(ne.hostRootFsPath, mountNsPath)
|
||||
fullArgs := append([]string{fmt.Sprintf("--mount=%s", hostProcMountNsPath), "--"},
|
||||
append([]string{ne.AbsHostPath(cmd)}, args...)...)
|
||||
klog.V(5).Infof("Running nsenter command: %v %v", nsenterPath, fullArgs)
|
||||
return ne.executor.Command(nsenterPath, fullArgs...)
|
||||
}
|
||||
|
||||
// Command returns a command wrapped with nsenter
|
||||
func (ne *NSEnter) Command(cmd string, args ...string) exec.Cmd {
|
||||
return ne.Exec(cmd, args)
|
||||
}
|
||||
|
||||
// CommandContext returns a CommandContext wrapped with nsenter
|
||||
func (ne *NSEnter) CommandContext(ctx context.Context, cmd string, args ...string) exec.Cmd {
|
||||
hostProcMountNsPath := filepath.Join(ne.hostRootFsPath, mountNsPath)
|
||||
fullArgs := append([]string{fmt.Sprintf("--mount=%s", hostProcMountNsPath), "--"},
|
||||
append([]string{ne.AbsHostPath(cmd)}, args...)...)
|
||||
klog.V(5).Infof("Running nsenter command: %v %v", nsenterPath, fullArgs)
|
||||
return ne.executor.CommandContext(ctx, nsenterPath, fullArgs...)
|
||||
}
|
||||
|
||||
// LookPath returns a LookPath wrapped with nsenter
|
||||
func (ne *NSEnter) LookPath(file string) (string, error) {
|
||||
return "", fmt.Errorf("not implemented, error looking up : %s", file)
|
||||
}
|
||||
|
||||
// AbsHostPath returns the absolute runnable path for a specified command
|
||||
func (ne *NSEnter) AbsHostPath(command string) string {
|
||||
path, ok := ne.paths[command]
|
||||
if !ok {
|
||||
return command
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
// SupportsSystemd checks whether command systemd-run exists
|
||||
func (ne *NSEnter) SupportsSystemd() (string, bool) {
|
||||
systemdRunPath, ok := ne.paths["systemd-run"]
|
||||
return systemdRunPath, ok && systemdRunPath != ""
|
||||
}
|
||||
|
||||
// EvalSymlinks returns the path name on the host after evaluating symlinks on the
|
||||
// host.
|
||||
// mustExist makes EvalSymlinks to return error when the path does not
|
||||
// exist. When it's false, it evaluates symlinks of the existing part and
|
||||
// blindly adds the non-existing part:
|
||||
// pathname: /mnt/volume/non/existing/directory
|
||||
// /mnt/volume exists
|
||||
// non/existing/directory does not exist
|
||||
// -> It resolves symlinks in /mnt/volume to say /mnt/foo and returns
|
||||
// /mnt/foo/non/existing/directory.
|
||||
//
|
||||
// BEWARE! EvalSymlinks is not able to detect symlink looks with mustExist=false!
|
||||
// If /tmp/link is symlink to /tmp/link, EvalSymlinks(/tmp/link/foo) returns /tmp/link/foo.
|
||||
func (ne *NSEnter) EvalSymlinks(pathname string, mustExist bool) (string, error) {
|
||||
var args []string
|
||||
if mustExist {
|
||||
// "realpath -e: all components of the path must exist"
|
||||
args = []string{"-e", pathname}
|
||||
} else {
|
||||
// "realpath -m: no path components need exist or be a directory"
|
||||
args = []string{"-m", pathname}
|
||||
}
|
||||
outBytes, err := ne.Exec("realpath", args).CombinedOutput()
|
||||
if err != nil {
|
||||
klog.Infof("failed to resolve symbolic links on %s: %v", pathname, err)
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSpace(string(outBytes)), nil
|
||||
}
|
||||
|
||||
// KubeletPath returns the path name that can be accessed by containerized
|
||||
// kubelet. It is recommended to resolve symlinks on the host by EvalSymlinks
|
||||
// before calling this function
|
||||
func (ne *NSEnter) KubeletPath(pathname string) string {
|
||||
return filepath.Join(ne.hostRootFsPath, pathname)
|
||||
}
|
||||
|
||||
// NewFakeNsenter returns a NSEnter that does not run "nsenter --mount=... --",
|
||||
// but runs everything in the same mount namespace as the unit test binary.
|
||||
// rootfsPath is supposed to be a symlink, e.g. /tmp/xyz/rootfs -> /.
|
||||
// This fake NSEnter is enough for most operations, e.g. to resolve symlinks,
|
||||
// but it's not enough to call /bin/mount - unit tests don't run as root.
|
||||
func NewFakeNsenter(rootfsPath string) (*NSEnter, error) {
|
||||
executor := &fakeExec{
|
||||
rootfsPath: rootfsPath,
|
||||
}
|
||||
// prepare /rootfs/bin, usr/bin and usr/sbin
|
||||
bin := filepath.Join(rootfsPath, "bin")
|
||||
if err := os.Symlink("/bin", bin); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
usr := filepath.Join(rootfsPath, "usr")
|
||||
if err := os.Mkdir(usr, 0755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
usrbin := filepath.Join(usr, "bin")
|
||||
if err := os.Symlink("/usr/bin", usrbin); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
usrsbin := filepath.Join(usr, "sbin")
|
||||
if err := os.Symlink("/usr/sbin", usrsbin); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewNsenter(rootfsPath, executor)
|
||||
}
|
||||
|
||||
type fakeExec struct {
|
||||
rootfsPath string
|
||||
}
|
||||
|
||||
func (f fakeExec) Command(cmd string, args ...string) exec.Cmd {
|
||||
// This will intentionaly panic if NSEnter does not provide enough arguments.
|
||||
realCmd := args[2]
|
||||
realArgs := args[3:]
|
||||
return exec.New().Command(realCmd, realArgs...)
|
||||
}
|
||||
|
||||
func (fakeExec) LookPath(file string) (string, error) {
|
||||
return "", errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (fakeExec) CommandContext(ctx context.Context, cmd string, args ...string) exec.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ exec.Interface = fakeExec{}
|
||||
var _ exec.Interface = &NSEnter{}
|
||||
79
vendor/k8s.io/utils/nsenter/nsenter_unsupported.go
generated
vendored
Normal file
79
vendor/k8s.io/utils/nsenter/nsenter_unsupported.go
generated
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// +build !linux
|
||||
|
||||
/*
|
||||
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 nsenter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultHostRootFsPath is path to host's filesystem mounted into container
|
||||
// with kubelet.
|
||||
DefaultHostRootFsPath = "/rootfs"
|
||||
)
|
||||
|
||||
// Nsenter is a type alias for backward compatibility
|
||||
type Nsenter = NSEnter
|
||||
|
||||
// NSEnter is part of experimental support for running the kubelet
|
||||
// in a container.
|
||||
type NSEnter struct {
|
||||
// a map of commands to their paths on the host filesystem
|
||||
Paths map[string]string
|
||||
}
|
||||
|
||||
// NewNsenter constructs a new instance of NSEnter
|
||||
func NewNsenter(hostRootFsPath string, executor exec.Interface) (*Nsenter, error) {
|
||||
return &Nsenter{}, nil
|
||||
}
|
||||
|
||||
// Exec executes nsenter commands in hostProcMountNsPath mount namespace
|
||||
func (ne *NSEnter) Exec(cmd string, args []string) exec.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AbsHostPath returns the absolute runnable path for a specified command
|
||||
func (ne *NSEnter) AbsHostPath(command string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// SupportsSystemd checks whether command systemd-run exists
|
||||
func (ne *NSEnter) SupportsSystemd() (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Command returns a command wrapped with nenter
|
||||
func (ne *NSEnter) Command(cmd string, args ...string) exec.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CommandContext returns a CommandContext wrapped with nsenter
|
||||
func (ne *NSEnter) CommandContext(ctx context.Context, cmd string, args ...string) exec.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
// LookPath returns a LookPath wrapped with nsenter
|
||||
func (ne *NSEnter) LookPath(file string) (string, error) {
|
||||
return "", fmt.Errorf("not implemented, error looking up : %s", file)
|
||||
}
|
||||
|
||||
var _ exec.Interface = &NSEnter{}
|
||||
78
vendor/k8s.io/utils/path/file.go
generated
vendored
Normal file
78
vendor/k8s.io/utils/path/file.go
generated
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
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 path
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
// LinkTreatment is the base type for constants used by Exists that indicate
|
||||
// how symlinks are treated for existence checks.
|
||||
type LinkTreatment int
|
||||
|
||||
const (
|
||||
// CheckFollowSymlink follows the symlink and verifies that the target of
|
||||
// the symlink exists.
|
||||
CheckFollowSymlink LinkTreatment = iota
|
||||
|
||||
// CheckSymlinkOnly does not follow the symlink and verfies only that they
|
||||
// symlink itself exists.
|
||||
CheckSymlinkOnly
|
||||
)
|
||||
|
||||
// ErrInvalidLinkTreatment indicates that the link treatment behavior requested
|
||||
// is not a valid behavior.
|
||||
var ErrInvalidLinkTreatment = errors.New("unknown link behavior")
|
||||
|
||||
// Exists checks if specified file, directory, or symlink exists. The behavior
|
||||
// of the test depends on the linkBehaviour argument. See LinkTreatment for
|
||||
// more details.
|
||||
func Exists(linkBehavior LinkTreatment, filename string) (bool, error) {
|
||||
var err error
|
||||
|
||||
if linkBehavior == CheckFollowSymlink {
|
||||
_, err = os.Stat(filename)
|
||||
} else if linkBehavior == CheckSymlinkOnly {
|
||||
_, err = os.Lstat(filename)
|
||||
} else {
|
||||
return false, ErrInvalidLinkTreatment
|
||||
}
|
||||
|
||||
if 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)
|
||||
}
|
||||
96
vendor/k8s.io/utils/trace/trace.go
generated
vendored
Normal file
96
vendor/k8s.io/utils/trace/trace.go
generated
vendored
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
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 trace
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
type traceStep struct {
|
||||
stepTime time.Time
|
||||
msg string
|
||||
}
|
||||
|
||||
// Trace keeps track of a set of "steps" and allows us to log a specific
|
||||
// step if it took longer than its share of the total allowed time
|
||||
type Trace struct {
|
||||
name string
|
||||
startTime time.Time
|
||||
steps []traceStep
|
||||
}
|
||||
|
||||
// New creates a Trace with the specified name
|
||||
func New(name string) *Trace {
|
||||
return &Trace{name, time.Now(), nil}
|
||||
}
|
||||
|
||||
// Step adds a new step with a specific message
|
||||
func (t *Trace) Step(msg string) {
|
||||
if t.steps == nil {
|
||||
// traces almost always have less than 6 steps, do this to avoid more than a single allocation
|
||||
t.steps = make([]traceStep, 0, 6)
|
||||
}
|
||||
t.steps = append(t.steps, traceStep{time.Now(), msg})
|
||||
}
|
||||
|
||||
// Log is used to dump all the steps in the Trace
|
||||
func (t *Trace) Log() {
|
||||
// an explicit logging request should dump all the steps out at the higher level
|
||||
t.logWithStepThreshold(0)
|
||||
}
|
||||
|
||||
func (t *Trace) logWithStepThreshold(stepThreshold time.Duration) {
|
||||
var buffer bytes.Buffer
|
||||
tracenum := rand.Int31()
|
||||
endTime := time.Now()
|
||||
|
||||
totalTime := endTime.Sub(t.startTime)
|
||||
buffer.WriteString(fmt.Sprintf("Trace[%d]: %q (started: %v) (total time: %v):\n", tracenum, t.name, t.startTime, totalTime))
|
||||
lastStepTime := t.startTime
|
||||
for _, step := range t.steps {
|
||||
stepDuration := step.stepTime.Sub(lastStepTime)
|
||||
if stepThreshold == 0 || stepDuration > stepThreshold || klog.V(4) {
|
||||
buffer.WriteString(fmt.Sprintf("Trace[%d]: [%v] [%v] %v\n", tracenum, step.stepTime.Sub(t.startTime), stepDuration, step.msg))
|
||||
}
|
||||
lastStepTime = step.stepTime
|
||||
}
|
||||
stepDuration := endTime.Sub(lastStepTime)
|
||||
if stepThreshold == 0 || stepDuration > stepThreshold || klog.V(4) {
|
||||
buffer.WriteString(fmt.Sprintf("Trace[%d]: [%v] [%v] END\n", tracenum, endTime.Sub(t.startTime), stepDuration))
|
||||
}
|
||||
|
||||
klog.Info(buffer.String())
|
||||
}
|
||||
|
||||
// LogIfLong is used to dump steps that took longer than its share
|
||||
func (t *Trace) LogIfLong(threshold time.Duration) {
|
||||
if time.Since(t.startTime) >= threshold {
|
||||
// if any step took more than it's share of the total allowed time, it deserves a higher log level
|
||||
stepThreshold := threshold / time.Duration(len(t.steps)+1)
|
||||
t.logWithStepThreshold(stepThreshold)
|
||||
}
|
||||
}
|
||||
|
||||
// TotalTime can be used to figure out how long it took since the Trace was created
|
||||
func (t *Trace) TotalTime() time.Duration {
|
||||
return time.Since(t.startTime)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue