mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Add SupportsMetrics() for Block-mode volumes
Volumes that are provisioned with `VolumeMode: Block` often have a MetrucsProvider interface declared in their type. However, the MetricsProvider should implement a GetMetrics() function. In the cases where the storage drivers do not implement GetMetrics(), a panic can occur. Usual type-assertions are not sufficient in this case. All assertions assume the interface is present. There is no straight forward way to verify that a valid GetMetrics() function is provided. By adding SupportsMetrics(), storage driver implementations require careful reviewing for metrics support.
This commit is contained in:
parent
fd3bbf6f9e
commit
b997e0e4d6
@ -567,6 +567,10 @@ func (f *stubBlockVolume) UnmapPodDevice() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *stubBlockVolume) SupportsMetrics() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *stubBlockVolume) GetMetrics() (*volume.Metrics, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -112,7 +112,12 @@ func (s *volumeStatCalculator) calcAndStoreStats() {
|
||||
for name, v := range blockVolumes {
|
||||
// Only add the blockVolume if it implements the MetricsProvider interface
|
||||
if _, ok := v.(volume.MetricsProvider); ok {
|
||||
metricVolumes[name] = v
|
||||
// Some drivers inherit the MetricsProvider interface from Filesystem
|
||||
// mode volumes, but do not implement it for Block mode. Checking
|
||||
// SupportsMetrics() will prevent panics in that case.
|
||||
if v.SupportsMetrics() {
|
||||
metricVolumes[name] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -246,6 +246,8 @@ func (v *fakeBlockVolume) GetGlobalMapPath(*volume.Spec) (string, error) { retur
|
||||
|
||||
func (v *fakeBlockVolume) GetPodDeviceMapPath() (string, string) { return "", "" }
|
||||
|
||||
func (v *fakeBlockVolume) SupportsMetrics() bool { return true }
|
||||
|
||||
func (v *fakeBlockVolume) GetMetrics() (*volume.Metrics, error) {
|
||||
return expectedBlockMetrics(), nil
|
||||
}
|
||||
|
@ -165,3 +165,9 @@ func (ebs *awsElasticBlockStore) GetPodDeviceMapPath() (string, string) {
|
||||
name := awsElasticBlockStorePluginName
|
||||
return ebs.plugin.host.GetPodVolumeDeviceDir(ebs.podUID, utilstrings.EscapeQualifiedName(name)), ebs.volName
|
||||
}
|
||||
|
||||
// SupportsMetrics returns true for awsElasticBlockStore as it initializes the
|
||||
// MetricsProvider.
|
||||
func (ebs *awsElasticBlockStore) SupportsMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ func (plugin *azureDataDiskPlugin) newUnmapperInternal(volName string, podUID ty
|
||||
|
||||
type azureDataDiskUnmapper struct {
|
||||
*dataDisk
|
||||
volume.MetricsNil
|
||||
}
|
||||
|
||||
var _ volume.BlockVolumeUnmapper = &azureDataDiskUnmapper{}
|
||||
@ -157,3 +158,9 @@ func (disk *dataDisk) GetPodDeviceMapPath() (string, string) {
|
||||
name := azureDataDiskPluginName
|
||||
return disk.plugin.host.GetPodVolumeDeviceDir(disk.podUID, utilstrings.EscapeQualifiedName(name)), disk.volumeName
|
||||
}
|
||||
|
||||
// SupportsMetrics returns true for azureDataDiskMapper as it initializes the
|
||||
// MetricsProvider.
|
||||
func (addm *azureDataDiskMapper) SupportsMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
@ -140,6 +140,7 @@ func (plugin *cinderPlugin) newUnmapperInternal(volName string, podUID types.UID
|
||||
|
||||
type cinderPluginUnmapper struct {
|
||||
*cinderVolume
|
||||
volume.MetricsNil
|
||||
}
|
||||
|
||||
var _ volume.BlockVolumeUnmapper = &cinderPluginUnmapper{}
|
||||
@ -168,3 +169,9 @@ func (cd *cinderVolume) GetPodDeviceMapPath() (string, string) {
|
||||
name := cinderVolumePluginName
|
||||
return cd.plugin.host.GetPodVolumeDeviceDir(cd.podUID, utilstrings.EscapeQualifiedName(name)), cd.volName
|
||||
}
|
||||
|
||||
// SupportsMetrics returns true for cinderVolumeMapper as it initializes the
|
||||
// MetricsProvider.
|
||||
func (cvm *cinderVolumeMapper) SupportsMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
@ -115,6 +115,12 @@ func (m *csiBlockMapper) GetStagingPath() string {
|
||||
return filepath.Join(m.plugin.host.GetVolumeDevicePluginDir(CSIPluginName), "staging", m.specName)
|
||||
}
|
||||
|
||||
// SupportsMetrics returns true for csiBlockMapper as it initializes the
|
||||
// MetricsProvider.
|
||||
func (m *csiBlockMapper) SupportsMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// getPublishDir returns path to a directory, where the volume is published to each pod.
|
||||
// Example: plugins/kubernetes.io/csi/volumeDevices/publish/{specName}
|
||||
func (m *csiBlockMapper) getPublishDir() string {
|
||||
|
@ -174,3 +174,9 @@ func (pd *gcePersistentDisk) GetPodDeviceMapPath() (string, string) {
|
||||
name := gcePersistentDiskPluginName
|
||||
return pd.plugin.host.GetPodVolumeDeviceDir(pd.podUID, utilstrings.EscapeQualifiedName(name)), pd.volName
|
||||
}
|
||||
|
||||
// SupportsMetrics returns true for gcePersistentDisk as it initializes the
|
||||
// MetricsProvider.
|
||||
func (pd *gcePersistentDisk) SupportsMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
@ -393,6 +393,13 @@ type iscsiDiskUnmapper struct {
|
||||
*iscsiDisk
|
||||
exec utilexec.Interface
|
||||
deviceUtil ioutil.DeviceUtil
|
||||
volume.MetricsNil
|
||||
}
|
||||
|
||||
// SupportsMetrics returns true for SupportsMetrics as it initializes the
|
||||
// MetricsProvider.
|
||||
func (idm *iscsiDiskMapper) SupportsMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
var _ volume.BlockVolumeUnmapper = &iscsiDiskUnmapper{}
|
||||
|
@ -633,9 +633,16 @@ func (m *localVolumeMapper) GetStagingPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// SupportsMetrics returns true for SupportsMetrics as it initializes the
|
||||
// MetricsProvider.
|
||||
func (m *localVolumeMapper) SupportsMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// localVolumeUnmapper implements the BlockVolumeUnmapper interface for local volumes.
|
||||
type localVolumeUnmapper struct {
|
||||
*localVolume
|
||||
volume.MetricsNil
|
||||
}
|
||||
|
||||
var _ volume.BlockVolumeUnmapper = &localVolumeUnmapper{}
|
||||
|
@ -23,6 +23,11 @@ var _ MetricsProvider = &MetricsNil{}
|
||||
// metrics.
|
||||
type MetricsNil struct{}
|
||||
|
||||
// SupportsMetrics returns false for the MetricsNil type.
|
||||
func (*MetricsNil) SupportsMetrics() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetMetrics returns an empty Metrics and an error.
|
||||
// See MetricsProvider.GetMetrics
|
||||
func (*MetricsNil) GetMetrics() (*Metrics, error) {
|
||||
|
@ -20,6 +20,14 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMetricsNilSupportsMetrics(t *testing.T) {
|
||||
metrics := &MetricsNil{}
|
||||
supported := metrics.SupportsMetrics()
|
||||
if supported {
|
||||
t.Error("Expected no support for metrics")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetricsNilGetCapacity(t *testing.T) {
|
||||
metrics := &MetricsNil{}
|
||||
actual, err := metrics.GetMetrics()
|
||||
|
@ -938,6 +938,12 @@ func (rbd *rbd) rbdPodDeviceMapPath() (string, string) {
|
||||
return rbd.plugin.host.GetPodVolumeDeviceDir(rbd.podUID, utilstrings.EscapeQualifiedName(name)), rbd.volName
|
||||
}
|
||||
|
||||
// SupportsMetrics returns true for rbdDiskMapper as it initializes the
|
||||
// MetricsProvider.
|
||||
func (rdm *rbdDiskMapper) SupportsMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type rbdDiskUnmapper struct {
|
||||
*rbdDiskMapper
|
||||
}
|
||||
|
@ -49,6 +49,10 @@ type BlockVolume interface {
|
||||
// ex. pods/{podUid}/{DefaultKubeletVolumeDevicesDirName}/{escapeQualifiedPluginName}/, {volumeName}
|
||||
GetPodDeviceMapPath() (string, string)
|
||||
|
||||
// SupportsMetrics should return true if the MetricsProvider is
|
||||
// initialized
|
||||
SupportsMetrics() bool
|
||||
|
||||
// MetricsProvider embeds methods for exposing metrics (e.g.
|
||||
// used, available space).
|
||||
MetricsProvider
|
||||
|
@ -144,6 +144,7 @@ var _ volume.BlockVolumeUnmapper = &vsphereBlockVolumeUnmapper{}
|
||||
|
||||
type vsphereBlockVolumeUnmapper struct {
|
||||
*vsphereVolume
|
||||
volume.MetricsNil
|
||||
}
|
||||
|
||||
// GetGlobalMapPath returns global map path and error
|
||||
@ -159,3 +160,9 @@ func (v *vsphereVolume) GetGlobalMapPath(spec *volume.Spec) (string, error) {
|
||||
func (v *vsphereVolume) GetPodDeviceMapPath() (string, string) {
|
||||
return v.plugin.host.GetPodVolumeDeviceDir(v.podUID, utilstrings.EscapeQualifiedName(vsphereVolumePluginName)), v.volName
|
||||
}
|
||||
|
||||
// SupportsMetrics returns true for vsphereBlockVolumeMapper as it initializes the
|
||||
// MetricsProvider.
|
||||
func (vbvm *vsphereBlockVolumeMapper) SupportsMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user