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