Merge pull request #63248 from andyzhangx/formatAndMount-windows

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

fix formatAndMount func issue on Windows

**What this PR does / why we need it**:
disk format code is missing in formatAndMount func on Windows, currently it only has mount related code:
b87a392b1a/pkg/util/mount/mount_windows.go (L356-L377)

format code is now here, which is not correct(invoked in `azuredisk.WaitForAttach` operation, it's not correct, these code should be in `formatAndMount` func and invoked by `MountDevice` operation finally)
b87a392b1a/pkg/volume/azure_dd/azure_common_windows.go (L100-L117)

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #63236 

**Special notes for your reviewer**:
This is the first PR,  in second PR, I will remove disk format code in azure_common_windows.go
b87a392b1a/pkg/volume/azure_dd/azure_common_windows.go (L100-L117)

Also need to mention that there would not be issue if  following command invoked twice(by `WaitForAttach` and `formatAndMount`)
```
Get-Disk -Number 4 | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle MBR -PassThru  | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem ntfs -Confirm:$false
```
**Release note**:

```
fix formatAndMount func issue on Windows
```

/sig windows
/assign @rootfs 
cc @msau42
pull/8/head
Kubernetes Submit Queue 2018-06-01 21:25:57 -07:00 committed by GitHub
commit 2aced6d9e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 1 deletions

View File

@ -364,10 +364,23 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
glog.V(4).Infof("Attempting to formatAndMount disk: %s %s %s", fstype, source, target)
if err := ValidateDiskNumber(source); err != nil {
glog.Errorf("azureMount: formatAndMount failed, err: %v\n", err)
glog.Errorf("diskMount: formatAndMount failed, err: %v", err)
return err
}
if len(fstype) == 0 {
// Use 'NTFS' as the default
fstype = "NTFS"
}
// 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 {
return fmt.Errorf("diskMount: format disk failed, error: %v, output: %q", err, string(output))
}
glog.V(4).Infof("diskMount: Disk successfully formatted, disk: %q, fstype: %q", source, fstype)
driveLetter, err := getDriveLetterByDiskNumber(source, mounter.Exec)
if err != nil {
return err

View File

@ -24,6 +24,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
@ -720,3 +721,75 @@ func TestIsLikelyNotMountPoint(t *testing.T) {
}
}
}
func TestFormatAndMount(t *testing.T) {
fakeMounter := ErrorMounter{&FakeMounter{}, 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
mountOptions []string
expectError bool
}{
{
"0",
"disk",
"NTFS",
[]string{},
false,
},
{
"0",
"disk",
"",
[]string{},
false,
},
{
"invalidDevice",
"disk",
"NTFS",
[]string{},
true,
},
}
for _, test := range tests {
base, err := ioutil.TempDir("", test.device)
if err != nil {
t.Fatalf(err.Error())
}
defer os.RemoveAll(base)
target := filepath.Join(base, test.target)
err = mounter.FormatAndMount(test.device, target, test.fstype, test.mountOptions)
if test.expectError {
assert.NotNil(t, err, "Expect error during FormatAndMount(%s, %s, %s, %v)", test.device, test.target, test.fstype, test.mountOptions)
} else {
assert.Nil(t, err, "Expect error is nil during FormatAndMount(%s, %s, %s, %v)", test.device, test.target, test.fstype, test.mountOptions)
}
}
}