diff --git a/pkg/volume/util/fs/BUILD b/pkg/volume/util/fs/BUILD index 5df65eb027d..0193ae830f9 100644 --- a/pkg/volume/util/fs/BUILD +++ b/pkg/volume/util/fs/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", @@ -65,3 +65,15 @@ filegroup( tags = ["automanaged"], visibility = ["//visibility:public"], ) + +go_test( + name = "go_default_test", + srcs = ["fs_windows_test.go"], + embed = [":go_default_library"], + deps = select({ + "@io_bazel_rules_go//go/platform:windows": [ + "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", + ], + "//conditions:default": [], + }), +) diff --git a/pkg/volume/util/fs/fs_windows.go b/pkg/volume/util/fs/fs_windows.go index ea8c4784ae9..07c4e6bdbee 100644 --- a/pkg/volume/util/fs/fs_windows.go +++ b/pkg/volume/util/fs/fs_windows.go @@ -20,6 +20,7 @@ package fs import ( "fmt" + "os" "syscall" "unsafe" @@ -58,7 +59,12 @@ func FsInfo(path string) (int64, int64, int64, int64, int64, int64, error) { // DiskUsage gets disk usage of specified path. func DiskUsage(path string) (*resource.Quantity, error) { - _, _, usage, _, _, _, err := FsInfo(path) + info, err := os.Lstat(path) + if err != nil { + return nil, err + } + + usage, err := diskUsage(path, info) if err != nil { return nil, err } @@ -75,3 +81,41 @@ func DiskUsage(path string) (*resource.Quantity, error) { func Find(path string) (int64, error) { return 0, nil } + +func diskUsage(currPath string, info os.FileInfo) (int64, error) { + var size int64 + + if info.Mode()&os.ModeSymlink != 0 { + return size, nil + } + + size += info.Size() + + if !info.IsDir() { + return size, nil + } + + dir, err := os.Open(currPath) + if err != nil { + return size, err + } + defer dir.Close() + + files, err := dir.Readdir(-1) + if err != nil { + return size, err + } + + for _, file := range files { + if file.IsDir() { + s, err := diskUsage(fmt.Sprintf("%s/%s", currPath, file.Name()), file) + if err != nil { + return size, err + } + size += s + } else { + size += file.Size() + } + } + return size, nil +} diff --git a/pkg/volume/util/fs/fs_windows_test.go b/pkg/volume/util/fs/fs_windows_test.go new file mode 100644 index 00000000000..5723dcd72b6 --- /dev/null +++ b/pkg/volume/util/fs/fs_windows_test.go @@ -0,0 +1,81 @@ +/* +Copyright 2019 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 fs + +import ( + "fmt" + "io/ioutil" + "os" + + "k8s.io/apimachinery/pkg/api/resource" + "testing" +) + +func TestDiskUsage(t *testing.T) { + + dir_1, err := ioutil.TempDir("", "dir_1") + if err != nil { + t.Fatalf("TestDiskUsage failed: %s", err.Error()) + } + defer os.RemoveAll(dir_1) + + tmpfile_1, err := ioutil.TempFile(dir_1, "test") + if _, err = tmpfile_1.WriteString("just for testing"); err != nil { + t.Fatalf("TestDiskUsage failed: %s", err.Error()) + } + dir_2, err := ioutil.TempDir(dir_1, "dir_2") + if err != nil { + t.Fatalf("TestDiskUsage failed: %s", err.Error()) + } + tmpfile_2, err := ioutil.TempFile(dir_2, "test") + if _, err = tmpfile_2.WriteString("just for testing"); err != nil { + t.Fatalf("TestDiskUsage failed: %s", err.Error()) + } + + dirInfo1, err := os.Lstat(dir_1) + if err != nil { + t.Fatalf("TestDiskUsage failed: %s", err.Error()) + } + dirInfo2, err := os.Lstat(dir_2) + if err != nil { + t.Fatalf("TestDiskUsage failed: %s", err.Error()) + } + file1 := dir_1 + "/" + "test" + file2 := dir_2 + "/" + "test" + fileInfo1, err := os.Lstat(file1) + if err != nil { + t.Fatalf("TestDiskUsage failed: %s", err.Error()) + } + fileInfo2, err := os.Lstat(file2) + if err != nil { + t.Fatalf("TestDiskUsage failed: %s", err.Error()) + } + total := dirInfo1.Size() + dirInfo2.Size() + fileInfo1.Size() + fileInfo2.Size() + + size, err := DiskUsage(dir_1) + if err != nil { + t.Fatalf("TestDiskUsage failed: %s", err.Error()) + } + used, err := resource.ParseQuantity(fmt.Sprintf("%d", total)) + if err != nil { + t.Fatalf("TestDiskUsage failed: %s", err.Error()) + } + if size.Cmp(used) != 1 { + t.Fatalf("TestDiskUsage failed: %s", err.Error()) + } + +}