From fc988d429b854640e1ef2baa35695ff0453c6a95 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 30 Nov 2017 08:44:35 +0000 Subject: [PATCH] initial work for azure file grow size implementation enable azure file grow size fix according to comments fix comments fix review comments fix comments --- cmd/kube-controller-manager/app/plugins.go | 1 + .../providers/azure/azure_file.go | 10 ++--- .../providers/azure/azure_storage.go | 25 ++++++++++- pkg/volume/azure_file/azure_file.go | 44 +++++++++++++++++-- pkg/volume/azure_file/azure_provision.go | 10 +++-- .../persistentvolume/resize/admission.go | 3 ++ 6 files changed, 78 insertions(+), 15 deletions(-) diff --git a/cmd/kube-controller-manager/app/plugins.go b/cmd/kube-controller-manager/app/plugins.go index 170c366c90..a421377f12 100644 --- a/cmd/kube-controller-manager/app/plugins.go +++ b/cmd/kube-controller-manager/app/plugins.go @@ -102,6 +102,7 @@ func ProbeExpandableVolumePlugins(config componentconfig.VolumeConfiguration) [] allPlugins = append(allPlugins, glusterfs.ProbeVolumePlugins()...) allPlugins = append(allPlugins, rbd.ProbeVolumePlugins()...) allPlugins = append(allPlugins, azure_dd.ProbeVolumePlugins()...) + allPlugins = append(allPlugins, azure_file.ProbeVolumePlugins()...) allPlugins = append(allPlugins, photon_pd.ProbeVolumePlugins()...) allPlugins = append(allPlugins, scaleio.ProbeVolumePlugins()...) allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...) diff --git a/pkg/cloudprovider/providers/azure/azure_file.go b/pkg/cloudprovider/providers/azure/azure_file.go index 39e54383dc..1afb78015a 100644 --- a/pkg/cloudprovider/providers/azure/azure_file.go +++ b/pkg/cloudprovider/providers/azure/azure_file.go @@ -31,13 +31,13 @@ const ( // FileClient is the interface for creating file shares, interface for test // injection. type FileClient interface { - createFileShare(accountName, accountKey, name string, sizeGB int) error + createFileShare(accountName, accountKey, name string, sizeGiB int) error deleteFileShare(accountName, accountKey, name string) error } // create file share -func (az *Cloud) createFileShare(accountName, accountKey, name string, sizeGB int) error { - return az.FileClient.createFileShare(accountName, accountKey, name, sizeGB) +func (az *Cloud) createFileShare(accountName, accountKey, name string, sizeGiB int) error { + return az.FileClient.createFileShare(accountName, accountKey, name, sizeGiB) } func (az *Cloud) deleteFileShare(accountName, accountKey, name string) error { @@ -48,7 +48,7 @@ type azureFileClient struct { env azure.Environment } -func (f *azureFileClient) createFileShare(accountName, accountKey, name string, sizeGB int) error { +func (f *azureFileClient) createFileShare(accountName, accountKey, name string, sizeGiB int) error { fileClient, err := f.getFileSvcClient(accountName, accountKey) if err != nil { return err @@ -62,7 +62,7 @@ func (f *azureFileClient) createFileShare(accountName, accountKey, name string, if err = share.Create(nil); err != nil { return fmt.Errorf("failed to create file share, err: %v", err) } - share.Properties.Quota = sizeGB + share.Properties.Quota = sizeGiB if err = share.SetProperties(nil); err != nil { if err := share.Delete(nil); err != nil { glog.Errorf("Error deleting share: %v", err) diff --git a/pkg/cloudprovider/providers/azure/azure_storage.go b/pkg/cloudprovider/providers/azure/azure_storage.go index b9dead6fac..5be1fd7371 100644 --- a/pkg/cloudprovider/providers/azure/azure_storage.go +++ b/pkg/cloudprovider/providers/azure/azure_storage.go @@ -23,7 +23,7 @@ import ( ) // CreateFileShare creates a file share, using a matching storage account -func (az *Cloud) CreateFileShare(name, storageAccount, storageType, location string, requestGB int) (string, string, error) { +func (az *Cloud) CreateFileShare(name, storageAccount, storageType, location string, requestGiB int) (string, string, error) { var errResult error accounts := []accountWithLocation{} if len(storageAccount) > 0 { @@ -46,7 +46,7 @@ func (az *Cloud) CreateFileShare(name, storageAccount, storageType, location str continue } - if innerErr = az.createFileShare(account.Name, key, name, requestGB); innerErr != nil { + if innerErr = az.createFileShare(account.Name, key, name, requestGiB); innerErr != nil { errResult = fmt.Errorf("failed to create share %s in account %s: %v", name, account.Name, innerErr) continue } @@ -69,3 +69,24 @@ func (az *Cloud) DeleteFileShare(accountName, key, name string) error { glog.V(4).Infof("share %s deleted", name) return nil } + +// ResizeFileShare resizes a file share +func (az *Cloud) ResizeFileShare(accountName, accountKey, name string, sizeGiB int) error { + fileClient, err := az.getFileSvcClient(accountName, accountKey) + if err != nil { + return err + } + + share := fileClient.GetShareReference(name) + if share.Properties.Quota >= sizeGiB { + glog.Warningf("file share size(%dGi) is already greater or equal than requested size(%dGi), accountName: %s, shareName: %s", + share.Properties.Quota, sizeGiB, accountName, name) + return nil + } + share.Properties.Quota = sizeGiB + if err = share.SetProperties(nil); err != nil { + return fmt.Errorf("failed to set quota on file share %s, err: %v", name, err) + } + glog.V(4).Infof("resize file share completed, accountName: %s, shareName: %s, sizeGiB: %d", accountName, name, sizeGiB) + return nil +} diff --git a/pkg/volume/azure_file/azure_file.go b/pkg/volume/azure_file/azure_file.go index 7ac1962b8c..7b925495a6 100644 --- a/pkg/volume/azure_file/azure_file.go +++ b/pkg/volume/azure_file/azure_file.go @@ -21,16 +21,16 @@ import ( "os" "runtime" + "github.com/golang/glog" "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/kubernetes/pkg/cloudprovider" + "k8s.io/kubernetes/pkg/cloudprovider/providers/azure" "k8s.io/kubernetes/pkg/util/mount" kstrings "k8s.io/kubernetes/pkg/util/strings" "k8s.io/kubernetes/pkg/volume" - - "github.com/golang/glog" - "k8s.io/kubernetes/pkg/cloudprovider" - "k8s.io/kubernetes/pkg/cloudprovider/providers/azure" "k8s.io/kubernetes/pkg/volume/util" ) @@ -45,6 +45,7 @@ type azureFilePlugin struct { var _ volume.VolumePlugin = &azureFilePlugin{} var _ volume.PersistentVolumePlugin = &azureFilePlugin{} +var _ volume.ExpandableVolumePlugin = &azureFilePlugin{} const ( azureFilePluginName = "kubernetes.io/azure-file" @@ -139,6 +140,41 @@ func (plugin *azureFilePlugin) newUnmounterInternal(volName string, podUID types }}, nil } +func (plugin *azureFilePlugin) RequiresFSResize() bool { + return false +} + +func (plugin *azureFilePlugin) ExpandVolumeDevice( + spec *volume.Spec, + newSize resource.Quantity, + oldSize resource.Quantity) (resource.Quantity, error) { + + if spec.PersistentVolume != nil || spec.PersistentVolume.Spec.AzureFile == nil { + return oldSize, fmt.Errorf("invalid PV spec") + } + shareName := spec.PersistentVolume.Spec.AzureFile.ShareName + azure, err := getAzureCloudProvider(plugin.host.GetCloudProvider()) + if err != nil { + return oldSize, err + } + + secretName, secretNamespace, err := getSecretNameAndNamespace(spec, spec.PersistentVolume.Spec.ClaimRef.Namespace) + if err != nil { + return oldSize, err + } + + accountName, accountKey, err := (&azureSvc{}).GetAzureCredentials(plugin.host, secretNamespace, secretName) + if err != nil { + return oldSize, err + } + + if err := azure.ResizeFileShare(accountName, accountKey, shareName, int(volume.RoundUpToGiB(newSize))); err != nil { + return oldSize, err + } + + return newSize, nil +} + func (plugin *azureFilePlugin) ConstructVolumeSpec(volName, mountPath string) (*volume.Spec, error) { azureVolume := &v1.Volume{ Name: volName, diff --git a/pkg/volume/azure_file/azure_provision.go b/pkg/volume/azure_file/azure_provision.go index 882f496d12..76a9db87ce 100644 --- a/pkg/volume/azure_file/azure_provision.go +++ b/pkg/volume/azure_file/azure_provision.go @@ -38,9 +38,11 @@ var _ volume.ProvisionableVolumePlugin = &azureFilePlugin{} // azure cloud provider should implement it type azureCloudProvider interface { // create a file share - CreateFileShare(name, storageAccount, storageType, location string, requestGB int) (string, string, error) + CreateFileShare(name, storageAccount, storageType, location string, requestGiB int) (string, string, error) // delete a file share DeleteFileShare(accountName, key, name string) error + // resize a file share + ResizeFileShare(accountName, accountKey, name string, sizeGiB int) error } type azureFileDeleter struct { @@ -141,7 +143,7 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) { name = strings.Replace(name, "--", "-", -1) capacity := a.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)] requestBytes := capacity.Value() - requestGB := int(volume.RoundUpSize(requestBytes, 1024*1024*1024)) + requestGiB := int(volume.RoundUpSize(requestBytes, 1024*1024*1024)) secretNamespace := a.options.PVC.Namespace // Apply ProvisionerParameters (case-insensitive). We leave validation of // the values to the cloud provider. @@ -164,7 +166,7 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) { return nil, fmt.Errorf("claim.Spec.Selector is not supported for dynamic provisioning on Azure file") } - account, key, err := a.azureProvider.CreateFileShare(name, account, sku, location, requestGB) + account, key, err := a.azureProvider.CreateFileShare(name, account, sku, location, requestGiB) if err != nil { return nil, err } @@ -187,7 +189,7 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) { PersistentVolumeReclaimPolicy: a.options.PersistentVolumeReclaimPolicy, AccessModes: a.options.PVC.Spec.AccessModes, Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", requestGB)), + v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", requestGiB)), }, PersistentVolumeSource: v1.PersistentVolumeSource{ AzureFile: &v1.AzureFilePersistentVolumeSource{ diff --git a/plugin/pkg/admission/persistentvolume/resize/admission.go b/plugin/pkg/admission/persistentvolume/resize/admission.go index 9909f5f3fb..3d04ae812d 100644 --- a/plugin/pkg/admission/persistentvolume/resize/admission.go +++ b/plugin/pkg/admission/persistentvolume/resize/admission.go @@ -161,5 +161,8 @@ func (pvcr *persistentVolumeClaimResize) checkVolumePlugin(pv *api.PersistentVol return true } + if pv.Spec.AzureFile != nil { + return true + } return false }