Update go dependencies

This commit is contained in:
Manuel de Brito Fontes 2017-11-12 14:14:23 -03:00
parent a858c549d9
commit f3bde94d68
643 changed files with 14296 additions and 19354 deletions

View file

@ -38,7 +38,6 @@ filegroup(
"//pkg/util/net:all-srcs",
"//pkg/util/netsh:all-srcs",
"//pkg/util/node:all-srcs",
"//pkg/util/nsenter:all-srcs",
"//pkg/util/oom:all-srcs",
"//pkg/util/parsers:all-srcs",
"//pkg/util/pointer:all-srcs",

View file

@ -8,7 +8,6 @@ load(
go_library(
name = "go_default_library",
srcs = ["file.go"],
importpath = "k8s.io/kubernetes/pkg/util/file",
)
filegroup(

View file

@ -13,7 +13,6 @@ go_library(
"filesystem.go",
"watcher.go",
],
importpath = "k8s.io/kubernetes/pkg/util/filesystem",
deps = [
"//vendor/github.com/fsnotify/fsnotify:go_default_library",
"//vendor/github.com/spf13/afero:go_default_library",

View file

@ -62,11 +62,6 @@ func (DefaultFs) RemoveAll(path string) error {
return os.RemoveAll(path)
}
// Remove via os.RemoveAll
func (DefaultFs) Remove(name string) error {
return os.Remove(name)
}
// ReadFile via ioutil.ReadFile
func (DefaultFs) ReadFile(filename string) ([]byte, error) {
return ioutil.ReadFile(filename)

View file

@ -92,11 +92,6 @@ func (fs *fakeFs) RemoveAll(path string) error {
return fs.a.RemoveAll(path)
}
// Remove via afero.RemoveAll
func (fs *fakeFs) Remove(name string) error {
return fs.a.Remove(name)
}
// fakeFile implements File; for use with fakeFs
type fakeFile struct {
file afero.File

View file

@ -31,7 +31,6 @@ type Filesystem interface {
MkdirAll(path string, perm os.FileMode) error
Chtimes(name string, atime time.Time, mtime time.Time) error
RemoveAll(path string) error
Remove(name string) error
// from "io/ioutil"
ReadFile(filename string) ([]byte, error)

View file

@ -9,14 +9,12 @@ load(
go_library(
name = "go_default_library",
srcs = ["hash.go"],
importpath = "k8s.io/kubernetes/pkg/util/hash",
deps = ["//vendor/github.com/davecgh/go-spew/spew:go_default_library"],
)
go_test(
name = "go_default_test",
srcs = ["hash_test.go"],
importpath = "k8s.io/kubernetes/pkg/util/hash",
library = ":go_default_library",
deps = ["//vendor/github.com/davecgh/go-spew/spew:go_default_library"],
)

View file

@ -11,7 +11,6 @@ go_library(
"consistentread.go",
"writer.go",
],
importpath = "k8s.io/kubernetes/pkg/util/io",
deps = ["//vendor/github.com/golang/glog:go_default_library"],
)

View file

@ -25,14 +25,12 @@ go_library(
],
"//conditions:default": [],
}),
importpath = "k8s.io/kubernetes/pkg/util/mount",
deps = [
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
] + select({
"@io_bazel_rules_go//go/platform:linux_amd64": [
"//pkg/util/io:go_default_library",
"//pkg/util/nsenter:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
],
@ -54,7 +52,6 @@ go_test(
],
"//conditions:default": [],
}),
importpath = "k8s.io/kubernetes/pkg/util/mount",
library = ":go_default_library",
deps = ["//vendor/k8s.io/utils/exec/testing:go_default_library"],
)

View file

@ -125,7 +125,7 @@ func (f *FakeMounter) List() ([]MountPoint, error) {
}
func (f *FakeMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
return mp.Path == dir
return (mp.Path == dir)
}
func (f *FakeMounter) IsNotMountPoint(dir string) (bool, error) {
@ -175,19 +175,3 @@ func (f *FakeMounter) GetDeviceNameFromMount(mountPath, pluginDir string) (strin
func (f *FakeMounter) MakeRShared(path string) error {
return nil
}
func (f *FakeMounter) GetFileType(pathname string) (FileType, error) {
return FileType("fake"), nil
}
func (f *FakeMounter) MakeDir(pathname string) error {
return nil
}
func (f *FakeMounter) MakeFile(pathname string) error {
return nil
}
func (f *FakeMounter) ExistsPath(pathname string) bool {
return false
}

View file

@ -19,25 +19,13 @@ limitations under the License.
package mount
import (
"fmt"
"path"
"path/filepath"
"strings"
"github.com/golang/glog"
)
type FileType string
const (
// Default mount command if mounter path is not specified
defaultMountCommand = "mount"
MountsInGlobalPDPath = "mounts"
FileTypeDirectory FileType = "Directory"
FileTypeFile FileType = "File"
FileTypeSocket FileType = "Socket"
FileTypeCharDev FileType = "CharDevice"
FileTypeBlockDev FileType = "BlockDevice"
defaultMountCommand = "mount"
MountsInGlobalPDPath = "mounts"
)
type Interface interface {
@ -77,18 +65,6 @@ type Interface interface {
// MakeRShared checks that given path is on a mount with 'rshared' mount
// propagation. If not, it bind-mounts the path as rshared.
MakeRShared(path string) error
// GetFileType checks for file/directory/socket/block/character devices.
// Will operate in the host mount namespace if kubelet is running in a container
GetFileType(pathname string) (FileType, error)
// MakeFile creates an empty file.
// Will operate in the host mount namespace if kubelet is running in a container
MakeFile(pathname string) error
// MakeDir creates a new directory.
// Will operate in the host mount namespace if kubelet is running in a container
MakeDir(pathname string) error
// ExistsPath checks whether the path exists.
// Will operate in the host mount namespace if kubelet is running in a container
ExistsPath(pathname string) bool
}
// Exec executes command where mount utilities are. This can be either the host,
@ -138,41 +114,6 @@ func (mounter *SafeFormatAndMount) FormatAndMount(source string, target string,
return mounter.formatAndMount(source, target, fstype, options)
}
// GetMountRefs finds all other references to the device referenced
// by mountPath; returns a list of paths.
func GetMountRefs(mounter Interface, mountPath string) ([]string, error) {
mps, err := mounter.List()
if err != nil {
return nil, err
}
// Find the device name.
deviceName := ""
// If mountPath is symlink, need get its target path.
slTarget, err := filepath.EvalSymlinks(mountPath)
if err != nil {
slTarget = mountPath
}
for i := range mps {
if mps[i].Path == slTarget {
deviceName = mps[i].Device
break
}
}
// Find all references to the device.
var refs []string
if deviceName == "" {
glog.Warningf("could not determine device for path: %q", mountPath)
} else {
for i := range mps {
if mps[i].Device == deviceName && mps[i].Path != slTarget {
refs = append(refs, mps[i].Path)
}
}
}
return refs, nil
}
// GetMountRefsByDev finds all references to the device provided
// by mountPath; returns a list of paths.
func GetMountRefsByDev(mounter Interface, mountPath string) ([]string, error) {
@ -239,34 +180,6 @@ func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, e
return device, refCount, nil
}
// getDeviceNameFromMount find the device name from /proc/mounts in which
// the mount path reference should match the given plugin directory. In case no mount path reference
// matches, returns the volume name taken from its given mountPath
func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (string, error) {
refs, err := GetMountRefs(mounter, mountPath)
if err != nil {
glog.V(4).Infof("GetMountRefs failed for mount path %q: %v", mountPath, err)
return "", err
}
if len(refs) == 0 {
glog.V(4).Infof("Directory %s is not mounted", mountPath)
return "", fmt.Errorf("directory %s is not mounted", mountPath)
}
basemountPath := path.Join(pluginDir, MountsInGlobalPDPath)
for _, ref := range refs {
if strings.HasPrefix(ref, basemountPath) {
volumeID, err := filepath.Rel(basemountPath, ref)
if err != nil {
glog.Errorf("Failed to get volume id from mount %s - %v", mountPath, err)
return "", err
}
return volumeID, nil
}
}
return path.Base(mountPath), nil
}
// IsNotMountPoint determines if a directory is a mountpoint.
// It should return ErrNotExist when the directory does not exist.
// This method uses the List() of all mountpoints

View file

@ -22,6 +22,8 @@ import (
"fmt"
"os"
"os/exec"
"path"
"path/filepath"
"strconv"
"strings"
"syscall"
@ -42,6 +44,9 @@ const (
procMountsPath = "/proc/mounts"
// Location of the mountinfo file
procMountInfoPath = "/proc/self/mountinfo"
)
const (
// 'fsck' found errors and corrected them
fsckErrorsCorrected = 1
// 'fsck' found errors but exited without correcting them
@ -68,12 +73,12 @@ func New(mounterPath string) Interface {
// Mount mounts source to target as fstype with given options. 'source' and 'fstype' must
// be an emtpy string in case it's not required, e.g. for remount, or for auto filesystem
// type, where kernel handles fstype for you. The mount 'options' is a list of options,
// type, where kernel handles fs type for you. The mount 'options' is a list of options,
// currently come from mount(8), e.g. "ro", "remount", "bind", etc. If no more option is
// required, call Mount with an empty string list or nil.
func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error {
// Path to mounter binary if containerized mounter is needed. Otherwise, it is set to empty.
// All Linux distros are expected to be shipped with a mount utility that a support bind mounts.
// All Linux distros are expected to be shipped with a mount utility that an support bind mounts.
mounterPath := ""
bind, bindRemountOpts := isBind(options)
if bind {
@ -141,6 +146,41 @@ func (m *Mounter) doMount(mounterPath string, mountCmd string, source string, ta
return err
}
// GetMountRefs finds all other references to the device referenced
// by mountPath; returns a list of paths.
func GetMountRefs(mounter Interface, mountPath string) ([]string, error) {
mps, err := mounter.List()
if err != nil {
return nil, err
}
// Find the device name.
deviceName := ""
// If mountPath is symlink, need get its target path.
slTarget, err := filepath.EvalSymlinks(mountPath)
if err != nil {
slTarget = mountPath
}
for i := range mps {
if mps[i].Path == slTarget {
deviceName = mps[i].Device
break
}
}
// Find all references to the device.
var refs []string
if deviceName == "" {
glog.Warningf("could not determine device for path: %q", mountPath)
} else {
for i := range mps {
if mps[i].Device == deviceName && mps[i].Path != slTarget {
refs = append(refs, mps[i].Path)
}
}
}
return refs, nil
}
// detectSystemd returns true if OS runs with systemd as init. When not sure
// (permission errors, ...), it returns false.
// There may be different ways how to detect systemd, this one makes sure that
@ -252,29 +292,17 @@ func (mounter *Mounter) DeviceOpened(pathname string) (bool, error) {
// PathIsDevice uses FileInfo returned from os.Stat to check if path refers
// to a device.
func (mounter *Mounter) PathIsDevice(pathname string) (bool, error) {
pathType, err := mounter.GetFileType(pathname)
isDevice := pathType == FileTypeCharDev || pathType == FileTypeBlockDev
return isDevice, err
return pathIsDevice(pathname)
}
func exclusiveOpenFailsOnDevice(pathname string) (bool, error) {
var isDevice bool
finfo, err := os.Stat(pathname)
if os.IsNotExist(err) {
isDevice = false
}
// err in call to os.Stat
isDevice, err := pathIsDevice(pathname)
if err != nil {
return false, fmt.Errorf(
"PathIsDevice failed for path %q: %v",
pathname,
err)
}
// path refers to a device
if finfo.Mode()&os.ModeDevice != 0 {
isDevice = true
}
if !isDevice {
glog.Errorf("Path %q is not refering to a device.", pathname)
return false, nil
@ -294,11 +322,56 @@ func exclusiveOpenFailsOnDevice(pathname string) (bool, error) {
return false, errno
}
func pathIsDevice(pathname string) (bool, error) {
finfo, err := os.Stat(pathname)
if os.IsNotExist(err) {
return false, nil
}
// err in call to os.Stat
if err != nil {
return false, err
}
// path refers to a device
if finfo.Mode()&os.ModeDevice != 0 {
return true, nil
}
// path does not refer to device
return false, nil
}
//GetDeviceNameFromMount: given a mount point, find the device name from its global mount point
func (mounter *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) {
return getDeviceNameFromMount(mounter, mountPath, pluginDir)
}
// getDeviceNameFromMount find the device name from /proc/mounts in which
// the mount path reference should match the given plugin directory. In case no mount path reference
// matches, returns the volume name taken from its given mountPath
func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (string, error) {
refs, err := GetMountRefs(mounter, mountPath)
if err != nil {
glog.V(4).Infof("GetMountRefs failed for mount path %q: %v", mountPath, err)
return "", err
}
if len(refs) == 0 {
glog.V(4).Infof("Directory %s is not mounted", mountPath)
return "", fmt.Errorf("directory %s is not mounted", mountPath)
}
basemountPath := path.Join(pluginDir, MountsInGlobalPDPath)
for _, ref := range refs {
if strings.HasPrefix(ref, basemountPath) {
volumeID, err := filepath.Rel(basemountPath, ref)
if err != nil {
glog.Errorf("Failed to get volume id from mount %s - %v", mountPath, err)
return "", err
}
return volumeID, nil
}
}
return path.Base(mountPath), nil
}
func listProcMounts(mountFilePath string) ([]MountPoint, error) {
content, err := utilio.ConsistentRead(mountFilePath, maxListTries)
if err != nil {
@ -345,64 +418,9 @@ func parseProcMounts(content []byte) ([]MountPoint, error) {
}
func (mounter *Mounter) MakeRShared(path string) error {
return doMakeRShared(path, procMountInfoPath)
}
func (mounter *Mounter) GetFileType(pathname string) (FileType, error) {
var pathType FileType
finfo, err := os.Stat(pathname)
if os.IsNotExist(err) {
return pathType, fmt.Errorf("path %q does not exist", pathname)
}
// err in call to os.Stat
if err != nil {
return pathType, err
}
mode := finfo.Sys().(*syscall.Stat_t).Mode
switch mode & syscall.S_IFMT {
case syscall.S_IFSOCK:
return FileTypeSocket, nil
case syscall.S_IFBLK:
return FileTypeBlockDev, nil
case syscall.S_IFCHR:
return FileTypeBlockDev, nil
case syscall.S_IFDIR:
return FileTypeDirectory, nil
case syscall.S_IFREG:
return FileTypeFile, nil
}
return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device")
}
func (mounter *Mounter) MakeDir(pathname string) error {
err := os.MkdirAll(pathname, os.FileMode(0755))
if err != nil {
if !os.IsExist(err) {
return err
}
}
return nil
}
func (mounter *Mounter) MakeFile(pathname string) error {
f, err := os.OpenFile(pathname, os.O_CREATE, os.FileMode(0644))
defer f.Close()
if err != nil {
if !os.IsExist(err) {
return err
}
}
return nil
}
func (mounter *Mounter) ExistsPath(pathname string) bool {
_, err := os.Stat(pathname)
if err != nil {
return false
}
return true
mountCmd := defaultMountCommand
mountArgs := []string{}
return doMakeRShared(path, procMountInfoPath, mountCmd, mountArgs)
}
// formatAndMount uses unix utils to format and mount the given disk
@ -471,7 +489,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
return mountErr
}
// getDiskFormat uses 'lsblk' to see if the given disk is unformated
// diskLooksUnformatted uses 'lsblk' to see if the given disk is unformated
func (mounter *SafeFormatAndMount) getDiskFormat(disk string) (string, error) {
args := []string{"-n", "-o", "FSTYPE", disk}
glog.V(4).Infof("Attempting to determine if disk %q is formatted using lsblk with args: (%v)", disk, args)
@ -573,7 +591,7 @@ func parseMountInfo(filename string) ([]mountInfo, error) {
// path is shared and bind-mounts it as rshared if needed. mountCmd and
// mountArgs are expected to contain mount-like command, doMakeRShared will add
// '--bind <path> <path>' and '--make-rshared <path>' to mountArgs.
func doMakeRShared(path string, mountInfoFilename string) error {
func doMakeRShared(path string, mountInfoFilename string, mountCmd string, mountArgs []string) error {
shared, err := isShared(path, mountInfoFilename)
if err != nil {
return err

View file

@ -18,10 +18,6 @@ limitations under the License.
package mount
import (
"errors"
)
type Mounter struct {
mounterPath string
}
@ -43,6 +39,12 @@ func (mounter *Mounter) Unmount(target string) error {
return nil
}
// GetMountRefs finds all other references to the device referenced
// by mountPath; returns a list of paths.
func GetMountRefs(mounter Interface, mountPath string) ([]string, error) {
return []string{}, nil
}
func (mounter *Mounter) List() ([]MountPoint, error) {
return []MountPoint{}, nil
}
@ -63,6 +65,10 @@ func (mounter *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (str
return "", nil
}
func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (string, error) {
return "", nil
}
func (mounter *Mounter) DeviceOpened(pathname string) (bool, error) {
return false, nil
}
@ -82,19 +88,3 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) {
return true, nil
}
func (mounter *Mounter) GetFileType(pathname string) (FileType, error) {
return FileType("fake"), errors.New("not implemented")
}
func (mounter *Mounter) MakeDir(pathname string) error {
return nil
}
func (mounter *Mounter) MakeFile(pathname string) error {
return nil
}
func (mounter *Mounter) ExistsPath(pathname string) bool {
return true
}

View file

@ -22,10 +22,10 @@ import (
"fmt"
"os"
"os/exec"
"path"
"path/filepath"
"strconv"
"strings"
"syscall"
"github.com/golang/glog"
)
@ -75,28 +75,8 @@ func (mounter *Mounter) Mount(source string, target string, fstype string, optio
return nil
}
// currently only cifs mount is supported
if strings.ToLower(fstype) != "cifs" {
return fmt.Errorf("azureMount: only cifs mount is supported now, fstype: %q, mounting source (%q), target (%q), with options (%q)", fstype, source, target, options)
}
cmdLine := fmt.Sprintf(`$User = "%s";$PWord = ConvertTo-SecureString -String "%s" -AsPlainText -Force;`+
`$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord`,
options[0], options[1])
driverLetter, err := getAvailableDriveLetter()
if err != nil {
return err
}
bindSource = driverLetter + ":"
cmdLine += fmt.Sprintf(";New-SmbGlobalMapping -LocalPath %s -RemotePath %s -Credential $Credential", bindSource, source)
if output, err := exec.Command("powershell", "/c", cmdLine).CombinedOutput(); err != nil {
// we don't return error here, even though New-SmbGlobalMapping failed, we still make it successful,
// will return error when Windows 2016 RS3 is ready on azure
glog.Errorf("azureMount: SmbGlobalMapping failed: %v, only SMB mount is supported now, output: %q", err, string(output))
return os.MkdirAll(target, 0755)
}
// empty implementation for mounting azure file
return os.MkdirAll(target, 0755)
}
if output, err := exec.Command("cmd", "/c", "mklink", "/D", target, bindSource).CombinedOutput(); err != nil {
@ -118,6 +98,16 @@ func (mounter *Mounter) Unmount(target string) error {
return nil
}
// GetMountRefs finds all other references to the device(drive) referenced
// by mountPath; returns a list of paths.
func GetMountRefs(mounter Interface, mountPath string) ([]string, error) {
refs, err := getAllParentLinks(normalizeWindowsPath(mountPath))
if err != nil {
return nil, err
}
return refs, nil
}
// List returns a list of all mounted filesystems. todo
func (mounter *Mounter) List() ([]MountPoint, error) {
return []MountPoint{}, nil
@ -152,6 +142,33 @@ func (mounter *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (str
return getDeviceNameFromMount(mounter, mountPath, pluginDir)
}
// getDeviceNameFromMount find the device(drive) name in which
// the mount path reference should match the given plugin directory. In case no mount path reference
// matches, returns the volume name taken from its given mountPath
func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (string, error) {
refs, err := GetMountRefs(mounter, mountPath)
if err != nil {
glog.V(4).Infof("GetMountRefs failed for mount path %q: %v", mountPath, err)
return "", err
}
if len(refs) == 0 {
return "", fmt.Errorf("directory %s is not mounted", mountPath)
}
basemountPath := normalizeWindowsPath(path.Join(pluginDir, MountsInGlobalPDPath))
for _, ref := range refs {
if strings.Contains(ref, basemountPath) {
volumeID, err := filepath.Rel(normalizeWindowsPath(basemountPath), ref)
if err != nil {
glog.Errorf("Failed to get volume id from mount %s - %v", mountPath, err)
return "", err
}
return volumeID, nil
}
}
return path.Base(mountPath), nil
}
// DeviceOpened determines if the device is in use elsewhere
func (mounter *Mounter) DeviceOpened(pathname string) (bool, error) {
return false, nil
@ -168,67 +185,6 @@ func (mounter *Mounter) MakeRShared(path string) error {
return nil
}
// GetFileType checks for sockets/block/character devices
func (mounter *Mounter) GetFileType(pathname string) (FileType, error) {
var pathType FileType
info, err := os.Stat(pathname)
if os.IsNotExist(err) {
return pathType, fmt.Errorf("path %q does not exist", pathname)
}
// err in call to os.Stat
if err != nil {
return pathType, err
}
mode := info.Sys().(*syscall.Win32FileAttributeData).FileAttributes
switch mode & syscall.S_IFMT {
case syscall.S_IFSOCK:
return FileTypeSocket, nil
case syscall.S_IFBLK:
return FileTypeBlockDev, nil
case syscall.S_IFCHR:
return FileTypeCharDev, nil
case syscall.S_IFDIR:
return FileTypeDirectory, nil
case syscall.S_IFREG:
return FileTypeFile, nil
}
return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device")
}
// MakeFile creates a new directory
func (mounter *Mounter) MakeDir(pathname string) error {
err := os.MkdirAll(pathname, os.FileMode(0755))
if err != nil {
if !os.IsExist(err) {
return err
}
}
return nil
}
// MakeFile creates an empty file
func (mounter *Mounter) MakeFile(pathname string) error {
f, err := os.OpenFile(pathname, os.O_CREATE, os.FileMode(0644))
defer f.Close()
if err != nil {
if !os.IsExist(err) {
return err
}
}
return nil
}
// ExistsPath checks whether the path exists
func (mounter *Mounter) ExistsPath(pathname string) bool {
_, err := os.Stat(pathname)
if err != nil {
return false
}
return true
}
func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, fstype string, options []string) error {
// Try to mount the disk
glog.V(4).Infof("Attempting to formatAndMount disk: %s %s %s", fstype, source, target)
@ -260,20 +216,6 @@ func normalizeWindowsPath(path string) string {
return normalizedPath
}
func getAvailableDriveLetter() (string, error) {
cmd := "$used = Get-PSDrive | Select-Object -Expand Name | Where-Object { $_.Length -eq 1 }"
cmd += ";$drive = 67..90 | ForEach-Object { [string][char]$_ } | Where-Object { $used -notcontains $_ } | Select-Object -First 1;$drive"
output, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
if err != nil {
return "", fmt.Errorf("getAvailableDriveLetter failed: %v, output: %q", err, string(output))
}
if len(output) == 0 {
return "", fmt.Errorf("azureMount: there is no available drive letter now")
}
return string(output)[:1], nil
}
// ValidateDiskNumber : disk number should be a number in [0, 99]
func ValidateDiskNumber(disk string) error {
diskNum, err := strconv.Atoi(disk)
@ -300,3 +242,30 @@ func getDriveLetterByDiskNumber(diskNum string, exec Exec) (string, error) {
}
return string(output)[:1], nil
}
// getAllParentLinks walks all symbolic links and return all the parent targets recursively
func getAllParentLinks(path string) ([]string, error) {
const maxIter = 255
links := []string{}
for {
links = append(links, path)
if len(links) > maxIter {
return links, fmt.Errorf("unexpected length of parent links: %v", links)
}
fi, err := os.Lstat(path)
if err != nil {
return links, fmt.Errorf("Lstat: %v", err)
}
if fi.Mode()&os.ModeSymlink == 0 {
break
}
path, err = os.Readlink(path)
if err != nil {
return links, fmt.Errorf("Readlink error: %v", err)
}
}
return links, nil
}

View file

@ -19,6 +19,8 @@ limitations under the License.
package mount
import (
"fmt"
"os/exec"
"testing"
)
@ -69,3 +71,70 @@ func TestValidateDiskNumber(t *testing.T) {
t.Errorf("TestValidateDiskNumber test failed, disk number : %s", diskNum)
}
}
func makeLink(link, target string) error {
if output, err := exec.Command("cmd", "/c", "mklink", "/D", link, target).CombinedOutput(); err != nil {
return fmt.Errorf("mklink failed: %v, link(%q) target(%q) output: %q", err, link, target, string(output))
}
return nil
}
func removeLink(link string) error {
if output, err := exec.Command("cmd", "/c", "rmdir", link).CombinedOutput(); err != nil {
return fmt.Errorf("rmdir failed: %v, output: %q", err, string(output))
}
return nil
}
func setEquivalent(set1, set2 []string) bool {
map1 := make(map[string]bool)
map2 := make(map[string]bool)
for _, s := range set1 {
map1[s] = true
}
for _, s := range set2 {
map2[s] = true
}
for s := range map1 {
if !map2[s] {
return false
}
}
for s := range map2 {
if !map1[s] {
return false
}
}
return true
}
// this func must run in admin mode, otherwise it will fail
func TestGetMountRefs(t *testing.T) {
fm := &FakeMounter{MountPoints: []MountPoint{}}
mountPath := `c:\secondmountpath`
expectedRefs := []string{`c:\`, `c:\firstmountpath`, mountPath}
// remove symbolic links first
for i := 1; i < len(expectedRefs); i++ {
removeLink(expectedRefs[i])
}
// create symbolic links
for i := 1; i < len(expectedRefs); i++ {
if err := makeLink(expectedRefs[i], expectedRefs[i-1]); err != nil {
t.Errorf("makeLink failed: %v", err)
}
}
if refs, err := GetMountRefs(fm, mountPath); err != nil || !setEquivalent(expectedRefs, refs) {
t.Errorf("getMountRefs(%q) = %v, error: %v; expected %v", mountPath, refs, err, expectedRefs)
}
// remove symbolic links
for i := 1; i < len(expectedRefs); i++ {
if err := removeLink(expectedRefs[i]); err != nil {
t.Errorf("removeLink failed: %v", err)
}
}
}

View file

@ -25,30 +25,78 @@ import (
"strings"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/util/nsenter"
"k8s.io/utils/exec"
)
const (
// hostProcMountsPath is the default mount path for rootfs
hostProcMountsPath = "/rootfs/proc/1/mounts"
// hostProcMountinfoPath is the default mount info path for rootfs
hostProcMountinfoPath = "/rootfs/proc/1/mountinfo"
)
// Currently, all docker containers receive their own mount namespaces.
// NsenterMounter works by executing nsenter to run commands in
// NsenterMounter is part of experimental support for running the kubelet
// in a container. Currently, all docker containers receive their own mount
// namespaces. NsenterMounter works by executing nsenter to run commands in
// the host's mount namespace.
//
// NsenterMounter 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, and umount binaries in /bin,
// /usr/sbin, or /usr/bin
// 7. The host image should have systemd-run in /bin, /usr/sbin, or /usr/bin
// For more information about mount propagation modes, see:
// https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
type NsenterMounter struct {
ne *nsenter.Nsenter
// a map of commands to their paths on the host filesystem
paths map[string]string
}
func NewNsenterMounter() *NsenterMounter {
return &NsenterMounter{ne: nsenter.NewNsenter()}
m := &NsenterMounter{
paths: map[string]string{
"mount": "",
"findmnt": "",
"umount": "",
"systemd-run": "",
},
}
// search for the mount command in other locations besides /usr/bin
for binary := range m.paths {
// default to root
m.paths[binary] = filepath.Join("/", binary)
for _, path := range []string{"/bin", "/usr/sbin", "/usr/bin"} {
binPath := filepath.Join(path, binary)
if _, err := os.Stat(filepath.Join(hostRootFsPath, binPath)); err != nil {
continue
}
m.paths[binary] = binPath
break
}
// TODO: error, so that the kubelet can stop if the mounts don't exist
// (don't forget that systemd-run is optional)
}
return m
}
// NsenterMounter implements mount.Interface
var _ = Interface(&NsenterMounter{})
const (
hostRootFsPath = "/rootfs"
hostProcMountsPath = "/rootfs/proc/1/mounts"
hostProcMountinfoPath = "/rootfs/proc/1/mountinfo"
hostMountNamespacePath = "/rootfs/proc/1/ns/mnt"
nsenterPath = "nsenter"
)
// Mount runs mount(8) in the host's root mount namespace. Aside from this
// aspect, Mount has the same semantics as the mounter returned by mount.New()
func (n *NsenterMounter) Mount(source string, target string, fstype string, options []string) error {
@ -68,22 +116,26 @@ func (n *NsenterMounter) Mount(source string, target string, fstype string, opti
// doNsenterMount nsenters the host's mount namespace and performs the
// requested mount.
func (n *NsenterMounter) doNsenterMount(source, target, fstype string, options []string) error {
glog.V(5).Infof("nsenter mount %s %s %s %v", source, target, fstype, options)
cmd, args := n.makeNsenterArgs(source, target, fstype, options)
outputBytes, err := n.ne.Exec(cmd, args).CombinedOutput()
glog.V(5).Infof("nsenter Mounting %s %s %s %v", source, target, fstype, options)
args := n.makeNsenterArgs(source, target, fstype, options)
glog.V(5).Infof("Mount command: %v %v", nsenterPath, args)
exec := exec.New()
outputBytes, err := exec.Command(nsenterPath, args...).CombinedOutput()
if len(outputBytes) != 0 {
glog.V(5).Infof("Output of mounting %s to %s: %v", source, target, string(outputBytes))
}
return err
}
// makeNsenterArgs makes a list of argument to nsenter in order to do the
// requested mount.
func (n *NsenterMounter) makeNsenterArgs(source, target, fstype string, options []string) (string, []string) {
mountCmd := n.ne.AbsHostPath("mount")
func (n *NsenterMounter) makeNsenterArgs(source, target, fstype string, options []string) []string {
mountCmd := n.absHostPath("mount")
mountArgs := makeMountArgs(source, target, fstype, options)
if systemdRunPath, hasSystemd := n.ne.SupportsSystemd(); hasSystemd {
if systemdRunPath, hasSystemd := n.paths["systemd-run"]; hasSystemd {
// Complete command line:
// nsenter --mount=/rootfs/proc/1/ns/mnt -- /bin/systemd-run --description=... --scope -- /bin/mount -t <type> <what> <where>
// Expected flow is:
@ -113,20 +165,34 @@ func (n *NsenterMounter) makeNsenterArgs(source, target, fstype string, options
// No code here, mountCmd and mountArgs use /bin/mount
}
return mountCmd, mountArgs
nsenterArgs := []string{
"--mount=" + hostMountNamespacePath,
"--",
mountCmd,
}
nsenterArgs = append(nsenterArgs, mountArgs...)
return nsenterArgs
}
// Unmount runs umount(8) in the host's mount namespace.
func (n *NsenterMounter) Unmount(target string) error {
args := []string{target}
args := []string{
"--mount=" + hostMountNamespacePath,
"--",
n.absHostPath("umount"),
target,
}
// No need to execute systemd-run here, it's enough that unmount is executed
// in the host's mount namespace. It will finish appropriate fuse daemon(s)
// running in any scope.
glog.V(5).Infof("nsenter unmount args: %v", args)
outputBytes, err := n.ne.Exec("umount", args).CombinedOutput()
glog.V(5).Infof("Unmount command: %v %v", nsenterPath, args)
exec := exec.New()
outputBytes, err := exec.Command(nsenterPath, args...).CombinedOutput()
if len(outputBytes) != 0 {
glog.V(5).Infof("Output of unmounting %s: %v", target, string(outputBytes))
}
return err
}
@ -141,7 +207,7 @@ func (m *NsenterMounter) IsNotMountPoint(dir string) (bool, error) {
func (*NsenterMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
deletedDir := fmt.Sprintf("%s\\040(deleted)", dir)
return (mp.Path == dir) || (mp.Path == deletedDir)
return ((mp.Path == dir) || (mp.Path == deletedDir))
}
// IsLikelyNotMountPoint determines whether a path is a mountpoint by calling findmnt
@ -161,9 +227,11 @@ func (n *NsenterMounter) IsLikelyNotMountPoint(file string) (bool, error) {
// the first of multiple possible mountpoints using --first-only.
// Also add fstype output to make sure that the output of target file will give the full path
// TODO: Need more refactoring for this function. Track the solution with issue #26996
args := []string{"-o", "target,fstype", "--noheadings", "--first-only", "--target", file}
glog.V(5).Infof("nsenter findmnt args: %v", args)
out, err := n.ne.Exec("findmnt", args).CombinedOutput()
args := []string{"--mount=" + hostMountNamespacePath, "--", n.absHostPath("findmnt"), "-o", "target,fstype", "--noheadings", "--first-only", "--target", file}
glog.V(5).Infof("findmnt command: %v %v", nsenterPath, args)
exec := exec.New()
out, err := exec.Command(nsenterPath, args...).CombinedOutput()
if err != nil {
glog.V(2).Infof("Failed findmnt command for path %s: %v", file, err)
// Different operating systems behave differently for paths which are not mount points.
@ -209,9 +277,7 @@ func (n *NsenterMounter) DeviceOpened(pathname string) (bool, error) {
// PathIsDevice uses FileInfo returned from os.Stat to check if path refers
// to a device.
func (n *NsenterMounter) PathIsDevice(pathname string) (bool, error) {
pathType, err := n.GetFileType(pathname)
isDevice := pathType == FileTypeCharDev || pathType == FileTypeBlockDev
return isDevice, err
return pathIsDevice(pathname)
}
//GetDeviceNameFromMount given a mount point, find the volume id from checking /proc/mounts
@ -219,54 +285,20 @@ func (n *NsenterMounter) GetDeviceNameFromMount(mountPath, pluginDir string) (st
return getDeviceNameFromMount(n, mountPath, pluginDir)
}
func (n *NsenterMounter) absHostPath(command string) string {
path, ok := n.paths[command]
if !ok {
return command
}
return path
}
func (n *NsenterMounter) MakeRShared(path string) error {
return doMakeRShared(path, hostProcMountinfoPath)
}
func (mounter *NsenterMounter) GetFileType(pathname string) (FileType, error) {
var pathType FileType
outputBytes, err := mounter.ne.Exec("stat", []string{"-L", `--printf "%F"`, pathname}).CombinedOutput()
if err != nil {
return pathType, err
nsenterCmd := nsenterPath
nsenterArgs := []string{
"--mount=" + hostMountNamespacePath,
"--",
n.absHostPath("mount"),
}
switch string(outputBytes) {
case "socket":
return FileTypeSocket, nil
case "character special file":
return FileTypeCharDev, nil
case "block special file":
return FileTypeBlockDev, nil
case "directory":
return FileTypeDirectory, nil
case "regular file":
return FileTypeFile, nil
}
return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device")
}
func (mounter *NsenterMounter) MakeDir(pathname string) error {
args := []string{"-p", pathname}
if _, err := mounter.ne.Exec("mkdir", args).CombinedOutput(); err != nil {
return err
}
return nil
}
func (mounter *NsenterMounter) MakeFile(pathname string) error {
args := []string{pathname}
if _, err := mounter.ne.Exec("touch", args).CombinedOutput(); err != nil {
return err
}
return nil
}
func (mounter *NsenterMounter) ExistsPath(pathname string) bool {
args := []string{pathname}
_, err := mounter.ne.Exec("ls", args).CombinedOutput()
if err == nil {
return true
}
return false
return doMakeRShared(path, hostProcMountinfoPath, nsenterCmd, nsenterArgs)
}

View file

@ -18,10 +18,6 @@ limitations under the License.
package mount
import (
"errors"
)
type NsenterMounter struct{}
func NewNsenterMounter() *NsenterMounter {
@ -69,19 +65,3 @@ func (*NsenterMounter) GetDeviceNameFromMount(mountPath, pluginDir string) (stri
func (*NsenterMounter) MakeRShared(path string) error {
return nil
}
func (*NsenterMounter) GetFileType(_ string) (FileType, error) {
return FileType("fake"), errors.New("not implemented")
}
func (*NsenterMounter) MakeDir(pathname string) error {
return nil
}
func (*NsenterMounter) MakeFile(pathname string) error {
return nil
}
func (*NsenterMounter) ExistsPath(pathname string) bool {
return true
}

View file

@ -12,13 +12,11 @@ go_library(
"doc.go",
"ipnet.go",
],
importpath = "k8s.io/kubernetes/pkg/util/net/sets",
)
go_test(
name = "go_default_test",
srcs = ["ipnet_test.go"],
importpath = "k8s.io/kubernetes/pkg/util/net/sets",
library = ":go_default_library",
)

View file

@ -1,37 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"nsenter_unsupported.go",
] + select({
"@io_bazel_rules_go//go/platform:linux_amd64": [
"nsenter.go",
],
"//conditions:default": [],
}),
importpath = "k8s.io/kubernetes/pkg/util/nsenter",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/utils/exec:go_default_library",
] + select({
"@io_bazel_rules_go//go/platform:linux_amd64": [
"//vendor/github.com/golang/glog:go_default_library",
],
"//conditions:default": [],
}),
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View file

@ -1,124 +0,0 @@
// +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 (
"fmt"
"os"
"path/filepath"
"k8s.io/utils/exec"
"github.com/golang/glog"
)
const (
hostRootFsPath = "/rootfs"
// hostProcMountNsPath is the default mount namespace for rootfs
hostProcMountNsPath = "/rootfs/proc/1/ns/mnt"
// nsenterPath is the default nsenter command
nsenterPath = "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
// 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
}
// NewNsenter constructs a new instance of Nsenter
func NewNsenter() *Nsenter {
ne := &Nsenter{
paths: map[string]string{
"mount": "",
"findmnt": "",
"umount": "",
"systemd-run": "",
"stat": "",
"touch": "",
"mkdir": "",
"ls": "",
"sh": "",
"chmod": "",
},
}
// search for the required commands in other locations besides /usr/bin
for binary := range ne.paths {
// default to root
ne.paths[binary] = filepath.Join("/", binary)
for _, path := range []string{"/bin", "/usr/sbin", "/usr/bin"} {
binPath := filepath.Join(path, binary)
if _, err := os.Stat(filepath.Join(hostRootFsPath, binPath)); err != nil {
continue
}
ne.paths[binary] = binPath
break
}
// TODO: error, so that the kubelet can stop if the paths don't exist
// (don't forget that systemd-run is optional)
}
return ne
}
// Exec executes nsenter commands in hostProcMountNsPath mount namespace
func (ne *Nsenter) Exec(cmd string, args []string) exec.Cmd {
fullArgs := append([]string{fmt.Sprintf("--mount=%s", hostProcMountNsPath), "--"},
append([]string{ne.AbsHostPath(cmd)}, args...)...)
glog.V(5).Infof("Running nsenter command: %v %v", nsenterPath, fullArgs)
exec := exec.New()
return exec.Command(nsenterPath, fullArgs...)
}
// 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, hasSystemd := ne.paths["systemd-run"]
return systemdRunPath, hasSystemd
}

View file

@ -1,50 +0,0 @@
// +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 (
"k8s.io/utils/exec"
)
// 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() *Nsenter {
return &Nsenter{}
}
// Exec executes nsenter commands in hostProcMountNsPath mount namespace
func (ne *Nsenter) Exec(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
}

View file

@ -9,14 +9,12 @@ load(
go_library(
name = "go_default_library",
srcs = ["parsers.go"],
importpath = "k8s.io/kubernetes/pkg/util/parsers",
deps = ["//vendor/github.com/docker/distribution/reference:go_default_library"],
)
go_test(
name = "go_default_test",
srcs = ["parsers_test.go"],
importpath = "k8s.io/kubernetes/pkg/util/parsers",
library = ":go_default_library",
)

View file

@ -9,14 +9,12 @@ load(
go_test(
name = "go_default_test",
srcs = ["pointer_test.go"],
importpath = "k8s.io/kubernetes/pkg/util/pointer",
library = ":go_default_library",
)
go_library(
name = "go_default_library",
srcs = ["pointer.go"],
importpath = "k8s.io/kubernetes/pkg/util/pointer",
)
filegroup(

View file

@ -8,7 +8,6 @@ load(
go_library(
name = "go_default_library",
srcs = ["sysctl.go"],
importpath = "k8s.io/kubernetes/pkg/util/sysctl",
)
filegroup(

View file

@ -9,7 +9,6 @@ load(
go_library(
name = "go_default_library",
srcs = ["taints.go"],
importpath = "k8s.io/kubernetes/pkg/util/taints",
deps = [
"//pkg/api:go_default_library",
"//pkg/api/helper:go_default_library",
@ -23,7 +22,6 @@ go_library(
go_test(
name = "go_default_test",
srcs = ["taints_test.go"],
importpath = "k8s.io/kubernetes/pkg/util/taints",
library = ":go_default_library",
deps = [
"//pkg/api:go_default_library",

View file

@ -35,7 +35,7 @@ const (
UNTAINTED = "untainted"
)
// parseTaint parses a taint from a string. Taint must be of the format '<key>=<value>:<effect>'.
// 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, "=")
@ -76,10 +76,6 @@ type taintsVar struct {
}
func (t taintsVar) Set(s string) error {
if len(s) == 0 {
*t.ptr = nil
return nil
}
sts := strings.Split(s, ",")
var taints []api.Taint
for _, st := range sts {
@ -95,7 +91,7 @@ func (t taintsVar) Set(s string) error {
func (t taintsVar) String() string {
if len(*t.ptr) == 0 {
return ""
return "<nil>"
}
var taints []string
for _, taint := range *t.ptr {
@ -242,7 +238,11 @@ func DeleteTaint(taints []v1.Taint, taintToDelete *v1.Taint) ([]v1.Taint, bool)
// 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) {
newNode := node.DeepCopy()
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
@ -260,7 +260,11 @@ func RemoveTaint(node *v1.Node, taint *v1.Taint) (*v1.Node, bool, error) {
// 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) {
newNode := node.DeepCopy()
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