Change:
Kubernetes version (use ): Client Version: version.Info{Major:"1", Minor:"6+", GitVersion:"v1.6.0-alpha.0.345+-dirty", GitCommit:"", GitTreeState:"dirty", BuildDate:"2016-11-10T06:07:31Z", GoVersion:"go1.7.3", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"6+", GitVersion:"v1.6.0-alpha.0.345+-dirty", GitCommit:"", GitTreeState:"dirty", BuildDate:"2016-11-10T06:07:31Z", GoVersion:"go1.7.3", Compiler:"gc", Platform:"linux/amd64"} Environment: Linux Cloud provider or hardware configuration: OS (e.g. from /etc/os-release): RHEL 7.3 Install tools: hack/local-up- What happened: storage class pvc annotated with this storage class a pod consume this pvc read/write function with the mounted path pod/pvc the pv status which is "Failed" What you expected to happen: PV should not have "Failed" status before deleted How to reproduce it (as minimally and precisely as possible): Always Anything else do we need to know:
cc
Per message The disk is still being attached. As a result, PV cannot be deleted.
This condition is handled by the PV framework. See However the volume plugin must return which it looks like the Azure volume plugin is not doing.
please help remove label, kubectl can't do anything with this.

Discussion:
"//pkg/cloudprovider:go_default_library", "//pkg/types:go_default_library", "//pkg/util/errors:go_default_library", <ins> "//pkg/volume:go_default_library", </ins> "//vendor:github.com/Azure/azure-sdk-for-go/arm/compute", "//vendor:github.com/Azure/azure-sdk-for-go/arm/network", "//vendor:github.com/Azure/azure-sdk-for-go/arm/storage",

import ( "fmt" "regexp" <ins> "strings" </ins> azs "github.com/Azure/azure-sdk-for-go/storage" )

name = name + ".vhd" err = blobClient.PutPageBlob(vhdContainerName, name, vhdSize, tags) if err != nil { <ins> // if container doesn't exist, create one and retry PutPageBlob detail := err.Error() if strings.Contains(detail, errContainerNotFound) { err = blobClient.CreateContainer(vhdContainerName, azs.ContainerAccessTypeContainer) if err == nil { err = blobClient.PutPageBlob(vhdContainerName, name, vhdSize, tags) } } } if err != nil { </ins> return "", "", fmt.Errorf("failed to put page blob: %v", err) } // add VHD signature to the blob h, err := createVHDHeader(uint64(size)) if err != nil {

"github.com/golang/glog" "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/types" <ins> "k8s.io/kubernetes/pkg/volume" </ins> ) const ( <del> maxLUN = 64 // max number of LUNs per VM </del> <ins> maxLUN               = 64 // max number of LUNs per VM errLeaseFailed       = "AcquireDiskLeaseFailed" errLeaseIDMissing    = "LeaseIdMissing" errContainerNotFound = "ContainerNotFound" </ins> ) // AttachDisk attaches a vhd to vm

if err != nil { glog.Errorf("azure attach failed, err: %v", err) detail := err.Error() <del> if strings.Contains(detail, "Code="AcquireDiskLeaseFailed"") { </del> <ins> if strings.Contains(detail, errLeaseFailed) { </ins> // if lease cannot be acquired, immediately detach the disk and return the original error glog.Infof("failed to acquire disk lease, try detach") az.DetachDiskByName(diskName, diskURI, nodeName)

err = az.deleteVhdBlob(accountName, key, blob) if err != nil { glog.Warningf("failed to delete blob %s err: %v", uri, err) <ins> detail := err.Error() if strings.Contains(detail, errLeaseIDMissing) { // disk is still being used // see https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.blob.protocol.bloberrorcodestrings.leaseidmissing.aspx return volume.NewDeletedVolumeInUseError(fmt.Sprintf("disk %q is still in use while being deleted", name)) } </ins> return fmt.Errorf("failed to delete vhd %v, account %s, blob %s, err: %v", uri, accountName, blob, err) } glog.V(4).Infof("blob %s deleted", uri)