mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #85153 from codenrhoden/mount-no-exec-int
Retire mount.Exec for k8s.io/utils/exec
This commit is contained in:
commit
565566f4b2
@ -46,6 +46,7 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/util/workqueue:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -45,6 +45,8 @@ import (
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
"k8s.io/klog"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
|
||||
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/cache"
|
||||
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/metrics"
|
||||
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/populator"
|
||||
@ -768,8 +770,8 @@ func (adc *attachDetachController) DeleteServiceAccountTokenFunc() func(types.UI
|
||||
}
|
||||
}
|
||||
|
||||
func (adc *attachDetachController) GetExec(pluginName string) mount.Exec {
|
||||
return mount.NewOSExec()
|
||||
func (adc *attachDetachController) GetExec(pluginName string) utilexec.Interface {
|
||||
return utilexec.New()
|
||||
}
|
||||
|
||||
func (adc *attachDetachController) addNodeToDswp(node *v1.Node, nodeName types.NodeName) {
|
||||
|
@ -33,6 +33,7 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/util/workqueue:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -41,6 +41,8 @@ import (
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
|
||||
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
||||
"k8s.io/kubernetes/pkg/controller/volume/events"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
@ -380,8 +382,8 @@ func (expc *expandController) GetMounter(pluginName string) mount.Interface {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (expc *expandController) GetExec(pluginName string) mount.Exec {
|
||||
return mount.NewOSExec()
|
||||
func (expc *expandController) GetExec(pluginName string) utilexec.Interface {
|
||||
return utilexec.New()
|
||||
}
|
||||
|
||||
func (expc *expandController) GetHostName() string {
|
||||
|
@ -56,6 +56,7 @@ go_library(
|
||||
"//staging/src/k8s.io/cloud-provider/volume/errors:go_default_library",
|
||||
"//staging/src/k8s.io/csi-translation-lib:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -27,6 +27,8 @@ import (
|
||||
"k8s.io/client-go/tools/record"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
"k8s.io/klog"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
vol "k8s.io/kubernetes/pkg/volume"
|
||||
"k8s.io/kubernetes/pkg/volume/util/subpath"
|
||||
@ -116,8 +118,8 @@ func (ctrl *PersistentVolumeController) DeleteServiceAccountTokenFunc() func(typ
|
||||
}
|
||||
}
|
||||
|
||||
func (adc *PersistentVolumeController) GetExec(pluginName string) mount.Exec {
|
||||
return mount.NewOSExec()
|
||||
func (adc *PersistentVolumeController) GetExec(pluginName string) utilexec.Interface {
|
||||
return utilexec.New()
|
||||
}
|
||||
|
||||
func (ctrl *PersistentVolumeController) GetNodeLabels() (map[string]string, error) {
|
||||
|
@ -34,6 +34,8 @@ import (
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/kubelet/configmap"
|
||||
"k8s.io/kubernetes/pkg/kubelet/secret"
|
||||
@ -86,7 +88,7 @@ func NewInitializedVolumePluginMgr(
|
||||
informerFactory: informerFactory,
|
||||
csiDriverLister: csiDriverLister,
|
||||
csiDriversSynced: csiDriversSynced,
|
||||
exec: mount.NewOSExec(),
|
||||
exec: utilexec.New(),
|
||||
}
|
||||
|
||||
if err := kvh.volumePluginMgr.InitPlugins(plugins, prober, kvh); err != nil {
|
||||
@ -115,7 +117,7 @@ type kubeletVolumeHost struct {
|
||||
informerFactory informers.SharedInformerFactory
|
||||
csiDriverLister storagelisters.CSIDriverLister
|
||||
csiDriversSynced cache.InformerSynced
|
||||
exec mount.Exec
|
||||
exec utilexec.Interface
|
||||
}
|
||||
|
||||
func (kvh *kubeletVolumeHost) SetKubeletError(err error) {
|
||||
@ -271,6 +273,6 @@ func (kvh *kubeletVolumeHost) GetEventRecorder() record.EventRecorder {
|
||||
return kvh.kubelet.recorder
|
||||
}
|
||||
|
||||
func (kvh *kubeletVolumeHost) GetExec(pluginName string) mount.Exec {
|
||||
func (kvh *kubeletVolumeHost) GetExec(pluginName string) utilexec.Interface {
|
||||
return kvh.exec
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"exec.go",
|
||||
"fake_exec.go",
|
||||
"fake_mounter.go",
|
||||
"mount.go",
|
||||
@ -75,6 +74,7 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec/testing:go_default_library",
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:windows": [
|
||||
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
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 mount
|
||||
|
||||
import "k8s.io/utils/exec"
|
||||
|
||||
// NewOSExec returns a new Exec interface implementation based on exec()
|
||||
func NewOSExec() *OSExec {
|
||||
return &OSExec{}
|
||||
}
|
||||
|
||||
// OSExec is an implementation of Exec interface that uses simple utils.Exec
|
||||
type OSExec struct{}
|
||||
|
||||
var _ Exec = &OSExec{}
|
||||
|
||||
// Run exucutes the given cmd and arges and returns stdout and stderr as a
|
||||
// combined byte stream
|
||||
func (e *OSExec) Run(cmd string, args ...string) ([]byte, error) {
|
||||
exe := exec.New()
|
||||
return exe.Command(cmd, args...).CombinedOutput()
|
||||
}
|
@ -23,6 +23,8 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
utilexec "k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -53,13 +55,6 @@ type Interface interface {
|
||||
GetMountRefs(pathname string) ([]string, error)
|
||||
}
|
||||
|
||||
// Exec is an interface for executing commands on systems.
|
||||
type Exec interface {
|
||||
// Run executes a command and returns its stdout + stderr combined in one
|
||||
// stream.
|
||||
Run(cmd string, args ...string) ([]byte, error)
|
||||
}
|
||||
|
||||
// Compile-time check to ensure all Mounter implementations satisfy
|
||||
// the mount interface.
|
||||
var _ Interface = &Mounter{}
|
||||
@ -79,7 +74,7 @@ type MountPoint struct {
|
||||
// mounts it otherwise the device is formatted first then mounted.
|
||||
type SafeFormatAndMount struct {
|
||||
Interface
|
||||
Exec
|
||||
Exec utilexec.Interface
|
||||
}
|
||||
|
||||
// FormatAndMount formats the given disk, if needed, and mounts it.
|
||||
|
@ -273,7 +273,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
||||
// Run fsck on the disk to fix repairable issues, only do this for volumes requested as rw.
|
||||
klog.V(4).Infof("Checking for issues with fsck on disk: %s", source)
|
||||
args := []string{"-a", source}
|
||||
out, err := mounter.Exec.Run("fsck", args...)
|
||||
out, err := mounter.Exec.Command("fsck", args...).CombinedOutput()
|
||||
if err != nil {
|
||||
ee, isExitError := err.(utilexec.ExitError)
|
||||
switch {
|
||||
@ -320,7 +320,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
||||
}
|
||||
}
|
||||
klog.Infof("Disk %q appears to be unformatted, attempting to format as type: %q with options: %v", source, fstype, args)
|
||||
_, err := mounter.Exec.Run("mkfs."+fstype, args...)
|
||||
_, err := mounter.Exec.Command("mkfs."+fstype, args...).CombinedOutput()
|
||||
if err == nil {
|
||||
// the disk has been formatted successfully try to mount it again.
|
||||
klog.Infof("Disk successfully formatted (mkfs): %s - %s %s", fstype, source, target)
|
||||
@ -344,7 +344,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
||||
func (mounter *SafeFormatAndMount) GetDiskFormat(disk string) (string, error) {
|
||||
args := []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", disk}
|
||||
klog.V(4).Infof("Attempting to determine if disk %q is formatted using blkid with args: (%v)", disk, args)
|
||||
dataOut, err := mounter.Exec.Run("blkid", args...)
|
||||
dataOut, err := mounter.Exec.Command("blkid", args...).CombinedOutput()
|
||||
output := string(dataOut)
|
||||
klog.V(4).Infof("Output: %q, err: %v", output, err)
|
||||
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/klog"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
"k8s.io/utils/keymutex"
|
||||
utilpath "k8s.io/utils/path"
|
||||
)
|
||||
@ -219,7 +220,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
||||
// format disk if it is unformatted(raw)
|
||||
cmd := fmt.Sprintf("Get-Disk -Number %s | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle MBR -PassThru"+
|
||||
" | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem %s -Confirm:$false", source, fstype)
|
||||
if output, err := mounter.Exec.Run("powershell", "/c", cmd); err != nil {
|
||||
if output, err := mounter.Exec.Command("powershell", "/c", cmd).CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("diskMount: format disk failed, error: %v, output: %q", err, string(output))
|
||||
}
|
||||
klog.V(4).Infof("diskMount: Disk successfully formatted, disk: %q, fstype: %q", source, fstype)
|
||||
@ -231,7 +232,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
||||
driverPath := driveLetter + ":"
|
||||
target = NormalizeWindowsPath(target)
|
||||
klog.V(4).Infof("Attempting to formatAndMount disk: %s %s %s", fstype, driverPath, target)
|
||||
if output, err := mounter.Exec.Run("cmd", "/c", "mklink", "/D", target, driverPath); err != nil {
|
||||
if output, err := mounter.Exec.Command("cmd", "/c", "mklink", "/D", target, driverPath).CombinedOutput(); err != nil {
|
||||
klog.Errorf("mklink failed: %v, output: %q", err, string(output))
|
||||
return err
|
||||
}
|
||||
@ -239,9 +240,9 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
||||
}
|
||||
|
||||
// Get drive letter according to windows disk number
|
||||
func getDriveLetterByDiskNumber(diskNum string, exec Exec) (string, error) {
|
||||
func getDriveLetterByDiskNumber(diskNum string, exec utilexec.Interface) (string, error) {
|
||||
cmd := fmt.Sprintf("(Get-Partition -DiskNumber %s).DriveLetter", diskNum)
|
||||
output, err := exec.Run("powershell", "/c", cmd)
|
||||
output, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("azureMount: Get Drive Letter failed: %v, output: %q", err, string(output))
|
||||
}
|
||||
|
@ -24,10 +24,10 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/utils/exec/testing"
|
||||
)
|
||||
|
||||
func makeLink(link, target string) error {
|
||||
@ -224,61 +224,61 @@ func TestIsLikelyNotMountPoint(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFormatAndMount(t *testing.T) {
|
||||
fakeMounter := ErrorMounter{NewFakeMounter(nil), 0, nil}
|
||||
execCallback := func(cmd string, args ...string) ([]byte, error) {
|
||||
for j := range args {
|
||||
if strings.Contains(args[j], "Get-Disk -Number") {
|
||||
return []byte("0"), nil
|
||||
}
|
||||
|
||||
if strings.Contains(args[j], "Get-Partition -DiskNumber") {
|
||||
return []byte("0"), nil
|
||||
}
|
||||
|
||||
if strings.Contains(args[j], "mklink") {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("Unexpected cmd %s, args %v", cmd, args)
|
||||
}
|
||||
fakeExec := NewFakeExec(execCallback)
|
||||
|
||||
mounter := SafeFormatAndMount{
|
||||
Interface: &fakeMounter,
|
||||
Exec: fakeExec,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
device string
|
||||
target string
|
||||
fstype string
|
||||
execScripts []ExecArgs
|
||||
mountOptions []string
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
"0",
|
||||
"disk",
|
||||
"NTFS",
|
||||
[]string{},
|
||||
false,
|
||||
device: "0",
|
||||
target: "disk",
|
||||
fstype: "NTFS",
|
||||
execScripts: []ExecArgs{
|
||||
{"powershell", []string{"/c", "Get-Disk", "-Number"}, "0", nil},
|
||||
{"powershell", []string{"/c", "Get-Partition", "-DiskNumber"}, "0", nil},
|
||||
{"cmd", []string{"/c", "mklink", "/D"}, "", nil},
|
||||
},
|
||||
mountOptions: []string{},
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
"0",
|
||||
"disk",
|
||||
"",
|
||||
[]string{},
|
||||
false,
|
||||
device: "0",
|
||||
target: "disk",
|
||||
fstype: "",
|
||||
execScripts: []ExecArgs{
|
||||
{"powershell", []string{"/c", "Get-Disk", "-Number"}, "0", nil},
|
||||
{"powershell", []string{"/c", "Get-Partition", "-DiskNumber"}, "0", nil},
|
||||
{"cmd", []string{"/c", "mklink", "/D"}, "", nil},
|
||||
},
|
||||
mountOptions: []string{},
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
"invalidDevice",
|
||||
"disk",
|
||||
"NTFS",
|
||||
[]string{},
|
||||
true,
|
||||
device: "invalidDevice",
|
||||
target: "disk",
|
||||
fstype: "NTFS",
|
||||
mountOptions: []string{},
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
fakeMounter := ErrorMounter{NewFakeMounter(nil), 0, nil}
|
||||
fakeExec := &testingexec.FakeExec{}
|
||||
for _, script := range test.execScripts {
|
||||
fakeCmd := &testingexec.FakeCmd{}
|
||||
cmdAction := makeFakeCmd(fakeCmd, script.command, script.args...)
|
||||
outputAction := makeFakeOutput(script.output, script.err)
|
||||
fakeCmd.CombinedOutputScript = append(fakeCmd.CombinedOutputScript, outputAction)
|
||||
fakeExec.CommandScript = append(fakeExec.CommandScript, cmdAction)
|
||||
}
|
||||
mounter := SafeFormatAndMount{
|
||||
Interface: &fakeMounter,
|
||||
Exec: fakeExec,
|
||||
}
|
||||
base, err := ioutil.TempDir("", test.device)
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
|
@ -24,7 +24,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
fakeexec "k8s.io/utils/exec/testing"
|
||||
"k8s.io/utils/exec"
|
||||
"k8s.io/utils/exec/testing"
|
||||
)
|
||||
|
||||
type ErrorMounter struct {
|
||||
@ -82,7 +83,7 @@ func TestSafeFormatAndMount(t *testing.T) {
|
||||
description: "Test 'fsck' fails with exit status 4",
|
||||
fstype: "ext4",
|
||||
execScripts: []ExecArgs{
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", &fakeexec.FakeExitError{Status: 4}},
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", &testingexec.FakeExitError{Status: 4}},
|
||||
},
|
||||
expectedError: fmt.Errorf("'fsck' found errors on device /dev/foo but could not correct them"),
|
||||
},
|
||||
@ -90,14 +91,14 @@ func TestSafeFormatAndMount(t *testing.T) {
|
||||
description: "Test 'fsck' fails with exit status 1 (errors found and corrected)",
|
||||
fstype: "ext4",
|
||||
execScripts: []ExecArgs{
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", &fakeexec.FakeExitError{Status: 1}},
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", &testingexec.FakeExitError{Status: 1}},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Test 'fsck' fails with exit status other than 1 and 4 (likely unformatted device)",
|
||||
fstype: "ext4",
|
||||
execScripts: []ExecArgs{
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", &fakeexec.FakeExitError{Status: 8}},
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", &testingexec.FakeExitError{Status: 8}},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -116,7 +117,7 @@ func TestSafeFormatAndMount(t *testing.T) {
|
||||
mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'")},
|
||||
execScripts: []ExecArgs{
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", nil},
|
||||
{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", &fakeexec.FakeExitError{Status: 2}},
|
||||
{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", &testingexec.FakeExitError{Status: 2}},
|
||||
{"mkfs.ext4", []string{"-F", "-m0", "/dev/foo"}, "", fmt.Errorf("formatting failed")},
|
||||
},
|
||||
expectedError: fmt.Errorf("formatting failed"),
|
||||
@ -127,7 +128,7 @@ func TestSafeFormatAndMount(t *testing.T) {
|
||||
mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), fmt.Errorf("Still cannot mount")},
|
||||
execScripts: []ExecArgs{
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", nil},
|
||||
{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", &fakeexec.FakeExitError{Status: 2}},
|
||||
{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", &testingexec.FakeExitError{Status: 2}},
|
||||
{"mkfs.ext4", []string{"-F", "-m0", "/dev/foo"}, "", nil},
|
||||
},
|
||||
expectedError: fmt.Errorf("Still cannot mount"),
|
||||
@ -138,7 +139,7 @@ func TestSafeFormatAndMount(t *testing.T) {
|
||||
mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), nil},
|
||||
execScripts: []ExecArgs{
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", nil},
|
||||
{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", &fakeexec.FakeExitError{Status: 2}},
|
||||
{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", &testingexec.FakeExitError{Status: 2}},
|
||||
{"mkfs.ext4", []string{"-F", "-m0", "/dev/foo"}, "", nil},
|
||||
},
|
||||
expectedError: nil,
|
||||
@ -149,7 +150,7 @@ func TestSafeFormatAndMount(t *testing.T) {
|
||||
mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), nil},
|
||||
execScripts: []ExecArgs{
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", nil},
|
||||
{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", &fakeexec.FakeExitError{Status: 2}},
|
||||
{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", &testingexec.FakeExitError{Status: 2}},
|
||||
{"mkfs.ext3", []string{"-F", "-m0", "/dev/foo"}, "", nil},
|
||||
},
|
||||
expectedError: nil,
|
||||
@ -160,7 +161,7 @@ func TestSafeFormatAndMount(t *testing.T) {
|
||||
mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), nil},
|
||||
execScripts: []ExecArgs{
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", nil},
|
||||
{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", &fakeexec.FakeExitError{Status: 2}},
|
||||
{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", &testingexec.FakeExitError{Status: 2}},
|
||||
{"mkfs.xfs", []string{"/dev/foo"}, "", nil},
|
||||
},
|
||||
expectedError: nil,
|
||||
@ -181,7 +182,7 @@ func TestSafeFormatAndMount(t *testing.T) {
|
||||
mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), nil},
|
||||
execScripts: []ExecArgs{
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", nil},
|
||||
{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", &fakeexec.FakeExitError{Status: 4}},
|
||||
{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", &testingexec.FakeExitError{Status: 4}},
|
||||
{"mkfs.xfs", []string{"/dev/foo"}, "", nil},
|
||||
},
|
||||
expectedError: fmt.Errorf("exit 4"),
|
||||
@ -189,27 +190,15 @@ func TestSafeFormatAndMount(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
execCallCount := 0
|
||||
execCallback := func(cmd string, args ...string) ([]byte, error) {
|
||||
if len(test.execScripts) <= execCallCount {
|
||||
t.Errorf("Unexpected command: %s %v", cmd, args)
|
||||
return nil, nil
|
||||
}
|
||||
script := test.execScripts[execCallCount]
|
||||
execCallCount++
|
||||
if script.command != cmd {
|
||||
t.Errorf("Unexpected command %s. Expecting %s", cmd, script.command)
|
||||
}
|
||||
for j := range args {
|
||||
if args[j] != script.args[j] {
|
||||
t.Errorf("Unexpected args %v. Expecting %v", args, script.args)
|
||||
}
|
||||
}
|
||||
return []byte(script.output), script.err
|
||||
}
|
||||
|
||||
fakeMounter := ErrorMounter{NewFakeMounter(nil), 0, test.mountErrs}
|
||||
fakeExec := NewFakeExec(execCallback)
|
||||
fakeExec := &testingexec.FakeExec{ExactOrder: true}
|
||||
for _, script := range test.execScripts {
|
||||
fakeCmd := &testingexec.FakeCmd{}
|
||||
cmdAction := makeFakeCmd(fakeCmd, script.command, script.args...)
|
||||
outputAction := makeFakeOutput(script.output, script.err)
|
||||
fakeCmd.CombinedOutputScript = append(fakeCmd.CombinedOutputScript, outputAction)
|
||||
fakeExec.CommandScript = append(fakeExec.CommandScript, cmdAction)
|
||||
}
|
||||
mounter := SafeFormatAndMount{
|
||||
Interface: &fakeMounter,
|
||||
Exec: fakeExec,
|
||||
@ -241,3 +230,19 @@ func TestSafeFormatAndMount(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makeFakeCmd(fakeCmd *testingexec.FakeCmd, cmd string, args ...string) testingexec.FakeCommandAction {
|
||||
c := cmd
|
||||
a := args
|
||||
return func(cmd string, args ...string) exec.Cmd {
|
||||
command := testingexec.InitFakeCmd(fakeCmd, c, a...)
|
||||
return command
|
||||
}
|
||||
}
|
||||
|
||||
func makeFakeOutput(output string, err error) testingexec.FakeCombinedOutputAction {
|
||||
o := output
|
||||
return func() ([]byte, error) {
|
||||
return []byte(o), err
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func (resizefs *ResizeFs) Resize(devicePath string, deviceMountPath string) (boo
|
||||
}
|
||||
|
||||
func (resizefs *ResizeFs) extResize(devicePath string) (bool, error) {
|
||||
output, err := resizefs.mounter.Exec.Run("resize2fs", devicePath)
|
||||
output, err := resizefs.mounter.Exec.Command("resize2fs", devicePath).CombinedOutput()
|
||||
if err == nil {
|
||||
klog.V(2).Infof("Device %s resized successfully", devicePath)
|
||||
return true, nil
|
||||
@ -74,7 +74,7 @@ func (resizefs *ResizeFs) extResize(devicePath string) (bool, error) {
|
||||
|
||||
func (resizefs *ResizeFs) xfsResize(deviceMountPath string) (bool, error) {
|
||||
args := []string{"-d", deviceMountPath}
|
||||
output, err := resizefs.mounter.Exec.Run("xfs_growfs", args...)
|
||||
output, err := resizefs.mounter.Exec.Command("xfs_growfs", args...).CombinedOutput()
|
||||
|
||||
if err == nil {
|
||||
klog.V(2).Infof("Device %s resized successfully", deviceMountPath)
|
||||
|
@ -40,6 +40,7 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/tools/record:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -41,7 +41,7 @@ func (attacher *awsElasticBlockStoreAttacher) getDiskNumber(volumeID string) (st
|
||||
volumeID = split[len(split)-1]
|
||||
|
||||
exec := attacher.host.GetExec(awsElasticBlockStorePluginName)
|
||||
output, err := exec.Run(ebsnvmeID)
|
||||
output, err := exec.Command(ebsnvmeID).CombinedOutput()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error calling ebsnvme-id.exe: %v", err)
|
||||
}
|
||||
|
@ -43,7 +43,45 @@ go_library(
|
||||
"//vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-04-01/storage:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/strings:go_default_library",
|
||||
],
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:android": [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:darwin": [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:dragonfly": [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:freebsd": [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:ios": [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:linux": [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:nacl": [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:netbsd": [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:openbsd": [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:plan9": [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:solaris": [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:windows": [
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
|
||||
filegroup(
|
||||
@ -70,7 +108,6 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/util/mount:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/testing:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
@ -79,5 +116,6 @@ go_test(
|
||||
"//staging/src/k8s.io/client-go/util/testing:go_default_library",
|
||||
"//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -26,7 +26,7 @@ import (
|
||||
libstrings "strings"
|
||||
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
// exclude those used by azure as resource and OS root in /dev/disk/azure
|
||||
@ -69,7 +69,7 @@ func getDiskLinkByDevName(io ioHandler, devLinkPath, devName string) (string, er
|
||||
return "", fmt.Errorf("read %s error: %v", devLinkPath, err)
|
||||
}
|
||||
|
||||
func scsiHostRescan(io ioHandler, exec mount.Exec) {
|
||||
func scsiHostRescan(io ioHandler, exec utilexec.Interface) {
|
||||
scsi_path := "/sys/class/scsi_host/"
|
||||
if dirs, err := io.ReadDir(scsi_path); err == nil {
|
||||
for _, f := range dirs {
|
||||
@ -84,7 +84,7 @@ func scsiHostRescan(io ioHandler, exec mount.Exec) {
|
||||
}
|
||||
}
|
||||
|
||||
func findDiskByLun(lun int, io ioHandler, exec mount.Exec) (string, error) {
|
||||
func findDiskByLun(lun int, io ioHandler, exec utilexec.Interface) (string, error) {
|
||||
azureDisks := listAzureDiskPath(io)
|
||||
return findDiskByLunWithConstraint(lun, io, azureDisks)
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ import (
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
type fakeFileInfo struct {
|
||||
@ -126,7 +125,7 @@ func TestIoHandler(t *testing.T) {
|
||||
if runtime.GOOS != "windows" && runtime.GOOS != "linux" {
|
||||
t.Skipf("TestIoHandler not supported on GOOS=%s", runtime.GOOS)
|
||||
}
|
||||
disk, err := findDiskByLun(lun, &fakeIOHandler{}, mount.NewOSExec())
|
||||
disk, err := findDiskByLun(lun, &fakeIOHandler{}, exec.New())
|
||||
if runtime.GOOS == "windows" {
|
||||
if err != nil {
|
||||
t.Errorf("no data disk found: disk %v err %v", disk, err)
|
||||
|
@ -19,11 +19,11 @@ limitations under the License.
|
||||
|
||||
package azure_dd
|
||||
|
||||
import "k8s.io/kubernetes/pkg/util/mount"
|
||||
import "k8s.io/utils/exec"
|
||||
|
||||
func scsiHostRescan(io ioHandler, exec mount.Exec) {
|
||||
func scsiHostRescan(io ioHandler, exec exec.Interface) {
|
||||
}
|
||||
|
||||
func findDiskByLun(lun int, io ioHandler, exec mount.Exec) (string, error) {
|
||||
func findDiskByLun(lun int, io ioHandler, exec exec.Interface) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
@ -26,22 +26,23 @@ import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/klog"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
)
|
||||
|
||||
func scsiHostRescan(io ioHandler, exec mount.Exec) {
|
||||
func scsiHostRescan(io ioHandler, exec utilexec.Interface) {
|
||||
cmd := "Update-HostStorageCache"
|
||||
output, err := exec.Run("powershell", "/c", cmd)
|
||||
output, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
|
||||
if err != nil {
|
||||
klog.Errorf("Update-HostStorageCache failed in scsiHostRescan, error: %v, output: %q", err, string(output))
|
||||
}
|
||||
}
|
||||
|
||||
// search Windows disk number by LUN
|
||||
func findDiskByLun(lun int, iohandler ioHandler, exec mount.Exec) (string, error) {
|
||||
func findDiskByLun(lun int, iohandler ioHandler, exec utilexec.Interface) (string, error) {
|
||||
cmd := `Get-Disk | select number, location | ConvertTo-Json`
|
||||
output, err := exec.Run("powershell", "/c", cmd)
|
||||
output, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
|
||||
if err != nil {
|
||||
klog.Errorf("Get-Disk failed in findDiskByLun, error: %v, output: %q", err, string(output))
|
||||
return "", err
|
||||
@ -98,7 +99,7 @@ func findDiskByLun(lun int, iohandler ioHandler, exec mount.Exec) (string, error
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func formatIfNotFormatted(disk string, fstype string, exec mount.Exec) {
|
||||
func formatIfNotFormatted(disk string, fstype string, exec utilexec.Interface) {
|
||||
if err := mount.ValidateDiskNumber(disk); err != nil {
|
||||
klog.Errorf("azureDisk Mount: formatIfNotFormatted failed, err: %v\n", err)
|
||||
return
|
||||
@ -110,7 +111,7 @@ func formatIfNotFormatted(disk string, fstype string, exec mount.Exec) {
|
||||
}
|
||||
cmd := fmt.Sprintf("Get-Disk -Number %s | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle MBR -PassThru", disk)
|
||||
cmd += fmt.Sprintf(" | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem %s -Confirm:$false", fstype)
|
||||
output, err := exec.Run("powershell", "/c", cmd)
|
||||
output, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
|
||||
if err != nil {
|
||||
klog.Errorf("azureDisk Mount: Get-Disk failed, error: %v, output: %q", err, string(output))
|
||||
} else {
|
||||
|
@ -331,7 +331,7 @@ func (cephfsVolume *cephfsMounter) checkFuseMount() bool {
|
||||
execute := cephfsVolume.plugin.host.GetExec(cephfsVolume.plugin.GetPluginName())
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
if _, err := execute.Run("/usr/bin/test", "-x", "/sbin/mount.fuse.ceph"); err == nil {
|
||||
if _, err := execute.Command("/usr/bin/test", "-x", "/sbin/mount.fuse.ceph").CombinedOutput(); err == nil {
|
||||
klog.V(4).Info("/sbin/mount.fuse.ceph exists, it should be fuse mount.")
|
||||
return true
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ go_library(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
"//vendor/k8s.io/utils/strings:go_default_library",
|
||||
],
|
||||
)
|
||||
@ -48,6 +49,7 @@ go_test(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/util/testing:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -28,6 +28,8 @@ import (
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/klog"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
@ -114,7 +116,7 @@ func (plugin *fcPlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ volume.Volu
|
||||
return plugin.newMounterInternal(spec, pod.UID, &fcUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()))
|
||||
}
|
||||
|
||||
func (plugin *fcPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, exec mount.Exec) (volume.Mounter, error) {
|
||||
func (plugin *fcPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, exec utilexec.Interface) (volume.Mounter, error) {
|
||||
// fc volumes used directly in a pod have a ReadOnly flag set by the pod author.
|
||||
// fc volumes used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV
|
||||
fc, readOnly, err := getVolumeSource(spec)
|
||||
@ -174,7 +176,7 @@ func (plugin *fcPlugin) NewBlockVolumeMapper(spec *volume.Spec, pod *v1.Pod, _ v
|
||||
return plugin.newBlockVolumeMapperInternal(spec, uid, &fcUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()))
|
||||
}
|
||||
|
||||
func (plugin *fcPlugin) newBlockVolumeMapperInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, exec mount.Exec) (volume.BlockVolumeMapper, error) {
|
||||
func (plugin *fcPlugin) newBlockVolumeMapperInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, exec utilexec.Interface) (volume.BlockVolumeMapper, error) {
|
||||
fc, readOnly, err := getVolumeSource(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -29,6 +29,8 @@ import (
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
utiltesting "k8s.io/client-go/util/testing"
|
||||
"k8s.io/utils/exec/testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||
@ -164,7 +166,7 @@ func doTestPlugin(t *testing.T, spec *volume.Spec) {
|
||||
fakeManager := newFakeDiskManager()
|
||||
defer fakeManager.Cleanup()
|
||||
fakeMounter := mount.NewFakeMounter(nil)
|
||||
fakeExec := mount.NewFakeExec(nil)
|
||||
fakeExec := &testingexec.FakeExec{}
|
||||
mounter, err := plug.(*fcPlugin).newMounterInternal(spec, types.UID("poduid"), fakeManager, fakeMounter, fakeExec)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||
@ -227,7 +229,7 @@ func doTestPluginNilMounter(t *testing.T, spec *volume.Spec) {
|
||||
fakeManager := newFakeDiskManager()
|
||||
defer fakeManager.Cleanup()
|
||||
fakeMounter := mount.NewFakeMounter(nil)
|
||||
fakeExec := mount.NewFakeExec(nil)
|
||||
fakeExec := &testingexec.FakeExec{}
|
||||
mounter, err := plug.(*fcPlugin).newMounterInternal(spec, types.UID("poduid"), fakeManager, fakeMounter, fakeExec)
|
||||
if err == nil {
|
||||
t.Errorf("Error failed to make a new Mounter is expected: %v", err)
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
volumetesting "k8s.io/kubernetes/pkg/volume/testing"
|
||||
"k8s.io/kubernetes/test/utils/harness"
|
||||
"k8s.io/utils/exec"
|
||||
fakeexec "k8s.io/utils/exec/testing"
|
||||
"k8s.io/utils/exec/testing"
|
||||
)
|
||||
|
||||
func testPlugin(h *harness.Harness) (*flexVolumeAttachablePlugin, string) {
|
||||
@ -39,7 +39,7 @@ func testPlugin(h *harness.Harness) (*flexVolumeAttachablePlugin, string) {
|
||||
}, rootDir
|
||||
}
|
||||
|
||||
func assertDriverCall(t *harness.Harness, output fakeexec.FakeCombinedOutputAction, expectedCommand string, expectedArgs ...string) fakeexec.FakeCommandAction {
|
||||
func assertDriverCall(t *harness.Harness, output testingexec.FakeCombinedOutputAction, expectedCommand string, expectedArgs ...string) testingexec.FakeCommandAction {
|
||||
return func(cmd string, args ...string) exec.Cmd {
|
||||
if cmd != "/plugin/test" {
|
||||
t.Errorf("Wrong executable called: got %v, expected %v", cmd, "/plugin/test")
|
||||
@ -51,20 +51,20 @@ func assertDriverCall(t *harness.Harness, output fakeexec.FakeCombinedOutputActi
|
||||
if !sameArgs(cmdArgs, expectedArgs) {
|
||||
t.Errorf("Wrong args for %s: got %v, expected %v", args[0], cmdArgs, expectedArgs)
|
||||
}
|
||||
return &fakeexec.FakeCmd{
|
||||
return &testingexec.FakeCmd{
|
||||
Argv: args,
|
||||
CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{output},
|
||||
CombinedOutputScript: []testingexec.FakeCombinedOutputAction{output},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func fakeRunner(fakeCommands ...fakeexec.FakeCommandAction) exec.Interface {
|
||||
return &fakeexec.FakeExec{
|
||||
func fakeRunner(fakeCommands ...testingexec.FakeCommandAction) exec.Interface {
|
||||
return &testingexec.FakeExec{
|
||||
CommandScript: fakeCommands,
|
||||
}
|
||||
}
|
||||
|
||||
func fakeResultOutput(result interface{}) fakeexec.FakeCombinedOutputAction {
|
||||
func fakeResultOutput(result interface{}) testingexec.FakeCombinedOutputAction {
|
||||
return func() ([]byte, error) {
|
||||
bytes, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
@ -74,11 +74,11 @@ func fakeResultOutput(result interface{}) fakeexec.FakeCombinedOutputAction {
|
||||
}
|
||||
}
|
||||
|
||||
func successOutput() fakeexec.FakeCombinedOutputAction {
|
||||
func successOutput() testingexec.FakeCombinedOutputAction {
|
||||
return fakeResultOutput(&DriverStatus{StatusSuccess, "", "", "", true, nil, 0})
|
||||
}
|
||||
|
||||
func notSupportedOutput() fakeexec.FakeCombinedOutputAction {
|
||||
func notSupportedOutput() testingexec.FakeCombinedOutputAction {
|
||||
return fakeResultOutput(&DriverStatus{StatusNotSupported, "", "", "", false, nil, 0})
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/test/utils/harness"
|
||||
exec "k8s.io/utils/exec/testing"
|
||||
"k8s.io/utils/exec/testing"
|
||||
)
|
||||
|
||||
func TestInit(tt *testing.T) {
|
||||
@ -34,7 +34,7 @@ func TestInit(tt *testing.T) {
|
||||
plugin.Init(plugin.host)
|
||||
}
|
||||
|
||||
func fakeVolumeNameOutput(name string) exec.FakeCombinedOutputAction {
|
||||
func fakeVolumeNameOutput(name string) testingexec.FakeCombinedOutputAction {
|
||||
return fakeResultOutput(&DriverStatus{
|
||||
Status: StatusSuccess,
|
||||
VolumeName: name,
|
||||
|
@ -33,6 +33,8 @@ import (
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/klog"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
@ -179,10 +181,10 @@ func (attacher *gcePersistentDiskAttacher) BulkVerifyVolumes(volumesByNode map[t
|
||||
}
|
||||
|
||||
// search Windows disk number by LUN
|
||||
func getDiskID(pdName string, exec mount.Exec) (string, error) {
|
||||
func getDiskID(pdName string, exec utilexec.Interface) (string, error) {
|
||||
// TODO: replace Get-GcePdName with native windows support of Get-Disk, see issue #74674
|
||||
cmd := `Get-GcePdName | select Name, DeviceId | ConvertTo-Json`
|
||||
output, err := exec.Run("powershell", "/c", cmd)
|
||||
output, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
|
||||
if err != nil {
|
||||
klog.Errorf("Get-GcePdName failed, error: %v, output: %q", err, string(output))
|
||||
err = errors.New(err.Error() + " " + string(output))
|
||||
|
@ -264,7 +264,7 @@ func (b *glusterfsMounter) CanMount() error {
|
||||
exe := b.plugin.host.GetExec(b.plugin.GetPluginName())
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
if _, err := exe.Run("test", "-x", gciLinuxGlusterMountBinaryPath); err != nil {
|
||||
if _, err := exe.Command("test", "-x", gciLinuxGlusterMountBinaryPath).CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("required binary %s is missing", gciLinuxGlusterMountBinaryPath)
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ go_test(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/util/testing:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -27,6 +27,8 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/klog"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
ioutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
@ -110,7 +112,7 @@ func (plugin *iscsiPlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ volume.V
|
||||
return plugin.newMounterInternal(spec, pod.UID, &ISCSIUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()), secret)
|
||||
}
|
||||
|
||||
func (plugin *iscsiPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, exec mount.Exec, secret map[string]string) (volume.Mounter, error) {
|
||||
func (plugin *iscsiPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, exec utilexec.Interface, secret map[string]string) (volume.Mounter, error) {
|
||||
readOnly, fsType, err := getISCSIVolumeInfo(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -153,7 +155,7 @@ func (plugin *iscsiPlugin) NewBlockVolumeMapper(spec *volume.Spec, pod *v1.Pod,
|
||||
return plugin.newBlockVolumeMapperInternal(spec, uid, &ISCSIUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()), secret)
|
||||
}
|
||||
|
||||
func (plugin *iscsiPlugin) newBlockVolumeMapperInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, exec mount.Exec, secret map[string]string) (volume.BlockVolumeMapper, error) {
|
||||
func (plugin *iscsiPlugin) newBlockVolumeMapperInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, exec utilexec.Interface, secret map[string]string) (volume.BlockVolumeMapper, error) {
|
||||
readOnly, _, err := getISCSIVolumeInfo(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -174,7 +176,7 @@ func (plugin *iscsiPlugin) NewUnmounter(volName string, podUID types.UID) (volum
|
||||
return plugin.newUnmounterInternal(volName, podUID, &ISCSIUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()))
|
||||
}
|
||||
|
||||
func (plugin *iscsiPlugin) newUnmounterInternal(volName string, podUID types.UID, manager diskManager, mounter mount.Interface, exec mount.Exec) (volume.Unmounter, error) {
|
||||
func (plugin *iscsiPlugin) newUnmounterInternal(volName string, podUID types.UID, manager diskManager, mounter mount.Interface, exec utilexec.Interface) (volume.Unmounter, error) {
|
||||
return &iscsiDiskUnmounter{
|
||||
iscsiDisk: &iscsiDisk{
|
||||
podUID: podUID,
|
||||
@ -194,7 +196,7 @@ func (plugin *iscsiPlugin) NewBlockVolumeUnmapper(volName string, podUID types.U
|
||||
return plugin.newUnmapperInternal(volName, podUID, &ISCSIUtil{}, plugin.host.GetExec(plugin.GetPluginName()))
|
||||
}
|
||||
|
||||
func (plugin *iscsiPlugin) newUnmapperInternal(volName string, podUID types.UID, manager diskManager, exec mount.Exec) (volume.BlockVolumeUnmapper, error) {
|
||||
func (plugin *iscsiPlugin) newUnmapperInternal(volName string, podUID types.UID, manager diskManager, exec utilexec.Interface) (volume.BlockVolumeUnmapper, error) {
|
||||
return &iscsiDiskUnmapper{
|
||||
iscsiDisk: &iscsiDisk{
|
||||
podUID: podUID,
|
||||
@ -318,7 +320,7 @@ type iscsiDiskMounter struct {
|
||||
fsType string
|
||||
volumeMode v1.PersistentVolumeMode
|
||||
mounter *mount.SafeFormatAndMount
|
||||
exec mount.Exec
|
||||
exec utilexec.Interface
|
||||
deviceUtil ioutil.DeviceUtil
|
||||
mountOptions []string
|
||||
}
|
||||
@ -356,7 +358,7 @@ func (b *iscsiDiskMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) e
|
||||
type iscsiDiskUnmounter struct {
|
||||
*iscsiDisk
|
||||
mounter mount.Interface
|
||||
exec mount.Exec
|
||||
exec utilexec.Interface
|
||||
deviceUtil ioutil.DeviceUtil
|
||||
}
|
||||
|
||||
@ -376,7 +378,7 @@ func (c *iscsiDiskUnmounter) TearDownAt(dir string) error {
|
||||
type iscsiDiskMapper struct {
|
||||
*iscsiDisk
|
||||
readOnly bool
|
||||
exec mount.Exec
|
||||
exec utilexec.Interface
|
||||
deviceUtil ioutil.DeviceUtil
|
||||
}
|
||||
|
||||
@ -392,7 +394,7 @@ func (b *iscsiDiskMapper) MapDevice(devicePath, globalMapPath, volumeMapPath, vo
|
||||
|
||||
type iscsiDiskUnmapper struct {
|
||||
*iscsiDisk
|
||||
exec mount.Exec
|
||||
exec utilexec.Interface
|
||||
deviceUtil ioutil.DeviceUtil
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,8 @@ import (
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
utiltesting "k8s.io/client-go/util/testing"
|
||||
"k8s.io/utils/exec/testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||
@ -160,7 +162,7 @@ func doTestPlugin(t *testing.T, spec *volume.Spec) {
|
||||
fakeManager := NewFakeDiskManager()
|
||||
defer fakeManager.Cleanup()
|
||||
fakeMounter := mount.NewFakeMounter(nil)
|
||||
fakeExec := mount.NewFakeExec(nil)
|
||||
fakeExec := &testingexec.FakeExec{}
|
||||
mounter, err := plug.(*iscsiPlugin).newMounterInternal(spec, types.UID("poduid"), fakeManager, fakeMounter, fakeExec, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -96,7 +97,7 @@ func updateISCSIDiscoverydb(b iscsiDiskMounter, tp string) error {
|
||||
v := b.secret[k]
|
||||
if len(v) > 0 {
|
||||
// explicitly not using execWithLog so secrets are not logged
|
||||
out, err := b.exec.Run("iscsiadm", "-m", "discoverydb", "-t", "sendtargets", "-p", tp, "-I", b.Iface, "-o", "update", "-n", k, "-v", v)
|
||||
out, err := b.exec.Command("iscsiadm", "-m", "discoverydb", "-t", "sendtargets", "-p", tp, "-I", b.Iface, "-o", "update", "-n", k, "-v", v).CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("iscsi: failed to update discoverydb key %q error: %v", k, string(out))
|
||||
}
|
||||
@ -119,7 +120,7 @@ func updateISCSINode(b iscsiDiskMounter, tp string) error {
|
||||
v := b.secret[k]
|
||||
if len(v) > 0 {
|
||||
// explicitly not using execWithLog so secrets are not logged
|
||||
out, err := b.exec.Run("iscsiadm", "-m", "node", "-p", tp, "-T", b.Iqn, "-I", b.Iface, "-o", "update", "-n", k, "-v", v)
|
||||
out, err := b.exec.Command("iscsiadm", "-m", "node", "-p", tp, "-T", b.Iqn, "-I", b.Iface, "-o", "update", "-n", k, "-v", v).CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("iscsi: failed to update node session key %q error: %v", k, string(out))
|
||||
}
|
||||
@ -561,7 +562,7 @@ func deleteDevices(c iscsiDiskUnmounter) error {
|
||||
}
|
||||
// Flush any multipath device maps
|
||||
for mpathDevice := range mpathDevices {
|
||||
_, err = c.exec.Run("multipath", "-f", mpathDevice)
|
||||
_, err = c.exec.Command("multipath", "-f", mpathDevice).CombinedOutput()
|
||||
if err != nil {
|
||||
klog.Warningf("Warning: Failed to flush multipath device map: %s\nError: %v", mpathDevice, err)
|
||||
// Fall through -- keep deleting the block devices
|
||||
@ -722,7 +723,7 @@ func (util *ISCSIUtil) DetachBlockISCSIDisk(c iscsiDiskUnmapper, mapPath string)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (util *ISCSIUtil) detachISCSIDisk(exec mount.Exec, portals []string, iqn, iface, volName, initiatorName string, found bool) error {
|
||||
func (util *ISCSIUtil) detachISCSIDisk(exec utilexec.Interface, portals []string, iqn, iface, volName, initiatorName string, found bool) error {
|
||||
for _, portal := range portals {
|
||||
logoutArgs := []string{"-m", "node", "-p", portal, "-T", iqn, "--logout"}
|
||||
deleteArgs := []string{"-m", "node", "-p", portal, "-T", iqn, "-o", "delete"}
|
||||
@ -731,7 +732,7 @@ func (util *ISCSIUtil) detachISCSIDisk(exec mount.Exec, portals []string, iqn, i
|
||||
deleteArgs = append(deleteArgs, []string{"-I", iface}...)
|
||||
}
|
||||
klog.Infof("iscsi: log out target %s iqn %s iface %s", portal, iqn, iface)
|
||||
out, err := exec.Run("iscsiadm", logoutArgs...)
|
||||
out, err := exec.Command("iscsiadm", logoutArgs...).CombinedOutput()
|
||||
err = ignoreExitCodes(err, exit_ISCSI_ERR_NO_OBJS_FOUND, exit_ISCSI_ERR_SESS_NOT_FOUND)
|
||||
if err != nil {
|
||||
klog.Errorf("iscsi: failed to detach disk Error: %s", string(out))
|
||||
@ -739,7 +740,7 @@ func (util *ISCSIUtil) detachISCSIDisk(exec mount.Exec, portals []string, iqn, i
|
||||
}
|
||||
// Delete the node record
|
||||
klog.Infof("iscsi: delete node record target %s iqn %s", portal, iqn)
|
||||
out, err = exec.Run("iscsiadm", deleteArgs...)
|
||||
out, err = exec.Command("iscsiadm", deleteArgs...).CombinedOutput()
|
||||
err = ignoreExitCodes(err, exit_ISCSI_ERR_NO_OBJS_FOUND, exit_ISCSI_ERR_SESS_NOT_FOUND)
|
||||
if err != nil {
|
||||
klog.Errorf("iscsi: failed to delete node record Error: %s", string(out))
|
||||
@ -750,7 +751,7 @@ func (util *ISCSIUtil) detachISCSIDisk(exec mount.Exec, portals []string, iqn, i
|
||||
// If the iface is not created via iscsi plugin, skip to delete
|
||||
if initiatorName != "" && found && iface == (portals[0]+":"+volName) {
|
||||
deleteArgs := []string{"-m", "iface", "-I", iface, "-o", "delete"}
|
||||
out, err := exec.Run("iscsiadm", deleteArgs...)
|
||||
out, err := exec.Command("iscsiadm", deleteArgs...).CombinedOutput()
|
||||
err = ignoreExitCodes(err, exit_ISCSI_ERR_NO_OBJS_FOUND, exit_ISCSI_ERR_SESS_NOT_FOUND)
|
||||
if err != nil {
|
||||
klog.Errorf("iscsi: failed to delete iface Error: %s", string(out))
|
||||
@ -884,9 +885,15 @@ func cloneIface(b iscsiDiskMounter) error {
|
||||
return lastErr
|
||||
}
|
||||
}
|
||||
// Get and sort keys to maintain a stable iteration order
|
||||
var keys []string
|
||||
for k := range params {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
// update new iface records
|
||||
for key, val := range params {
|
||||
_, err = execWithLog(b, "iscsiadm", "-m", "iface", "-I", b.Iface, "-o", "update", "-n", key, "-v", val)
|
||||
for _, key := range keys {
|
||||
_, err = execWithLog(b, "iscsiadm", "-m", "iface", "-I", b.Iface, "-o", "update", "-n", key, "-v", params[key])
|
||||
if err != nil {
|
||||
execWithLog(b, "iscsiadm", "-m", "iface", "-I", b.Iface, "-o", "delete")
|
||||
lastErr = fmt.Errorf("iscsi: failed to update iface records: %s (%v). iface(%s) will be used", out, err, b.InitIface)
|
||||
@ -965,7 +972,7 @@ func ignoreExitCodes(err error, ignoredExitCodes ...int) error {
|
||||
|
||||
func execWithLog(b iscsiDiskMounter, cmd string, args ...string) (string, error) {
|
||||
start := time.Now()
|
||||
out, err := b.exec.Run(cmd, args...)
|
||||
out, err := b.exec.Command(cmd, args...).CombinedOutput()
|
||||
if klog.V(5) {
|
||||
d := time.Since(start)
|
||||
klog.V(5).Infof("Executed %s %v in %v, err: %v", cmd, args, d, err)
|
||||
|
@ -17,16 +17,20 @@ limitations under the License.
|
||||
package iscsi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/utils/exec/testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||
)
|
||||
|
||||
const (
|
||||
TestIface = "192.168.1.10:pv0001"
|
||||
)
|
||||
|
||||
func TestExtractDeviceAndPrefix(t *testing.T) {
|
||||
@ -216,28 +220,28 @@ func TestParseIscsiadmShow(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClonedIface(t *testing.T) {
|
||||
cmdCount := 0
|
||||
fakeExec := mount.NewFakeExec(func(cmd string, args ...string) ([]byte, error) {
|
||||
cmdCount++
|
||||
if cmd != "iscsiadm" {
|
||||
t.Errorf("iscsiadm command expected, got %q", cmd)
|
||||
}
|
||||
switch cmdCount {
|
||||
case 1:
|
||||
// iscsiadm -m iface -I <iface> -o show
|
||||
return []byte("iface.ipaddress = <empty>\niface.transport_name = tcp\niface.initiatorname = <empty>\n"), nil
|
||||
|
||||
case 2:
|
||||
// iscsiadm -m iface -I <newIface> -o new
|
||||
return []byte("New interface 192.168.1.10:pv0001 added"), nil
|
||||
case 3:
|
||||
// iscsiadm -m iface -I <newIface> -o update -n <key> -v <val>
|
||||
return []byte(""), nil
|
||||
case 4:
|
||||
return []byte(""), nil
|
||||
}
|
||||
return nil, fmt.Errorf("Unexpected exec call nr %d: %s", cmdCount, cmd)
|
||||
})
|
||||
fakeExec := &testingexec.FakeExec{}
|
||||
scripts := []volumetest.CommandScript{
|
||||
{
|
||||
Cmd: "iscsiadm",
|
||||
Args: []string{"-m", "iface", "-I", "", "-o", "show"},
|
||||
Output: "iface.ipaddress = <empty>\niface.transport_name = tcp\niface.initiatorname = <empty>\n",
|
||||
},
|
||||
{
|
||||
Cmd: "iscsiadm",
|
||||
Args: []string{"-m", "iface", "-I", TestIface, "-o", "new"},
|
||||
},
|
||||
{
|
||||
Cmd: "iscsiadm",
|
||||
Args: []string{"-m", "iface", "-I", TestIface, "-o", "update", "-n", "iface.initiatorname", "-v", ""},
|
||||
},
|
||||
{
|
||||
Cmd: "iscsiadm",
|
||||
Args: []string{"-m", "iface", "-I", TestIface, "-o", "update", "-n", "iface.transport_name", "-v", "tcp"},
|
||||
},
|
||||
}
|
||||
volumetest.ScriptCommands(fakeExec, scripts)
|
||||
fakeExec.ExactOrder = true
|
||||
plugins := []volume.VolumePlugin{
|
||||
&iscsiPlugin{
|
||||
host: nil,
|
||||
@ -246,27 +250,32 @@ func TestClonedIface(t *testing.T) {
|
||||
plugin := plugins[0]
|
||||
fakeMounter := iscsiDiskMounter{
|
||||
iscsiDisk: &iscsiDisk{
|
||||
Iface: "192.168.1.10:pv0001",
|
||||
Iface: TestIface,
|
||||
plugin: plugin.(*iscsiPlugin)},
|
||||
exec: fakeExec,
|
||||
}
|
||||
cloneIface(fakeMounter)
|
||||
if cmdCount != 4 {
|
||||
t.Errorf("expected 4 CombinedOutput() calls, got %d", cmdCount)
|
||||
err := cloneIface(fakeMounter)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if fakeExec.CommandCalls != len(scripts) {
|
||||
t.Errorf("expected 4 CombinedOutput() calls, got %d", fakeExec.CommandCalls)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestClonedIfaceShowError(t *testing.T) {
|
||||
cmdCount := 0
|
||||
fakeExec := mount.NewFakeExec(func(cmd string, args ...string) ([]byte, error) {
|
||||
cmdCount++
|
||||
if cmd != "iscsiadm" {
|
||||
t.Errorf("iscsiadm command expected, got %q", cmd)
|
||||
}
|
||||
// iscsiadm -m iface -I <iface> -o show, return test error
|
||||
return []byte(""), errors.New("test error")
|
||||
})
|
||||
fakeExec := &testingexec.FakeExec{}
|
||||
scripts := []volumetest.CommandScript{
|
||||
{
|
||||
Cmd: "iscsiadm",
|
||||
Args: []string{"-m", "iface", "-I", "", "-o", "show"},
|
||||
Output: "test error",
|
||||
ReturnCode: 1,
|
||||
},
|
||||
}
|
||||
volumetest.ScriptCommands(fakeExec, scripts)
|
||||
fakeExec.ExactOrder = true
|
||||
|
||||
plugins := []volume.VolumePlugin{
|
||||
&iscsiPlugin{
|
||||
host: nil,
|
||||
@ -275,43 +284,49 @@ func TestClonedIfaceShowError(t *testing.T) {
|
||||
plugin := plugins[0]
|
||||
fakeMounter := iscsiDiskMounter{
|
||||
iscsiDisk: &iscsiDisk{
|
||||
Iface: "192.168.1.10:pv0001",
|
||||
Iface: TestIface,
|
||||
plugin: plugin.(*iscsiPlugin)},
|
||||
exec: fakeExec,
|
||||
}
|
||||
cloneIface(fakeMounter)
|
||||
if cmdCount != 1 {
|
||||
t.Errorf("expected 1 CombinedOutput() calls, got %d", cmdCount)
|
||||
err := cloneIface(fakeMounter)
|
||||
if err == nil {
|
||||
t.Errorf("expect to receive error, nil received")
|
||||
}
|
||||
if fakeExec.CommandCalls != len(scripts) {
|
||||
t.Errorf("expected 1 CombinedOutput() calls, got %d", fakeExec.CommandCalls)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestClonedIfaceUpdateError(t *testing.T) {
|
||||
cmdCount := 0
|
||||
fakeExec := mount.NewFakeExec(func(cmd string, args ...string) ([]byte, error) {
|
||||
cmdCount++
|
||||
if cmd != "iscsiadm" {
|
||||
t.Errorf("iscsiadm command expected, got %q", cmd)
|
||||
}
|
||||
switch cmdCount {
|
||||
case 1:
|
||||
// iscsiadm -m iface -I <iface> -o show
|
||||
return []byte("iface.ipaddress = <empty>\niface.transport_name = tcp\niface.initiatorname = <empty>\n"), nil
|
||||
fakeExec := &testingexec.FakeExec{}
|
||||
scripts := []volumetest.CommandScript{
|
||||
{
|
||||
Cmd: "iscsiadm",
|
||||
Args: []string{"-m", "iface", "-I", "", "-o", "show"},
|
||||
Output: "iface.ipaddress = <empty>\niface.transport_name = tcp\niface.initiatorname = <empty>\n",
|
||||
},
|
||||
{
|
||||
Cmd: "iscsiadm",
|
||||
Args: []string{"-m", "iface", "-I", TestIface, "-o", "new"},
|
||||
},
|
||||
{
|
||||
Cmd: "iscsiadm",
|
||||
Args: []string{"-m", "iface", "-I", TestIface, "-o", "update", "-n", "iface.initiatorname", "-v", ""},
|
||||
},
|
||||
{
|
||||
Cmd: "iscsiadm",
|
||||
Args: []string{"-m", "iface", "-I", TestIface, "-o", "update", "-n", "iface.transport_name", "-v", "tcp"},
|
||||
ReturnCode: 1,
|
||||
},
|
||||
{
|
||||
Cmd: "iscsiadm",
|
||||
Args: []string{"-m", "iface", "-I", TestIface, "-o", "delete"},
|
||||
},
|
||||
}
|
||||
volumetest.ScriptCommands(fakeExec, scripts)
|
||||
fakeExec.ExactOrder = true
|
||||
|
||||
case 2:
|
||||
// iscsiadm -m iface -I <newIface> -o new
|
||||
return []byte("New interface 192.168.1.10:pv0001 added"), nil
|
||||
case 3:
|
||||
// iscsiadm -m iface -I <newIface> -o update -n <key> -v <val>
|
||||
return []byte(""), nil
|
||||
case 4:
|
||||
return []byte(""), errors.New("test error")
|
||||
case 5:
|
||||
// iscsiadm -m iface -I <newIface> -o delete
|
||||
return []byte(""), nil
|
||||
}
|
||||
return nil, fmt.Errorf("Unexpected exec call nr %d: %s", cmdCount, cmd)
|
||||
})
|
||||
plugins := []volume.VolumePlugin{
|
||||
&iscsiPlugin{
|
||||
host: nil,
|
||||
@ -320,13 +335,16 @@ func TestClonedIfaceUpdateError(t *testing.T) {
|
||||
plugin := plugins[0]
|
||||
fakeMounter := iscsiDiskMounter{
|
||||
iscsiDisk: &iscsiDisk{
|
||||
Iface: "192.168.1.10:pv0001",
|
||||
Iface: TestIface,
|
||||
plugin: plugin.(*iscsiPlugin)},
|
||||
exec: fakeExec,
|
||||
}
|
||||
cloneIface(fakeMounter)
|
||||
if cmdCount != 5 {
|
||||
t.Errorf("expected 5 CombinedOutput() calls, got %d", cmdCount)
|
||||
err := cloneIface(fakeMounter)
|
||||
if err == nil {
|
||||
t.Errorf("expect to receive error, nil received")
|
||||
}
|
||||
if fakeExec.CommandCalls != len(scripts) {
|
||||
t.Errorf("expected 5 CombinedOutput() calls, got %d", fakeExec.CommandCalls)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -206,15 +206,15 @@ func (nfsMounter *nfsMounter) CanMount() error {
|
||||
exec := nfsMounter.plugin.host.GetExec(nfsMounter.plugin.GetPluginName())
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
if _, err := exec.Run("test", "-x", "/sbin/mount.nfs"); err != nil {
|
||||
if _, err := exec.Command("test", "-x", "/sbin/mount.nfs").CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("Required binary /sbin/mount.nfs is missing")
|
||||
}
|
||||
if _, err := exec.Run("test", "-x", "/sbin/mount.nfs4"); err != nil {
|
||||
if _, err := exec.Command("test", "-x", "/sbin/mount.nfs4").CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("Required binary /sbin/mount.nfs4 is missing")
|
||||
}
|
||||
return nil
|
||||
case "darwin":
|
||||
if _, err := exec.Run("test", "-x", "/sbin/mount_nfs"); err != nil {
|
||||
if _, err := exec.Command("test", "-x", "/sbin/mount_nfs").CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("Required binary /sbin/mount_nfs is missing")
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ import (
|
||||
"k8s.io/client-go/tools/record"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/utils/exec"
|
||||
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/volume/util/hostutil"
|
||||
@ -437,7 +439,7 @@ type VolumeHost interface {
|
||||
DeleteServiceAccountTokenFunc() func(podUID types.UID)
|
||||
|
||||
// Returns an interface that should be used to execute any utilities in volume plugins
|
||||
GetExec(pluginName string) mount.Exec
|
||||
GetExec(pluginName string) exec.Interface
|
||||
|
||||
// Returns the labels on the node
|
||||
GetNodeLabels() (map[string]string, error)
|
||||
|
@ -102,7 +102,7 @@ func (plugin *quobytePlugin) CanSupport(spec *volume.Spec) bool {
|
||||
}
|
||||
|
||||
exec := plugin.host.GetExec(plugin.GetPluginName())
|
||||
if out, err := exec.Run("ls", "/sbin/mount.quobyte"); err == nil {
|
||||
if out, err := exec.Command("ls", "/sbin/mount.quobyte").CombinedOutput(); err == nil {
|
||||
klog.V(4).Infof("quobyte: can support: %s", string(out))
|
||||
return true
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider/volume/helpers:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
"//vendor/k8s.io/utils/path:go_default_library",
|
||||
"//vendor/k8s.io/utils/strings:go_default_library",
|
||||
],
|
||||
|
@ -38,6 +38,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/volume/util"
|
||||
volutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
utilstrings "k8s.io/utils/strings"
|
||||
)
|
||||
|
||||
@ -502,7 +503,7 @@ func (plugin *rbdPlugin) NewBlockVolumeMapper(spec *volume.Spec, pod *v1.Pod, _
|
||||
return plugin.newBlockVolumeMapperInternal(spec, uid, &RBDUtil{}, secret, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()))
|
||||
}
|
||||
|
||||
func (plugin *rbdPlugin) newBlockVolumeMapperInternal(spec *volume.Spec, podUID types.UID, manager diskManager, secret string, mounter mount.Interface, exec mount.Exec) (volume.BlockVolumeMapper, error) {
|
||||
func (plugin *rbdPlugin) newBlockVolumeMapperInternal(spec *volume.Spec, podUID types.UID, manager diskManager, secret string, mounter mount.Interface, exec utilexec.Interface) (volume.BlockVolumeMapper, error) {
|
||||
mon, err := getVolumeSourceMonitors(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -770,7 +771,7 @@ type rbd struct {
|
||||
ReadOnly bool
|
||||
plugin *rbdPlugin
|
||||
mounter *mount.SafeFormatAndMount
|
||||
exec mount.Exec
|
||||
exec utilexec.Interface
|
||||
// Utility interface that provides API calls to the provider to attach/detach disks.
|
||||
manager diskManager
|
||||
volume.MetricsProvider `json:"-"`
|
||||
|
@ -32,7 +32,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
@ -42,6 +42,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/util/node"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
volutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
utilpath "k8s.io/utils/path"
|
||||
)
|
||||
|
||||
@ -227,22 +228,22 @@ func execRbdMap(b rbdMounter, rbdCmd string, mon string) ([]byte, error) {
|
||||
// do not change this format - some tools like rbd-nbd are strict about it.
|
||||
imgPath := fmt.Sprintf("%s/%s", b.Pool, b.Image)
|
||||
if b.Secret != "" {
|
||||
return b.exec.Run(rbdCmd,
|
||||
"map", imgPath, "--id", b.Id, "-m", mon, "--key="+b.Secret)
|
||||
return b.exec.Command(rbdCmd,
|
||||
"map", imgPath, "--id", b.Id, "-m", mon, "--key="+b.Secret).CombinedOutput()
|
||||
} else {
|
||||
return b.exec.Run(rbdCmd,
|
||||
"map", imgPath, "--id", b.Id, "-m", mon, "-k", b.Keyring)
|
||||
return b.exec.Command(rbdCmd,
|
||||
"map", imgPath, "--id", b.Id, "-m", mon, "-k", b.Keyring).CombinedOutput()
|
||||
}
|
||||
}
|
||||
|
||||
// Check if rbd-nbd tools are installed.
|
||||
func checkRbdNbdTools(e mount.Exec) bool {
|
||||
_, err := e.Run("modprobe", "nbd")
|
||||
func checkRbdNbdTools(e utilexec.Interface) bool {
|
||||
_, err := e.Command("modprobe", "nbd").CombinedOutput()
|
||||
if err != nil {
|
||||
klog.V(5).Infof("rbd-nbd: nbd modprobe failed with error %v", err)
|
||||
return false
|
||||
}
|
||||
if _, err := e.Run("rbd-nbd", "--version"); err != nil {
|
||||
if _, err := e.Command("rbd-nbd", "--version").CombinedOutput(); err != nil {
|
||||
klog.V(5).Infof("rbd-nbd: getting rbd-nbd version failed with error %v", err)
|
||||
return false
|
||||
}
|
||||
@ -335,7 +336,7 @@ func (util *RBDUtil) rbdUnlock(b rbdMounter) error {
|
||||
// Get the locker name, something like "client.1234".
|
||||
args := []string{"lock", "list", b.Image, "--pool", b.Pool, "--id", b.Id, "-m", mon}
|
||||
args = append(args, secret_opt...)
|
||||
cmd, err = b.exec.Run("rbd", args...)
|
||||
cmd, err = b.exec.Command("rbd", args...).CombinedOutput()
|
||||
output = string(cmd)
|
||||
klog.V(4).Infof("lock list output %q", output)
|
||||
if err != nil {
|
||||
@ -353,7 +354,7 @@ func (util *RBDUtil) rbdUnlock(b rbdMounter) error {
|
||||
if len(locker) > 0 {
|
||||
args := []string{"lock", "remove", b.Image, lock_id, locker, "--pool", b.Pool, "--id", b.Id, "-m", mon}
|
||||
args = append(args, secret_opt...)
|
||||
cmd, err = b.exec.Run("rbd", args...)
|
||||
cmd, err = b.exec.Command("rbd", args...).CombinedOutput()
|
||||
if err == nil {
|
||||
klog.V(4).Infof("rbd: successfully remove lock (locker_id: %s) on image: %s/%s with id %s mon %s", lock_id, b.Pool, b.Image, b.Id, mon)
|
||||
} else {
|
||||
@ -432,7 +433,7 @@ func (util *RBDUtil) AttachDisk(b rbdMounter) (string, error) {
|
||||
mon := util.kernelRBDMonitorsOpt(b.Mon)
|
||||
klog.V(1).Infof("rbd: map mon %s", mon)
|
||||
|
||||
_, err := b.exec.Run("modprobe", "rbd")
|
||||
_, err := b.exec.Command("modprobe", "rbd").CombinedOutput()
|
||||
if err != nil {
|
||||
klog.Warningf("rbd: failed to load rbd kernel module:%v", err)
|
||||
}
|
||||
@ -483,7 +484,7 @@ func (util *RBDUtil) DetachDisk(plugin *rbdPlugin, deviceMountPath string, devic
|
||||
}
|
||||
|
||||
// rbd unmap
|
||||
output, err := exec.Run(rbdCmd, "unmap", device)
|
||||
output, err := exec.Command(rbdCmd, "unmap", device).CombinedOutput()
|
||||
if err != nil {
|
||||
return rbdErrors(err, fmt.Errorf("rbd: failed to unmap device %s, error %v, rbd output: %v", device, err, output))
|
||||
}
|
||||
@ -542,7 +543,7 @@ func (util *RBDUtil) DetachBlockDisk(disk rbdDiskUnmapper, mapPath string) error
|
||||
}
|
||||
|
||||
// rbd unmap
|
||||
output, err := exec.Run(rbdCmd, "unmap", device)
|
||||
output, err := exec.Command(rbdCmd, "unmap", device).CombinedOutput()
|
||||
if err != nil {
|
||||
return rbdErrors(err, fmt.Errorf("rbd: failed to unmap device %s, error %v, rbd output: %s", device, err, string(output)))
|
||||
}
|
||||
@ -601,7 +602,7 @@ func (util *RBDUtil) CreateImage(p *rbdVolumeProvisioner) (r *v1.RBDPersistentVo
|
||||
features := strings.Join(p.rbdMounter.imageFeatures, ",")
|
||||
args = append(args, "--image-feature", features)
|
||||
}
|
||||
output, err = p.exec.Run("rbd", args...)
|
||||
output, err = p.exec.Command("rbd", args...).CombinedOutput()
|
||||
|
||||
if err != nil {
|
||||
klog.Warningf("failed to create rbd image, output %v", string(output))
|
||||
@ -628,8 +629,8 @@ func (util *RBDUtil) DeleteImage(p *rbdVolumeDeleter) error {
|
||||
// rbd rm.
|
||||
mon := util.kernelRBDMonitorsOpt(p.rbdMounter.Mon)
|
||||
klog.V(4).Infof("rbd: rm %s using mon %s, pool %s id %s key %s", p.rbdMounter.Image, mon, p.rbdMounter.Pool, p.rbdMounter.adminId, p.rbdMounter.adminSecret)
|
||||
output, err = p.exec.Run("rbd",
|
||||
"rm", p.rbdMounter.Image, "--pool", p.rbdMounter.Pool, "--id", p.rbdMounter.adminId, "-m", mon, "--key="+p.rbdMounter.adminSecret)
|
||||
output, err = p.exec.Command("rbd",
|
||||
"rm", p.rbdMounter.Image, "--pool", p.rbdMounter.Pool, "--id", p.rbdMounter.adminId, "-m", mon, "--key="+p.rbdMounter.adminSecret).CombinedOutput()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
@ -660,8 +661,8 @@ func (util *RBDUtil) ExpandImage(rbdExpander *rbdVolumeExpander, oldSize resourc
|
||||
// rbd resize.
|
||||
mon := util.kernelRBDMonitorsOpt(rbdExpander.rbdMounter.Mon)
|
||||
klog.V(4).Infof("rbd: resize %s using mon %s, pool %s id %s key %s", rbdExpander.rbdMounter.Image, mon, rbdExpander.rbdMounter.Pool, rbdExpander.rbdMounter.adminId, rbdExpander.rbdMounter.adminSecret)
|
||||
output, err = rbdExpander.exec.Run("rbd",
|
||||
"resize", rbdExpander.rbdMounter.Image, "--size", newVolSz, "--pool", rbdExpander.rbdMounter.Pool, "--id", rbdExpander.rbdMounter.adminId, "-m", mon, "--key="+rbdExpander.rbdMounter.adminSecret)
|
||||
output, err = rbdExpander.exec.Command("rbd",
|
||||
"resize", rbdExpander.rbdMounter.Image, "--size", newVolSz, "--pool", rbdExpander.rbdMounter.Pool, "--id", rbdExpander.rbdMounter.adminId, "-m", mon, "--key="+rbdExpander.rbdMounter.adminSecret).CombinedOutput()
|
||||
if err == nil {
|
||||
return newSizeQuant, nil
|
||||
}
|
||||
@ -702,8 +703,8 @@ func (util *RBDUtil) rbdInfo(b *rbdMounter) (int, error) {
|
||||
// rbd: error opening image 1234: (2) No such file or directory
|
||||
//
|
||||
klog.V(4).Infof("rbd: info %s using mon %s, pool %s id %s key %s", b.Image, mon, b.Pool, id, secret)
|
||||
output, err = b.exec.Run("rbd",
|
||||
"info", b.Image, "--pool", b.Pool, "-m", mon, "--id", id, "--key="+secret, "-k=/dev/null", "--format=json")
|
||||
output, err = b.exec.Command("rbd",
|
||||
"info", b.Image, "--pool", b.Pool, "-m", mon, "--id", id, "--key="+secret, "-k=/dev/null", "--format=json").CombinedOutput()
|
||||
|
||||
if err, ok := err.(*exec.Error); ok {
|
||||
if err.Err == exec.ErrNotFound {
|
||||
@ -765,8 +766,8 @@ func (util *RBDUtil) rbdStatus(b *rbdMounter) (bool, string, error) {
|
||||
// rbd: error opening image kubernetes-dynamic-pvc-<UUID>: (2) No such file or directory
|
||||
//
|
||||
klog.V(4).Infof("rbd: status %s using mon %s, pool %s id %s key %s", b.Image, mon, b.Pool, id, secret)
|
||||
cmd, err = b.exec.Run("rbd",
|
||||
"status", b.Image, "--pool", b.Pool, "-m", mon, "--id", id, "--key="+secret)
|
||||
cmd, err = b.exec.Command("rbd",
|
||||
"status", b.Image, "--pool", b.Pool, "-m", mon, "--id", id, "--key="+secret).CombinedOutput()
|
||||
output = string(cmd)
|
||||
|
||||
if err, ok := err.(*exec.Error); ok {
|
||||
|
@ -15,7 +15,6 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/util/mount:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/testing:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
@ -26,6 +25,7 @@ go_test(
|
||||
"//staging/src/k8s.io/client-go/util/testing:go_default_library",
|
||||
"//vendor/github.com/thecodeteam/goscaleio/types/v1:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -52,6 +52,7 @@ go_library(
|
||||
"//vendor/github.com/thecodeteam/goscaleio:go_default_library",
|
||||
"//vendor/github.com/thecodeteam/goscaleio/types/v1:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
"//vendor/k8s.io/utils/keymutex:go_default_library",
|
||||
"//vendor/k8s.io/utils/strings:go_default_library",
|
||||
],
|
||||
|
@ -28,7 +28,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
|
||||
sio "github.com/thecodeteam/goscaleio"
|
||||
siotypes "github.com/thecodeteam/goscaleio/types/v1"
|
||||
@ -78,10 +78,10 @@ type sioClient struct {
|
||||
inited bool
|
||||
diskRegex *regexp.Regexp
|
||||
mtx sync.Mutex
|
||||
exec mount.Exec
|
||||
exec utilexec.Interface
|
||||
}
|
||||
|
||||
func newSioClient(gateway, username, password string, sslEnabled bool, exec mount.Exec) (*sioClient, error) {
|
||||
func newSioClient(gateway, username, password string, sslEnabled bool, exec utilexec.Interface) (*sioClient, error) {
|
||||
client := new(sioClient)
|
||||
client.gateway = gateway
|
||||
client.username = username
|
||||
@ -321,7 +321,7 @@ func (c *sioClient) getGUID() (string, error) {
|
||||
if c.sdcGUID == "" {
|
||||
klog.V(4).Info(log("sdc guid label not set, falling back to using drv_cfg"))
|
||||
cmd := c.getSdcCmd()
|
||||
output, err := c.exec.Run(cmd, "--query_guid")
|
||||
output, err := c.exec.Command(cmd, "--query_guid").CombinedOutput()
|
||||
if err != nil {
|
||||
klog.Error(log("drv_cfg --query_guid failed: %v", err))
|
||||
return "", err
|
||||
|
@ -20,9 +20,8 @@ import (
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
|
||||
"k8s.io/klog"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
|
||||
siotypes "github.com/thecodeteam/goscaleio/types/v1"
|
||||
)
|
||||
@ -30,10 +29,10 @@ import (
|
||||
type sioMgr struct {
|
||||
client sioInterface
|
||||
configData map[string]string
|
||||
exec mount.Exec
|
||||
exec utilexec.Interface
|
||||
}
|
||||
|
||||
func newSioMgr(configs map[string]string, exec mount.Exec) (*sioMgr, error) {
|
||||
func newSioMgr(configs map[string]string, exec utilexec.Interface) (*sioMgr, error) {
|
||||
if configs == nil {
|
||||
return nil, errors.New("missing configuration data")
|
||||
}
|
||||
|
@ -21,9 +21,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
|
||||
siotypes "github.com/thecodeteam/goscaleio/types/v1"
|
||||
"k8s.io/utils/exec/testing"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -44,7 +43,7 @@ var (
|
||||
)
|
||||
|
||||
func newTestMgr(t *testing.T) *sioMgr {
|
||||
mgr, err := newSioMgr(fakeConfig, mount.NewFakeExec(nil))
|
||||
mgr, err := newSioMgr(fakeConfig, &testingexec.FakeExec{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -53,7 +52,7 @@ func newTestMgr(t *testing.T) *sioMgr {
|
||||
}
|
||||
|
||||
func TestMgrNew(t *testing.T) {
|
||||
mgr, err := newSioMgr(fakeConfig, mount.NewFakeExec(nil))
|
||||
mgr, err := newSioMgr(fakeConfig, &testingexec.FakeExec{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ go_library(
|
||||
"//vendor/github.com/storageos/go-api:go_default_library",
|
||||
"//vendor/github.com/storageos/go-api/types:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
"//vendor/k8s.io/utils/strings:go_default_library",
|
||||
],
|
||||
)
|
||||
@ -48,6 +49,7 @@ go_test(
|
||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/util/testing:go_default_library",
|
||||
"//vendor/github.com/storageos/go-api/types:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -33,6 +33,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
"k8s.io/kubernetes/pkg/volume/util"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
utilstrings "k8s.io/utils/strings"
|
||||
)
|
||||
|
||||
@ -115,7 +116,7 @@ func (plugin *storageosPlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ volu
|
||||
return plugin.newMounterInternal(spec, pod, apiCfg, &storageosUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()))
|
||||
}
|
||||
|
||||
func (plugin *storageosPlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod, apiCfg *storageosAPIConfig, manager storageosManager, mounter mount.Interface, exec mount.Exec) (volume.Mounter, error) {
|
||||
func (plugin *storageosPlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod, apiCfg *storageosAPIConfig, manager storageosManager, mounter mount.Interface, exec utilexec.Interface) (volume.Mounter, error) {
|
||||
|
||||
volName, volNamespace, fsType, readOnly, err := getVolumeInfoFromSpec(spec)
|
||||
if err != nil {
|
||||
@ -147,7 +148,7 @@ func (plugin *storageosPlugin) NewUnmounter(pvName string, podUID types.UID) (vo
|
||||
return plugin.newUnmounterInternal(pvName, podUID, &storageosUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()))
|
||||
}
|
||||
|
||||
func (plugin *storageosPlugin) newUnmounterInternal(pvName string, podUID types.UID, manager storageosManager, mounter mount.Interface, exec mount.Exec) (volume.Unmounter, error) {
|
||||
func (plugin *storageosPlugin) newUnmounterInternal(pvName string, podUID types.UID, manager storageosManager, mounter mount.Interface, exec utilexec.Interface) (volume.Unmounter, error) {
|
||||
|
||||
// Parse volume namespace & name from mountpoint if mounted
|
||||
volNamespace, volName, err := getVolumeInfo(pvName, podUID, plugin.host)
|
||||
@ -311,7 +312,7 @@ type storageos struct {
|
||||
apiCfg *storageosAPIConfig
|
||||
manager storageosManager
|
||||
mounter mount.Interface
|
||||
exec mount.Exec
|
||||
exec utilexec.Interface
|
||||
plugin *storageosPlugin
|
||||
volume.MetricsProvider
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||
"k8s.io/utils/exec/testing"
|
||||
)
|
||||
|
||||
func TestCanSupport(t *testing.T) {
|
||||
@ -194,7 +195,7 @@ func TestPlugin(t *testing.T) {
|
||||
t.Errorf("Couldn't get secret from %v/%v", pod.Namespace, secretName)
|
||||
}
|
||||
|
||||
mounter, err := plug.(*storageosPlugin).newMounterInternal(volume.NewSpecFromVolume(spec), pod, apiCfg, fakeManager, mount.NewFakeMounter(nil), mount.NewFakeExec(nil))
|
||||
mounter, err := plug.(*storageosPlugin).newMounterInternal(volume.NewSpecFromVolume(spec), pod, apiCfg, fakeManager, mount.NewFakeMounter(nil), &testingexec.FakeExec{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to make a new Mounter: %v", err)
|
||||
}
|
||||
@ -231,7 +232,7 @@ func TestPlugin(t *testing.T) {
|
||||
|
||||
// Test Unmounter
|
||||
fakeManager = &fakePDManager{}
|
||||
unmounter, err := plug.(*storageosPlugin).newUnmounterInternal("vol1-pvname", types.UID("poduid"), fakeManager, mount.NewFakeMounter(nil), mount.NewFakeExec(nil))
|
||||
unmounter, err := plug.(*storageosPlugin).newUnmounterInternal("vol1-pvname", types.UID("poduid"), fakeManager, mount.NewFakeMounter(nil), &testingexec.FakeExec{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Unmounter: %v", err)
|
||||
}
|
||||
@ -372,7 +373,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
|
||||
fakeManager := &fakePDManager{}
|
||||
fakeConfig := &fakeConfig{}
|
||||
apiCfg := fakeConfig.GetAPIConfig()
|
||||
mounter, err := plug.(*storageosPlugin).newMounterInternal(spec, pod, apiCfg, fakeManager, mount.NewFakeMounter(nil), mount.NewFakeExec(nil))
|
||||
mounter, err := plug.(*storageosPlugin).newMounterInternal(spec, pod, apiCfg, fakeManager, mount.NewFakeMounter(nil), &testingexec.FakeExec{})
|
||||
if err != nil {
|
||||
t.Fatalf("error creating a new internal mounter:%v", err)
|
||||
}
|
||||
|
@ -23,11 +23,10 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
|
||||
storageosapi "github.com/storageos/go-api"
|
||||
storageostypes "github.com/storageos/go-api/types"
|
||||
"k8s.io/klog"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -331,7 +330,7 @@ func pathDeviceType(path string) (deviceType, error) {
|
||||
|
||||
// attachFileDevice takes a path to a regular file and makes it available as an
|
||||
// attached block device.
|
||||
func attachFileDevice(path string, exec mount.Exec) (string, error) {
|
||||
func attachFileDevice(path string, exec utilexec.Interface) (string, error) {
|
||||
blockDevicePath, err := getLoopDevice(path, exec)
|
||||
if err != nil && err.Error() != ErrDeviceNotFound {
|
||||
return "", err
|
||||
@ -349,7 +348,7 @@ func attachFileDevice(path string, exec mount.Exec) (string, error) {
|
||||
}
|
||||
|
||||
// Returns the full path to the loop device associated with the given path.
|
||||
func getLoopDevice(path string, exec mount.Exec) (string, error) {
|
||||
func getLoopDevice(path string, exec utilexec.Interface) (string, error) {
|
||||
_, err := os.Stat(path)
|
||||
if os.IsNotExist(err) {
|
||||
return "", errors.New(ErrNotAvailable)
|
||||
@ -359,7 +358,7 @@ func getLoopDevice(path string, exec mount.Exec) (string, error) {
|
||||
}
|
||||
|
||||
args := []string{"-j", path}
|
||||
out, err := exec.Run(losetupPath, args...)
|
||||
out, err := exec.Command(losetupPath, args...).CombinedOutput()
|
||||
if err != nil {
|
||||
klog.V(2).Infof("Failed device discover command for path %s: %v", path, err)
|
||||
return "", err
|
||||
@ -367,9 +366,9 @@ func getLoopDevice(path string, exec mount.Exec) (string, error) {
|
||||
return parseLosetupOutputForDevice(out)
|
||||
}
|
||||
|
||||
func makeLoopDevice(path string, exec mount.Exec) (string, error) {
|
||||
func makeLoopDevice(path string, exec utilexec.Interface) (string, error) {
|
||||
args := []string{"-f", "-P", "--show", path}
|
||||
out, err := exec.Run(losetupPath, args...)
|
||||
out, err := exec.Command(losetupPath, args...).CombinedOutput()
|
||||
if err != nil {
|
||||
klog.V(2).Infof("Failed device create command for path %s: %v", path, err)
|
||||
return "", err
|
||||
@ -377,9 +376,9 @@ func makeLoopDevice(path string, exec mount.Exec) (string, error) {
|
||||
return parseLosetupOutputForDevice(out)
|
||||
}
|
||||
|
||||
func removeLoopDevice(device string, exec mount.Exec) error {
|
||||
func removeLoopDevice(device string, exec utilexec.Interface) error {
|
||||
args := []string{"-d", device}
|
||||
out, err := exec.Run(losetupPath, args...)
|
||||
out, err := exec.Command(losetupPath, args...).CombinedOutput()
|
||||
if err != nil {
|
||||
if !strings.Contains(string(out), "No such device or address") {
|
||||
return err
|
||||
|
@ -35,6 +35,8 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/util/testing:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/mock:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec/testing:go_default_library",
|
||||
"//vendor/k8s.io/utils/strings:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -20,7 +20,6 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -41,6 +40,9 @@ import (
|
||||
"k8s.io/client-go/tools/record"
|
||||
utiltesting "k8s.io/client-go/util/testing"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
"k8s.io/utils/exec"
|
||||
"k8s.io/utils/exec/testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
. "k8s.io/kubernetes/pkg/volume"
|
||||
"k8s.io/kubernetes/pkg/volume/util"
|
||||
@ -73,7 +75,7 @@ type fakeVolumeHost struct {
|
||||
cloud cloudprovider.Interface
|
||||
mounter mount.Interface
|
||||
hostUtil hostutil.HostUtils
|
||||
exec mount.Exec
|
||||
exec *testingexec.FakeExec
|
||||
nodeLabels map[string]string
|
||||
nodeName string
|
||||
subpather subpath.Interface
|
||||
@ -111,7 +113,7 @@ func newFakeVolumeHost(rootDir string, kubeClient clientset.Interface, plugins [
|
||||
host := &fakeVolumeHost{rootDir: rootDir, kubeClient: kubeClient, cloud: cloud}
|
||||
host.mounter = mount.NewFakeMounter(nil)
|
||||
host.hostUtil = hostutil.NewFakeHostUtil(pathToTypeMap)
|
||||
host.exec = mount.NewFakeExec(nil)
|
||||
host.exec = &testingexec.FakeExec{DisableScripts: true}
|
||||
host.pluginMgr.InitPlugins(plugins, nil /* prober */, host)
|
||||
host.subpather = &subpath.FakeSubpath{}
|
||||
host.informerFactory = informers.NewSharedInformerFactory(kubeClient, time.Minute)
|
||||
@ -213,7 +215,7 @@ func (f *fakeVolumeHost) GetSecretFunc() func(namespace, name string) (*v1.Secre
|
||||
}
|
||||
}
|
||||
|
||||
func (f *fakeVolumeHost) GetExec(pluginName string) mount.Exec {
|
||||
func (f *fakeVolumeHost) GetExec(pluginName string) exec.Interface {
|
||||
return f.exec
|
||||
}
|
||||
|
||||
@ -248,6 +250,64 @@ func (f *fakeVolumeHost) GetEventRecorder() record.EventRecorder {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeVolumeHost) ScriptCommands(scripts []CommandScript) {
|
||||
ScriptCommands(f.exec, scripts)
|
||||
}
|
||||
|
||||
// CommandScript is used to pre-configure a command that will be executed and
|
||||
// optionally set it's output (stdout and stderr combined) and return code.
|
||||
type CommandScript struct {
|
||||
// Cmd is the command to execute, e.g. "ls"
|
||||
Cmd string
|
||||
// Args is a slice of arguments to pass to the command, e.g. "-a"
|
||||
Args []string
|
||||
// Output is the combined stdout and stderr of the command to return
|
||||
Output string
|
||||
// ReturnCode is the exit code for the command. Setting this to non-zero will
|
||||
// cause the command to return an error with this exit code set.
|
||||
ReturnCode int
|
||||
}
|
||||
|
||||
// ScriptCommands configures fe, the FakeExec, to have a pre-configured list of
|
||||
// commands to expect. Calling more commands using fe than those scripted will
|
||||
// result in a panic. By default, the fe does not enforce command argument checking
|
||||
// or order -- if you have given an Output to the command, the first command scripted
|
||||
// will return its output on the first command call, even if the command called is
|
||||
// different than the one scripted. This is mostly useful to make sure that the
|
||||
// right number of commands were called. If you want to check the exact commands
|
||||
// and arguments were called, set fe.ExectOrder to true.
|
||||
func ScriptCommands(fe *testingexec.FakeExec, scripts []CommandScript) {
|
||||
fe.DisableScripts = false
|
||||
for _, script := range scripts {
|
||||
fakeCmd := &testingexec.FakeCmd{}
|
||||
cmdAction := makeFakeCmd(fakeCmd, script.Cmd, script.Args...)
|
||||
outputAction := makeFakeOutput(script.Output, script.ReturnCode)
|
||||
fakeCmd.CombinedOutputScript = append(fakeCmd.CombinedOutputScript, outputAction)
|
||||
fe.CommandScript = append(fe.CommandScript, cmdAction)
|
||||
}
|
||||
}
|
||||
|
||||
func makeFakeCmd(fakeCmd *testingexec.FakeCmd, cmd string, args ...string) testingexec.FakeCommandAction {
|
||||
fc := fakeCmd
|
||||
c := cmd
|
||||
a := args
|
||||
return func(cmd string, args ...string) exec.Cmd {
|
||||
command := testingexec.InitFakeCmd(fc, c, a...)
|
||||
return command
|
||||
}
|
||||
}
|
||||
|
||||
func makeFakeOutput(output string, rc int) testingexec.FakeCombinedOutputAction {
|
||||
o := output
|
||||
var e error
|
||||
if rc != 0 {
|
||||
e = testingexec.FakeExitError{Status: rc}
|
||||
}
|
||||
return func() ([]byte, error) {
|
||||
return []byte(o), e
|
||||
}
|
||||
}
|
||||
|
||||
func ProbeVolumePlugins(config VolumeConfig) []VolumePlugin {
|
||||
if _, ok := config.OtherAttributes["fake-property"]; ok {
|
||||
return []VolumePlugin{
|
||||
@ -1131,7 +1191,7 @@ func FindEmptyDirectoryUsageOnTmpfs() (*resource.Quantity, error) {
|
||||
return nil, err
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
out, err := exec.Command("nice", "-n", "19", "du", "-x", "-s", "-B", "1", tmpDir).CombinedOutput()
|
||||
out, err := exec.New().Command("nice", "-n", "19", "du", "-x", "-s", "-B", "1", tmpDir).CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed command 'du' on %s with error %v", tmpDir, err)
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ go_library(
|
||||
"//staging/src/k8s.io/component-base/metrics:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/metrics/legacyregistry:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
"//vendor/k8s.io/utils/strings:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -36,6 +36,7 @@ import (
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
||||
@ -44,6 +45,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
"k8s.io/kubernetes/pkg/volume/util/types"
|
||||
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
utilstrings "k8s.io/utils/strings"
|
||||
)
|
||||
|
||||
@ -585,11 +587,11 @@ func HasMountRefs(mountPath string, mountRefs []string) bool {
|
||||
}
|
||||
|
||||
//WriteVolumeCache flush disk data given the spcified mount path
|
||||
func WriteVolumeCache(deviceMountPath string, exec mount.Exec) error {
|
||||
func WriteVolumeCache(deviceMountPath string, exec utilexec.Interface) error {
|
||||
// If runtime os is windows, execute Write-VolumeCache powershell command on the disk
|
||||
if runtime.GOOS == "windows" {
|
||||
cmd := fmt.Sprintf("Get-Volume -FilePath %s | Write-Volumecache", deviceMountPath)
|
||||
output, err := exec.Run("powershell", "/c", cmd)
|
||||
output, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
|
||||
klog.Infof("command (%q) execeuted: %v, output: %q", cmd, err, string(output))
|
||||
if err != nil {
|
||||
return fmt.Errorf("command (%q) failed: %v, output: %q", cmd, err, string(output))
|
||||
|
Loading…
Reference in New Issue
Block a user