Skip to content

Commit 6a21076

Browse files
committed
copy mount files to hostutils
1 parent d54c516 commit 6a21076

14 files changed

+3403
-0
lines changed
File renamed without changes.
Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
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+
"path/filepath"
23+
"sync"
24+
25+
"k8s.io/klog"
26+
)
27+
28+
// FakeMounter implements mount.Interface for tests.
29+
type FakeMounter struct {
30+
MountPoints []MountPoint
31+
Log []FakeAction
32+
// Error to return for a path when calling IsLikelyNotMountPoint
33+
MountCheckErrors map[string]error
34+
// Some tests run things in parallel, make sure the mounter does not produce
35+
// any golang's DATA RACE warnings.
36+
mutex sync.Mutex
37+
}
38+
39+
var _ Interface = &FakeMounter{}
40+
41+
const (
42+
// FakeActionMount is the string for specifying mount as FakeAction.Action
43+
FakeActionMount = "mount"
44+
// FakeActionUnmount is the string for specifying unmount as FakeAction.Action
45+
FakeActionUnmount = "unmount"
46+
)
47+
48+
// FakeAction objects are logged every time a fake mount or unmount is called.
49+
type FakeAction struct {
50+
Action string // "mount" or "unmount"
51+
Target string // applies to both mount and unmount actions
52+
Source string // applies only to "mount" actions
53+
FSType string // applies only to "mount" actions
54+
}
55+
56+
// ResetLog clears all the log entries in FakeMounter
57+
func (f *FakeMounter) ResetLog() {
58+
f.mutex.Lock()
59+
defer f.mutex.Unlock()
60+
61+
f.Log = []FakeAction{}
62+
}
63+
64+
// Mount records the mount event and updates the in-memory mount points for FakeMounter
65+
func (f *FakeMounter) Mount(source string, target string, fstype string, options []string) error {
66+
f.mutex.Lock()
67+
defer f.mutex.Unlock()
68+
69+
opts := []string{}
70+
71+
for _, option := range options {
72+
// find 'bind' option
73+
if option == "bind" {
74+
// This is a bind-mount. In order to mimic linux behaviour, we must
75+
// use the original device of the bind-mount as the real source.
76+
// E.g. when mounted /dev/sda like this:
77+
// $ mount /dev/sda /mnt/test
78+
// $ mount -o bind /mnt/test /mnt/bound
79+
// then /proc/mount contains:
80+
// /dev/sda /mnt/test
81+
// /dev/sda /mnt/bound
82+
// (and not /mnt/test /mnt/bound)
83+
// I.e. we must use /dev/sda as source instead of /mnt/test in the
84+
// bind mount.
85+
for _, mnt := range f.MountPoints {
86+
if source == mnt.Path {
87+
source = mnt.Device
88+
break
89+
}
90+
}
91+
}
92+
// reuse MountPoint.Opts field to mark mount as readonly
93+
opts = append(opts, option)
94+
}
95+
96+
// If target is a symlink, get its absolute path
97+
absTarget, err := filepath.EvalSymlinks(target)
98+
if err != nil {
99+
absTarget = target
100+
}
101+
f.MountPoints = append(f.MountPoints, MountPoint{Device: source, Path: absTarget, Type: fstype, Opts: opts})
102+
klog.V(5).Infof("Fake mounter: mounted %s to %s", source, absTarget)
103+
f.Log = append(f.Log, FakeAction{Action: FakeActionMount, Target: absTarget, Source: source, FSType: fstype})
104+
return nil
105+
}
106+
107+
// Unmount records the unmount event and updates the in-memory mount points for FakeMounter
108+
func (f *FakeMounter) Unmount(target string) error {
109+
f.mutex.Lock()
110+
defer f.mutex.Unlock()
111+
112+
// If target is a symlink, get its absolute path
113+
absTarget, err := filepath.EvalSymlinks(target)
114+
if err != nil {
115+
absTarget = target
116+
}
117+
118+
newMountpoints := []MountPoint{}
119+
for _, mp := range f.MountPoints {
120+
if mp.Path == absTarget {
121+
klog.V(5).Infof("Fake mounter: unmounted %s from %s", mp.Device, absTarget)
122+
// Don't copy it to newMountpoints
123+
continue
124+
}
125+
newMountpoints = append(newMountpoints, MountPoint{Device: mp.Device, Path: mp.Path, Type: mp.Type})
126+
}
127+
f.MountPoints = newMountpoints
128+
f.Log = append(f.Log, FakeAction{Action: FakeActionUnmount, Target: absTarget})
129+
delete(f.MountCheckErrors, target)
130+
return nil
131+
}
132+
133+
// List returns all the in-memory mountpoints for FakeMounter
134+
func (f *FakeMounter) List() ([]MountPoint, error) {
135+
f.mutex.Lock()
136+
defer f.mutex.Unlock()
137+
138+
return f.MountPoints, nil
139+
}
140+
141+
// IsMountPointMatch tests if dir and mp are the same path
142+
func (f *FakeMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
143+
return mp.Path == dir
144+
}
145+
146+
// IsLikelyNotMountPoint determines whether a path is a mountpoint by checking
147+
// if the absolute path to file is in the in-memory mountpoints
148+
func (f *FakeMounter) IsLikelyNotMountPoint(file string) (bool, error) {
149+
f.mutex.Lock()
150+
defer f.mutex.Unlock()
151+
152+
err := f.MountCheckErrors[file]
153+
if err != nil {
154+
return false, err
155+
}
156+
157+
_, err = os.Stat(file)
158+
if err != nil {
159+
return true, err
160+
}
161+
162+
// If file is a symlink, get its absolute path
163+
absFile, err := filepath.EvalSymlinks(file)
164+
if err != nil {
165+
absFile = file
166+
}
167+
168+
for _, mp := range f.MountPoints {
169+
if mp.Path == absFile {
170+
klog.V(5).Infof("isLikelyNotMountPoint for %s: mounted %s, false", file, mp.Path)
171+
return false, nil
172+
}
173+
}
174+
klog.V(5).Infof("isLikelyNotMountPoint for %s: true", file)
175+
return true, nil
176+
}
177+
178+
// GetMountRefs finds all mount references to the path, returns a
179+
// list of paths.
180+
func (f *FakeMounter) GetMountRefs(pathname string) ([]string, error) {
181+
realpath, err := filepath.EvalSymlinks(pathname)
182+
if err != nil {
183+
// Ignore error in FakeMounter, because we actually didn't create files.
184+
realpath = pathname
185+
}
186+
return getMountRefsByDev(f, realpath)
187+
}
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+
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)