Skip to content

Commit 7ebbe34

Browse files
authored
Merge pull request kubernetes#81794 from codenrhoden/split-host-utils2
Split HostUtil functionality into its own files
2 parents a76d7fd + b94ee6b commit 7ebbe34

19 files changed

+1576
-1303
lines changed

pkg/util/mount/BUILD

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ go_library(
66
"doc.go",
77
"exec.go",
88
"fake.go",
9+
"fake_hostutil.go",
10+
"hostutil.go",
11+
"hostutil_linux.go",
12+
"hostutil_unsupported.go",
13+
"hostutil_windows.go",
914
"mount.go",
1015
"mount_helper_common.go",
1116
"mount_helper_unix.go",
@@ -20,11 +25,38 @@ go_library(
2025
"//vendor/k8s.io/klog:go_default_library",
2126
"//vendor/k8s.io/utils/exec:go_default_library",
2227
] + select({
28+
"@io_bazel_rules_go//go/platform:android": [
29+
"//vendor/k8s.io/utils/io:go_default_library",
30+
],
31+
"@io_bazel_rules_go//go/platform:darwin": [
32+
"//vendor/k8s.io/utils/io:go_default_library",
33+
],
34+
"@io_bazel_rules_go//go/platform:dragonfly": [
35+
"//vendor/k8s.io/utils/io:go_default_library",
36+
],
37+
"@io_bazel_rules_go//go/platform:freebsd": [
38+
"//vendor/k8s.io/utils/io:go_default_library",
39+
],
2340
"@io_bazel_rules_go//go/platform:linux": [
2441
"//vendor/golang.org/x/sys/unix:go_default_library",
2542
"//vendor/k8s.io/utils/io:go_default_library",
2643
"//vendor/k8s.io/utils/path:go_default_library",
2744
],
45+
"@io_bazel_rules_go//go/platform:nacl": [
46+
"//vendor/k8s.io/utils/io:go_default_library",
47+
],
48+
"@io_bazel_rules_go//go/platform:netbsd": [
49+
"//vendor/k8s.io/utils/io:go_default_library",
50+
],
51+
"@io_bazel_rules_go//go/platform:openbsd": [
52+
"//vendor/k8s.io/utils/io:go_default_library",
53+
],
54+
"@io_bazel_rules_go//go/platform:plan9": [
55+
"//vendor/k8s.io/utils/io:go_default_library",
56+
],
57+
"@io_bazel_rules_go//go/platform:solaris": [
58+
"//vendor/k8s.io/utils/io:go_default_library",
59+
],
2860
"@io_bazel_rules_go//go/platform:windows": [
2961
"//vendor/k8s.io/utils/keymutex:go_default_library",
3062
"//vendor/k8s.io/utils/path:go_default_library",
@@ -36,7 +68,11 @@ go_library(
3668
go_test(
3769
name = "go_default_test",
3870
srcs = [
71+
"hostutil_linux_test.go",
72+
"hostutil_windows_test.go",
3973
"mount_helper_test.go",
74+
"mount_helper_unix_test.go",
75+
"mount_helper_windows_test.go",
4076
"mount_linux_test.go",
4177
"mount_test.go",
4278
"mount_windows_test.go",

pkg/util/mount/fake.go

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ limitations under the License.
1717
package mount
1818

1919
import (
20-
"errors"
2120
"os"
2221
"path/filepath"
2322
"sync"
@@ -185,96 +184,3 @@ func (f *FakeMounter) GetMountRefs(pathname string) ([]string, error) {
185184
}
186185
return getMountRefsByDev(f, realpath)
187186
}
188-
189-
// FakeHostUtil is a fake mount.HostUtils implementation for testing
190-
type FakeHostUtil struct {
191-
MountPoints []MountPoint
192-
Filesystem map[string]FileType
193-
194-
mutex sync.Mutex
195-
}
196-
197-
var _ HostUtils = &FakeHostUtil{}
198-
199-
// DeviceOpened checks if block device referenced by pathname is in use by
200-
// checking if is listed as a device in the in-memory mountpoint table.
201-
func (hu *FakeHostUtil) DeviceOpened(pathname string) (bool, error) {
202-
hu.mutex.Lock()
203-
defer hu.mutex.Unlock()
204-
205-
for _, mp := range hu.MountPoints {
206-
if mp.Device == pathname {
207-
return true, nil
208-
}
209-
}
210-
return false, nil
211-
}
212-
213-
// PathIsDevice always returns true
214-
func (hu *FakeHostUtil) PathIsDevice(pathname string) (bool, error) {
215-
return true, nil
216-
}
217-
218-
// GetDeviceNameFromMount given a mount point, find the volume id
219-
func (hu *FakeHostUtil) GetDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) {
220-
return getDeviceNameFromMount(mounter, mountPath, pluginMountDir)
221-
}
222-
223-
// MakeRShared checks if path is shared and bind-mounts it as rshared if needed.
224-
// No-op for testing
225-
func (hu *FakeHostUtil) MakeRShared(path string) error {
226-
return nil
227-
}
228-
229-
// GetFileType checks for file/directory/socket/block/character devices.
230-
// Defaults to Directory if otherwise unspecified.
231-
func (hu *FakeHostUtil) GetFileType(pathname string) (FileType, error) {
232-
if t, ok := hu.Filesystem[pathname]; ok {
233-
return t, nil
234-
}
235-
return FileType("Directory"), nil
236-
}
237-
238-
// MakeDir creates a new directory.
239-
// No-op for testing
240-
func (hu *FakeHostUtil) MakeDir(pathname string) error {
241-
return nil
242-
}
243-
244-
// MakeFile creates a new file.
245-
// No-op for testing
246-
func (hu *FakeHostUtil) MakeFile(pathname string) error {
247-
return nil
248-
}
249-
250-
// PathExists checks if pathname exists.
251-
func (hu *FakeHostUtil) PathExists(pathname string) (bool, error) {
252-
if _, ok := hu.Filesystem[pathname]; ok {
253-
return true, nil
254-
}
255-
return false, nil
256-
}
257-
258-
// EvalHostSymlinks returns the path name after evaluating symlinks.
259-
// No-op for testing
260-
func (hu *FakeHostUtil) EvalHostSymlinks(pathname string) (string, error) {
261-
return pathname, nil
262-
}
263-
264-
// GetOwner returns the integer ID for the user and group of the given path
265-
// Not implemented for testing
266-
func (hu *FakeHostUtil) GetOwner(pathname string) (int64, int64, error) {
267-
return -1, -1, errors.New("GetOwner not implemented")
268-
}
269-
270-
// GetSELinuxSupport tests if pathname is on a mount that supports SELinux.
271-
// Not implemented for testing
272-
func (hu *FakeHostUtil) GetSELinuxSupport(pathname string) (bool, error) {
273-
return false, errors.New("GetSELinuxSupport not implemented")
274-
}
275-
276-
// GetMode returns permissions of pathname.
277-
// Not implemented for testing
278-
func (hu *FakeHostUtil) GetMode(pathname string) (os.FileMode, error) {
279-
return 0, errors.New("not implemented")
280-
}

pkg/util/mount/fake_hostutil.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
Copyright 2015 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package mount
18+
19+
import (
20+
"errors"
21+
"os"
22+
"sync"
23+
)
24+
25+
// FakeHostUtil is a fake mount.HostUtils implementation for testing
26+
type FakeHostUtil struct {
27+
MountPoints []MountPoint
28+
Filesystem map[string]FileType
29+
30+
mutex sync.Mutex
31+
}
32+
33+
var _ HostUtils = &FakeHostUtil{}
34+
35+
// DeviceOpened checks if block device referenced by pathname is in use by
36+
// checking if is listed as a device in the in-memory mountpoint table.
37+
func (hu *FakeHostUtil) DeviceOpened(pathname string) (bool, error) {
38+
hu.mutex.Lock()
39+
defer hu.mutex.Unlock()
40+
41+
for _, mp := range hu.MountPoints {
42+
if mp.Device == pathname {
43+
return true, nil
44+
}
45+
}
46+
return false, nil
47+
}
48+
49+
// PathIsDevice always returns true
50+
func (hu *FakeHostUtil) PathIsDevice(pathname string) (bool, error) {
51+
return true, nil
52+
}
53+
54+
// GetDeviceNameFromMount given a mount point, find the volume id
55+
func (hu *FakeHostUtil) GetDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) {
56+
return getDeviceNameFromMount(mounter, mountPath, pluginMountDir)
57+
}
58+
59+
// MakeRShared checks if path is shared and bind-mounts it as rshared if needed.
60+
// No-op for testing
61+
func (hu *FakeHostUtil) MakeRShared(path string) error {
62+
return nil
63+
}
64+
65+
// GetFileType checks for file/directory/socket/block/character devices.
66+
// Defaults to Directory if otherwise unspecified.
67+
func (hu *FakeHostUtil) GetFileType(pathname string) (FileType, error) {
68+
if t, ok := hu.Filesystem[pathname]; ok {
69+
return t, nil
70+
}
71+
return FileType("Directory"), nil
72+
}
73+
74+
// MakeDir creates a new directory.
75+
// No-op for testing
76+
func (hu *FakeHostUtil) MakeDir(pathname string) error {
77+
return nil
78+
}
79+
80+
// MakeFile creates a new file.
81+
// No-op for testing
82+
func (hu *FakeHostUtil) MakeFile(pathname string) error {
83+
return nil
84+
}
85+
86+
// PathExists checks if pathname exists.
87+
func (hu *FakeHostUtil) PathExists(pathname string) (bool, error) {
88+
if _, ok := hu.Filesystem[pathname]; ok {
89+
return true, nil
90+
}
91+
return false, nil
92+
}
93+
94+
// EvalHostSymlinks returns the path name after evaluating symlinks.
95+
// No-op for testing
96+
func (hu *FakeHostUtil) EvalHostSymlinks(pathname string) (string, error) {
97+
return pathname, nil
98+
}
99+
100+
// GetOwner returns the integer ID for the user and group of the given path
101+
// Not implemented for testing
102+
func (hu *FakeHostUtil) GetOwner(pathname string) (int64, int64, error) {
103+
return -1, -1, errors.New("GetOwner not implemented")
104+
}
105+
106+
// GetSELinuxSupport tests if pathname is on a mount that supports SELinux.
107+
// Not implemented for testing
108+
func (hu *FakeHostUtil) GetSELinuxSupport(pathname string) (bool, error) {
109+
return false, errors.New("GetSELinuxSupport not implemented")
110+
}
111+
112+
// GetMode returns permissions of pathname.
113+
// Not implemented for testing
114+
func (hu *FakeHostUtil) GetMode(pathname string) (os.FileMode, error) {
115+
return 0, errors.New("not implemented")
116+
}

pkg/util/mount/hostutil.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
Copyright 2014 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// TODO(thockin): This whole pkg is pretty linux-centric. As soon as we have
18+
// an alternate platform, we will need to abstract further.
19+
20+
package mount
21+
22+
import (
23+
"fmt"
24+
"os"
25+
)
26+
27+
// FileType enumerates the known set of possible file types.
28+
type FileType string
29+
30+
const (
31+
// FileTypeBlockDev defines a constant for the block device FileType.
32+
FileTypeBlockDev FileType = "BlockDevice"
33+
// FileTypeCharDev defines a constant for the character device FileType.
34+
FileTypeCharDev FileType = "CharDevice"
35+
// FileTypeDirectory defines a constant for the directory FileType.
36+
FileTypeDirectory FileType = "Directory"
37+
// FileTypeFile defines a constant for the file FileType.
38+
FileTypeFile FileType = "File"
39+
// FileTypeSocket defines a constant for the socket FileType.
40+
FileTypeSocket FileType = "Socket"
41+
// FileTypeUnknown defines a constant for an unknown FileType.
42+
FileTypeUnknown FileType = ""
43+
)
44+
45+
// HostUtils defines the set of methods for interacting with paths on a host.
46+
type HostUtils interface {
47+
// DeviceOpened determines if the device (e.g. /dev/sdc) is in use elsewhere
48+
// on the system, i.e. still mounted.
49+
DeviceOpened(pathname string) (bool, error)
50+
// PathIsDevice determines if a path is a device.
51+
PathIsDevice(pathname string) (bool, error)
52+
// GetDeviceNameFromMount finds the device name by checking the mount path
53+
// to get the global mount path within its plugin directory.
54+
GetDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error)
55+
// MakeRShared checks that given path is on a mount with 'rshared' mount
56+
// propagation. If not, it bind-mounts the path as rshared.
57+
MakeRShared(path string) error
58+
// GetFileType checks for file/directory/socket/block/character devices.
59+
GetFileType(pathname string) (FileType, error)
60+
// MakeFile creates an empty file.
61+
MakeFile(pathname string) error
62+
// MakeDir creates a new directory.
63+
MakeDir(pathname string) error
64+
// PathExists tests if the given path already exists
65+
// Error is returned on any other error than "file not found".
66+
PathExists(pathname string) (bool, error)
67+
// EvalHostSymlinks returns the path name after evaluating symlinks.
68+
EvalHostSymlinks(pathname string) (string, error)
69+
// GetOwner returns the integer ID for the user and group of the given path
70+
GetOwner(pathname string) (int64, int64, error)
71+
// GetSELinuxSupport returns true if given path is on a mount that supports
72+
// SELinux.
73+
GetSELinuxSupport(pathname string) (bool, error)
74+
// GetMode returns permissions of the path.
75+
GetMode(pathname string) (os.FileMode, error)
76+
}
77+
78+
// Compile-time check to ensure all HostUtil implementations satisfy
79+
// the HostUtils Interface.
80+
var _ HostUtils = &hostUtil{}
81+
82+
// getFileType checks for file/directory/socket and block/character devices.
83+
func getFileType(pathname string) (FileType, error) {
84+
var pathType FileType
85+
info, err := os.Stat(pathname)
86+
if os.IsNotExist(err) {
87+
return pathType, fmt.Errorf("path %q does not exist", pathname)
88+
}
89+
// err in call to os.Stat
90+
if err != nil {
91+
return pathType, err
92+
}
93+
94+
// checks whether the mode is the target mode.
95+
isSpecificMode := func(mode, targetMode os.FileMode) bool {
96+
return mode&targetMode == targetMode
97+
}
98+
99+
mode := info.Mode()
100+
if mode.IsDir() {
101+
return FileTypeDirectory, nil
102+
} else if mode.IsRegular() {
103+
return FileTypeFile, nil
104+
} else if isSpecificMode(mode, os.ModeSocket) {
105+
return FileTypeSocket, nil
106+
} else if isSpecificMode(mode, os.ModeDevice) {
107+
if isSpecificMode(mode, os.ModeCharDevice) {
108+
return FileTypeCharDev, nil
109+
}
110+
return FileTypeBlockDev, nil
111+
}
112+
113+
return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device")
114+
}

0 commit comments

Comments
 (0)