mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-05 23:47:50 +00:00
BlockVolumesSupport: CRI, VolumeManager and OperationExecutor changes
This patch contains following changes. - container runtime changes for adding block devices - volumemanager changes - operationexecutor changes
This commit is contained in:
@@ -39,6 +39,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
utilstrings "k8s.io/kubernetes/pkg/util/strings"
|
||||
. "k8s.io/kubernetes/pkg/volume"
|
||||
"k8s.io/kubernetes/pkg/volume/util"
|
||||
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
|
||||
)
|
||||
|
||||
@@ -81,10 +82,18 @@ func (f *fakeVolumeHost) GetPluginDir(podUID string) string {
|
||||
return path.Join(f.rootDir, "plugins", podUID)
|
||||
}
|
||||
|
||||
func (f *fakeVolumeHost) GetVolumeDevicePluginDir(podUID string) string {
|
||||
return path.Join(f.rootDir, "plugins", podUID)
|
||||
}
|
||||
|
||||
func (f *fakeVolumeHost) GetPodVolumeDir(podUID types.UID, pluginName, volumeName string) string {
|
||||
return path.Join(f.rootDir, "pods", string(podUID), "volumes", pluginName, volumeName)
|
||||
}
|
||||
|
||||
func (f *fakeVolumeHost) GetPodVolumeDeviceDir(podUID types.UID, pluginName string) string {
|
||||
return path.Join(f.rootDir, "pods", string(podUID), "volumeDevices", pluginName)
|
||||
}
|
||||
|
||||
func (f *fakeVolumeHost) GetPodPluginDir(podUID types.UID, pluginName string) string {
|
||||
return path.Join(f.rootDir, "pods", string(podUID), "plugins", pluginName)
|
||||
}
|
||||
@@ -194,13 +203,16 @@ type FakeVolumePlugin struct {
|
||||
NewAttacherCallCount int
|
||||
NewDetacherCallCount int
|
||||
|
||||
Mounters []*FakeVolume
|
||||
Unmounters []*FakeVolume
|
||||
Attachers []*FakeVolume
|
||||
Detachers []*FakeVolume
|
||||
Mounters []*FakeVolume
|
||||
Unmounters []*FakeVolume
|
||||
Attachers []*FakeVolume
|
||||
Detachers []*FakeVolume
|
||||
BlockVolumeMappers []*FakeVolume
|
||||
BlockVolumeUnmappers []*FakeVolume
|
||||
}
|
||||
|
||||
var _ VolumePlugin = &FakeVolumePlugin{}
|
||||
var _ BlockVolumePlugin = &FakeVolumePlugin{}
|
||||
var _ RecyclableVolumePlugin = &FakeVolumePlugin{}
|
||||
var _ DeletableVolumePlugin = &FakeVolumePlugin{}
|
||||
var _ ProvisionableVolumePlugin = &FakeVolumePlugin{}
|
||||
@@ -280,6 +292,44 @@ func (plugin *FakeVolumePlugin) GetUnmounters() (Unmounters []*FakeVolume) {
|
||||
return plugin.Unmounters
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (plugin *FakeVolumePlugin) NewBlockVolumeMapper(spec *Spec, pod *v1.Pod, opts VolumeOptions) (BlockVolumeMapper, error) {
|
||||
plugin.Lock()
|
||||
defer plugin.Unlock()
|
||||
volume := plugin.getFakeVolume(&plugin.BlockVolumeMappers)
|
||||
if pod != nil {
|
||||
volume.PodUID = pod.UID
|
||||
}
|
||||
volume.VolName = spec.Name()
|
||||
volume.Plugin = plugin
|
||||
return volume, nil
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (plugin *FakeVolumePlugin) GetBlockVolumeMapper() (BlockVolumeMappers []*FakeVolume) {
|
||||
plugin.RLock()
|
||||
defer plugin.RUnlock()
|
||||
return plugin.BlockVolumeMappers
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (plugin *FakeVolumePlugin) NewBlockVolumeUnmapper(volName string, podUID types.UID) (BlockVolumeUnmapper, error) {
|
||||
plugin.Lock()
|
||||
defer plugin.Unlock()
|
||||
volume := plugin.getFakeVolume(&plugin.BlockVolumeUnmappers)
|
||||
volume.PodUID = podUID
|
||||
volume.VolName = volName
|
||||
volume.Plugin = plugin
|
||||
return volume, nil
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (plugin *FakeVolumePlugin) GetBlockVolumeUnmapper() (BlockVolumeUnmappers []*FakeVolume) {
|
||||
plugin.RLock()
|
||||
defer plugin.RUnlock()
|
||||
return plugin.BlockVolumeUnmappers
|
||||
}
|
||||
|
||||
func (plugin *FakeVolumePlugin) NewAttacher() (Attacher, error) {
|
||||
plugin.Lock()
|
||||
defer plugin.Unlock()
|
||||
@@ -345,10 +395,66 @@ func (plugin *FakeVolumePlugin) ConstructVolumeSpec(volumeName, mountPath string
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (plugin *FakeVolumePlugin) ConstructBlockVolumeSpec(podUID types.UID, volumeName, mountPath string) (*Spec, error) {
|
||||
return &Spec{
|
||||
Volume: &v1.Volume{
|
||||
Name: volumeName,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (plugin *FakeVolumePlugin) GetDeviceMountRefs(deviceMountPath string) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
type FakeFileVolumePlugin struct {
|
||||
}
|
||||
|
||||
func (plugin *FakeFileVolumePlugin) Init(host VolumeHost) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (plugin *FakeFileVolumePlugin) GetPluginName() string {
|
||||
return "fake-file-plugin"
|
||||
}
|
||||
|
||||
func (plugin *FakeFileVolumePlugin) GetVolumeName(spec *Spec) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (plugin *FakeFileVolumePlugin) CanSupport(spec *Spec) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (plugin *FakeFileVolumePlugin) RequiresRemount() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (plugin *FakeFileVolumePlugin) SupportsMountOption() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (plugin *FakeFileVolumePlugin) SupportsBulkVolumeVerification() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (plugin *FakeFileVolumePlugin) NewMounter(spec *Spec, podRef *v1.Pod, opts VolumeOptions) (Mounter, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (plugin *FakeFileVolumePlugin) NewUnmounter(name string, podUID types.UID) (Unmounter, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (plugin *FakeFileVolumePlugin) ConstructVolumeSpec(volumeName, mountPath string) (*Spec, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func NewFakeFileVolumePlugin() []VolumePlugin {
|
||||
return []VolumePlugin{&FakeFileVolumePlugin{}}
|
||||
}
|
||||
|
||||
type FakeVolume struct {
|
||||
sync.RWMutex
|
||||
PodUID types.UID
|
||||
@@ -364,6 +470,10 @@ type FakeVolume struct {
|
||||
MountDeviceCallCount int
|
||||
UnmountDeviceCallCount int
|
||||
GetDeviceMountPathCallCount int
|
||||
SetUpDeviceCallCount int
|
||||
TearDownDeviceCallCount int
|
||||
GlobalMapPathCallCount int
|
||||
PodDeviceMapPathCallCount int
|
||||
}
|
||||
|
||||
func (_ *FakeVolume) GetAttributes() Attributes {
|
||||
@@ -422,6 +532,76 @@ func (fv *FakeVolume) TearDownAt(dir string) error {
|
||||
return os.RemoveAll(dir)
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (fv *FakeVolume) SetUpDevice() (string, error) {
|
||||
fv.Lock()
|
||||
defer fv.Unlock()
|
||||
fv.SetUpDeviceCallCount++
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (fv *FakeVolume) GetSetUpDeviceCallCount() int {
|
||||
fv.RLock()
|
||||
defer fv.RUnlock()
|
||||
return fv.SetUpDeviceCallCount
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (fv *FakeVolume) GetGlobalMapPath(spec *Spec) (string, error) {
|
||||
fv.RLock()
|
||||
defer fv.RUnlock()
|
||||
fv.GlobalMapPathCallCount++
|
||||
return fv.getGlobalMapPath()
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (fv *FakeVolume) getGlobalMapPath() (string, error) {
|
||||
return path.Join(fv.Plugin.Host.GetVolumeDevicePluginDir(utilstrings.EscapeQualifiedNameForDisk(fv.Plugin.PluginName)), "pluginDependentPath"), nil
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (fv *FakeVolume) GetGlobalMapPathCallCount() int {
|
||||
fv.RLock()
|
||||
defer fv.RUnlock()
|
||||
return fv.GlobalMapPathCallCount
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (fv *FakeVolume) GetPodDeviceMapPath() (string, string) {
|
||||
fv.RLock()
|
||||
defer fv.RUnlock()
|
||||
fv.PodDeviceMapPathCallCount++
|
||||
return fv.getPodDeviceMapPath()
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (fv *FakeVolume) getPodDeviceMapPath() (string, string) {
|
||||
return path.Join(fv.Plugin.Host.GetPodVolumeDeviceDir(fv.PodUID, utilstrings.EscapeQualifiedNameForDisk(fv.Plugin.PluginName))), fv.VolName
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (fv *FakeVolume) GetPodDeviceMapPathCallCount() int {
|
||||
fv.RLock()
|
||||
defer fv.RUnlock()
|
||||
return fv.PodDeviceMapPathCallCount
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (fv *FakeVolume) TearDownDevice(mapPath string, devicePath string) error {
|
||||
fv.Lock()
|
||||
defer fv.Unlock()
|
||||
fv.TearDownDeviceCallCount++
|
||||
return nil
|
||||
}
|
||||
|
||||
// Block volume support
|
||||
func (fv *FakeVolume) GetTearDownDeviceCallCount() int {
|
||||
fv.RLock()
|
||||
defer fv.RUnlock()
|
||||
return fv.TearDownDeviceCallCount
|
||||
}
|
||||
|
||||
func (fv *FakeVolume) Attach(spec *Spec, nodeName types.NodeName) (string, error) {
|
||||
fv.Lock()
|
||||
defer fv.Unlock()
|
||||
@@ -439,7 +619,7 @@ func (fv *FakeVolume) WaitForAttach(spec *Spec, devicePath string, pod *v1.Pod,
|
||||
fv.Lock()
|
||||
defer fv.Unlock()
|
||||
fv.WaitForAttachCallCount++
|
||||
return "", nil
|
||||
return "/dev/sdb", nil
|
||||
}
|
||||
|
||||
func (fv *FakeVolume) GetWaitForAttachCallCount() int {
|
||||
@@ -540,6 +720,62 @@ func (fc *FakeProvisioner) Provision() (*v1.PersistentVolume, error) {
|
||||
return pv, nil
|
||||
}
|
||||
|
||||
var _ util.BlockVolumePathHandler = &FakeVolumePathHandler{}
|
||||
|
||||
//NewDeviceHandler Create a new IoHandler implementation
|
||||
func NewBlockVolumePathHandler() util.BlockVolumePathHandler {
|
||||
return &FakeVolumePathHandler{}
|
||||
}
|
||||
|
||||
type FakeVolumePathHandler struct {
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func (fv *FakeVolumePathHandler) MapDevice(devicePath string, mapDir string, linkName string) error {
|
||||
// nil is success, else error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fv *FakeVolumePathHandler) UnmapDevice(mapDir string, linkName string) error {
|
||||
// nil is success, else error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fv *FakeVolumePathHandler) RemoveMapPath(mapPath string) error {
|
||||
// nil is success, else error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fv *FakeVolumePathHandler) IsSymlinkExist(mapPath string) (bool, error) {
|
||||
// nil is success, else error
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (fv *FakeVolumePathHandler) GetDeviceSymlinkRefs(devPath string, mapPath string) ([]string, error) {
|
||||
// nil is success, else error
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (fv *FakeVolumePathHandler) FindGlobalMapPathUUIDFromPod(pluginDir, mapPath string, podUID types.UID) (string, error) {
|
||||
// nil is success, else error
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (fv *FakeVolumePathHandler) AttachFileDevice(path string) (string, error) {
|
||||
// nil is success, else error
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (fv *FakeVolumePathHandler) GetLoopDevice(path string) (string, error) {
|
||||
// nil is success, else error
|
||||
return "/dev/loop1", nil
|
||||
}
|
||||
|
||||
func (fv *FakeVolumePathHandler) RemoveLoopDevice(device string) error {
|
||||
// nil is success, else error
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindEmptyDirectoryUsageOnTmpfs finds the expected usage of an empty directory existing on
|
||||
// a tmpfs filesystem on this system.
|
||||
func FindEmptyDirectoryUsageOnTmpfs() (*resource.Quantity, error) {
|
||||
@@ -758,6 +994,93 @@ func VerifyZeroDetachCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifySetUpDeviceCallCount ensures that at least one of the Mappers for this
|
||||
// plugin has the expectedSetUpDeviceCallCount number of calls. Otherwise it
|
||||
// returns an error.
|
||||
func VerifySetUpDeviceCallCount(
|
||||
expectedSetUpDeviceCallCount int,
|
||||
fakeVolumePlugin *FakeVolumePlugin) error {
|
||||
for _, mapper := range fakeVolumePlugin.GetBlockVolumeMapper() {
|
||||
actualCallCount := mapper.GetSetUpDeviceCallCount()
|
||||
if actualCallCount >= expectedSetUpDeviceCallCount {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf(
|
||||
"No Mapper have expected SetUpDeviceCallCount. Expected: <%v>.",
|
||||
expectedSetUpDeviceCallCount)
|
||||
}
|
||||
|
||||
// VerifyTearDownDeviceCallCount ensures that at least one of the Unmappers for this
|
||||
// plugin has the expectedTearDownDeviceCallCount number of calls. Otherwise it
|
||||
// returns an error.
|
||||
func VerifyTearDownDeviceCallCount(
|
||||
expectedTearDownDeviceCallCount int,
|
||||
fakeVolumePlugin *FakeVolumePlugin) error {
|
||||
for _, unmapper := range fakeVolumePlugin.GetBlockVolumeUnmapper() {
|
||||
actualCallCount := unmapper.GetTearDownDeviceCallCount()
|
||||
if actualCallCount >= expectedTearDownDeviceCallCount {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf(
|
||||
"No Unmapper have expected TearDownDeviceCallCount. Expected: <%v>.",
|
||||
expectedTearDownDeviceCallCount)
|
||||
}
|
||||
|
||||
// VerifyZeroTearDownDeviceCallCount ensures that all Mappers for this plugin have a
|
||||
// zero TearDownDeviceCallCount. Otherwise it returns an error.
|
||||
func VerifyZeroTearDownDeviceCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
|
||||
for _, unmapper := range fakeVolumePlugin.GetBlockVolumeUnmapper() {
|
||||
actualCallCount := unmapper.GetTearDownDeviceCallCount()
|
||||
if actualCallCount != 0 {
|
||||
return fmt.Errorf(
|
||||
"At least one unmapper has non-zero TearDownDeviceCallCount: <%v>.",
|
||||
actualCallCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifyGetGlobalMapPathCallCount ensures that at least one of the Mappers for this
|
||||
// plugin has the expectedGlobalMapPathCallCount number of calls. Otherwise it returns
|
||||
// an error.
|
||||
func VerifyGetGlobalMapPathCallCount(
|
||||
expectedGlobalMapPathCallCount int,
|
||||
fakeVolumePlugin *FakeVolumePlugin) error {
|
||||
for _, mapper := range fakeVolumePlugin.GetBlockVolumeMapper() {
|
||||
actualCallCount := mapper.GetGlobalMapPathCallCount()
|
||||
if actualCallCount == expectedGlobalMapPathCallCount {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf(
|
||||
"No Mappers have expected GetGlobalMapPathCallCount. Expected: <%v>.",
|
||||
expectedGlobalMapPathCallCount)
|
||||
}
|
||||
|
||||
// VerifyGetPodDeviceMapPathCallCount ensures that at least one of the Mappers for this
|
||||
// plugin has the expectedPodDeviceMapPathCallCount number of calls. Otherwise it returns
|
||||
// an error.
|
||||
func VerifyGetPodDeviceMapPathCallCount(
|
||||
expectedPodDeviceMapPathCallCount int,
|
||||
fakeVolumePlugin *FakeVolumePlugin) error {
|
||||
for _, mapper := range fakeVolumePlugin.GetBlockVolumeMapper() {
|
||||
actualCallCount := mapper.GetPodDeviceMapPathCallCount()
|
||||
if actualCallCount == expectedPodDeviceMapPathCallCount {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf(
|
||||
"No Mappers have expected GetPodDeviceMapPathCallCount. Expected: <%v>.",
|
||||
expectedPodDeviceMapPathCallCount)
|
||||
}
|
||||
|
||||
// GetTestVolumePluginMgr creates, initializes, and returns a test volume plugin
|
||||
// manager and fake volume plugin using a fake volume host.
|
||||
func GetTestVolumePluginMgr(
|
||||
|
||||
Reference in New Issue
Block a user