Commit fc988d42 authored by andyzhangx's avatar andyzhangx

initial work for azure file grow size implementation

enable azure file grow size fix according to comments fix comments fix review comments fix comments
parent db673bde
...@@ -102,6 +102,7 @@ func ProbeExpandableVolumePlugins(config componentconfig.VolumeConfiguration) [] ...@@ -102,6 +102,7 @@ func ProbeExpandableVolumePlugins(config componentconfig.VolumeConfiguration) []
allPlugins = append(allPlugins, glusterfs.ProbeVolumePlugins()...) allPlugins = append(allPlugins, glusterfs.ProbeVolumePlugins()...)
allPlugins = append(allPlugins, rbd.ProbeVolumePlugins()...) allPlugins = append(allPlugins, rbd.ProbeVolumePlugins()...)
allPlugins = append(allPlugins, azure_dd.ProbeVolumePlugins()...) allPlugins = append(allPlugins, azure_dd.ProbeVolumePlugins()...)
allPlugins = append(allPlugins, azure_file.ProbeVolumePlugins()...)
allPlugins = append(allPlugins, photon_pd.ProbeVolumePlugins()...) allPlugins = append(allPlugins, photon_pd.ProbeVolumePlugins()...)
allPlugins = append(allPlugins, scaleio.ProbeVolumePlugins()...) allPlugins = append(allPlugins, scaleio.ProbeVolumePlugins()...)
allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...) allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...)
......
...@@ -31,13 +31,13 @@ const ( ...@@ -31,13 +31,13 @@ const (
// FileClient is the interface for creating file shares, interface for test // FileClient is the interface for creating file shares, interface for test
// injection. // injection.
type FileClient interface { 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 deleteFileShare(accountName, accountKey, name string) error
} }
// create file share // create file share
func (az *Cloud) createFileShare(accountName, accountKey, name string, sizeGB int) error { func (az *Cloud) createFileShare(accountName, accountKey, name string, sizeGiB int) error {
return az.FileClient.createFileShare(accountName, accountKey, name, sizeGB) return az.FileClient.createFileShare(accountName, accountKey, name, sizeGiB)
} }
func (az *Cloud) deleteFileShare(accountName, accountKey, name string) error { func (az *Cloud) deleteFileShare(accountName, accountKey, name string) error {
...@@ -48,7 +48,7 @@ type azureFileClient struct { ...@@ -48,7 +48,7 @@ type azureFileClient struct {
env azure.Environment 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) fileClient, err := f.getFileSvcClient(accountName, accountKey)
if err != nil { if err != nil {
return err return err
...@@ -62,7 +62,7 @@ func (f *azureFileClient) createFileShare(accountName, accountKey, name string, ...@@ -62,7 +62,7 @@ func (f *azureFileClient) createFileShare(accountName, accountKey, name string,
if err = share.Create(nil); err != nil { if err = share.Create(nil); err != nil {
return fmt.Errorf("failed to create file share, err: %v", err) 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.SetProperties(nil); err != nil {
if err := share.Delete(nil); err != nil { if err := share.Delete(nil); err != nil {
glog.Errorf("Error deleting share: %v", err) glog.Errorf("Error deleting share: %v", err)
......
...@@ -23,7 +23,7 @@ import ( ...@@ -23,7 +23,7 @@ import (
) )
// CreateFileShare creates a file share, using a matching storage account // 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 var errResult error
accounts := []accountWithLocation{} accounts := []accountWithLocation{}
if len(storageAccount) > 0 { if len(storageAccount) > 0 {
...@@ -46,7 +46,7 @@ func (az *Cloud) CreateFileShare(name, storageAccount, storageType, location str ...@@ -46,7 +46,7 @@ func (az *Cloud) CreateFileShare(name, storageAccount, storageType, location str
continue 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) errResult = fmt.Errorf("failed to create share %s in account %s: %v", name, account.Name, innerErr)
continue continue
} }
...@@ -69,3 +69,24 @@ func (az *Cloud) DeleteFileShare(accountName, key, name string) error { ...@@ -69,3 +69,24 @@ func (az *Cloud) DeleteFileShare(accountName, key, name string) error {
glog.V(4).Infof("share %s deleted", name) glog.V(4).Infof("share %s deleted", name)
return nil 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
}
...@@ -21,16 +21,16 @@ import ( ...@@ -21,16 +21,16 @@ import (
"os" "os"
"runtime" "runtime"
"github.com/golang/glog"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/cloudprovider/providers/azure"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
kstrings "k8s.io/kubernetes/pkg/util/strings" kstrings "k8s.io/kubernetes/pkg/util/strings"
"k8s.io/kubernetes/pkg/volume" "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" "k8s.io/kubernetes/pkg/volume/util"
) )
...@@ -45,6 +45,7 @@ type azureFilePlugin struct { ...@@ -45,6 +45,7 @@ type azureFilePlugin struct {
var _ volume.VolumePlugin = &azureFilePlugin{} var _ volume.VolumePlugin = &azureFilePlugin{}
var _ volume.PersistentVolumePlugin = &azureFilePlugin{} var _ volume.PersistentVolumePlugin = &azureFilePlugin{}
var _ volume.ExpandableVolumePlugin = &azureFilePlugin{}
const ( const (
azureFilePluginName = "kubernetes.io/azure-file" azureFilePluginName = "kubernetes.io/azure-file"
...@@ -139,6 +140,41 @@ func (plugin *azureFilePlugin) newUnmounterInternal(volName string, podUID types ...@@ -139,6 +140,41 @@ func (plugin *azureFilePlugin) newUnmounterInternal(volName string, podUID types
}}, nil }}, 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) { func (plugin *azureFilePlugin) ConstructVolumeSpec(volName, mountPath string) (*volume.Spec, error) {
azureVolume := &v1.Volume{ azureVolume := &v1.Volume{
Name: volName, Name: volName,
......
...@@ -38,9 +38,11 @@ var _ volume.ProvisionableVolumePlugin = &azureFilePlugin{} ...@@ -38,9 +38,11 @@ var _ volume.ProvisionableVolumePlugin = &azureFilePlugin{}
// azure cloud provider should implement it // azure cloud provider should implement it
type azureCloudProvider interface { type azureCloudProvider interface {
// create a file share // 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 // delete a file share
DeleteFileShare(accountName, key, name string) error DeleteFileShare(accountName, key, name string) error
// resize a file share
ResizeFileShare(accountName, accountKey, name string, sizeGiB int) error
} }
type azureFileDeleter struct { type azureFileDeleter struct {
...@@ -141,7 +143,7 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) { ...@@ -141,7 +143,7 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) {
name = strings.Replace(name, "--", "-", -1) name = strings.Replace(name, "--", "-", -1)
capacity := a.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)] capacity := a.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
requestBytes := capacity.Value() requestBytes := capacity.Value()
requestGB := int(volume.RoundUpSize(requestBytes, 1024*1024*1024)) requestGiB := int(volume.RoundUpSize(requestBytes, 1024*1024*1024))
secretNamespace := a.options.PVC.Namespace secretNamespace := a.options.PVC.Namespace
// Apply ProvisionerParameters (case-insensitive). We leave validation of // Apply ProvisionerParameters (case-insensitive). We leave validation of
// the values to the cloud provider. // the values to the cloud provider.
...@@ -164,7 +166,7 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) { ...@@ -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") 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 { if err != nil {
return nil, err return nil, err
} }
...@@ -187,7 +189,7 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) { ...@@ -187,7 +189,7 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) {
PersistentVolumeReclaimPolicy: a.options.PersistentVolumeReclaimPolicy, PersistentVolumeReclaimPolicy: a.options.PersistentVolumeReclaimPolicy,
AccessModes: a.options.PVC.Spec.AccessModes, AccessModes: a.options.PVC.Spec.AccessModes,
Capacity: v1.ResourceList{ 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{ PersistentVolumeSource: v1.PersistentVolumeSource{
AzureFile: &v1.AzureFilePersistentVolumeSource{ AzureFile: &v1.AzureFilePersistentVolumeSource{
......
...@@ -161,5 +161,8 @@ func (pvcr *persistentVolumeClaimResize) checkVolumePlugin(pv *api.PersistentVol ...@@ -161,5 +161,8 @@ func (pvcr *persistentVolumeClaimResize) checkVolumePlugin(pv *api.PersistentVol
return true return true
} }
if pv.Spec.AzureFile != nil {
return true
}
return false return false
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment