diff --git a/pkg/util/mount/mount_windows.go b/pkg/util/mount/mount_windows.go index 64d39a59f7..5c57a57d06 100644 --- a/pkg/util/mount/mount_windows.go +++ b/pkg/util/mount/mount_windows.go @@ -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 diff --git a/pkg/util/mount/mount_windows_test.go b/pkg/util/mount/mount_windows_test.go index 32b0903f18..a6e26bec8a 100644 --- a/pkg/util/mount/mount_windows_test.go +++ b/pkg/util/mount/mount_windows_test.go @@ -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) + } + } +}