Change:
Investigate for the following volume plugins if they can be refactored to use volumeUtil.UnmountPath() azuredd cinder configmap downwardapi emptydir fc flexvolume git_repo iscsi rbd secret
configmap, secret, gitrepo and downwardapi use a wrapper unmounter that wrap EmptyDir and let it do the tear down. All of them use duplicated code and each of these plugins have their own private that returns the spec for emptydir. This can be extracted out into a common utility. Thing to keep in mind is to verify the of each of the empty_dir spec returned by the
The remaining plugins count the references before performing the unmount. This can be extracted in a separate utility. Thing to note here to ensure TearDownAt() for these plugins (azuredd cinder fc flexvolume iscsi rbd ) are guarded by a lock (Otherwise a concurrent SetupAt() can cause race conditions)
/sig storage
Issues go stale after 90d of inactivity. Mark the issue as fresh with . Stale issues rot after an additional 30d of inactivity and eventually close. Prevent issues from auto-closing with an comment. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle stale
Stale issues rot after 30d of inactivity. Mark the issue as fresh with . Rotten issues close after an additional 30d of inactivity. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle rotten /remove-lifecycle stale
Rotten issues close after 30d of inactivity. Reopen the issue with . Mark the issue as fresh with . Send feedback to sig-testing, kubernetes/test-infra and/or . /close

Discussion:
} func (c *configMapVolumeUnmounter) TearDownAt(dir string) error { <del> glog.V(3).Infof("Tearing down volume %v for pod %v at %v", c.volName, c.podUID, dir) // Wrap EmptyDir, let it do the teardown. wrapped, err := c.plugin.host.NewWrapperUnmounter(c.volName, wrappedVolumeSpec(), c.podUID) if err != nil { return err } return wrapped.TearDownAt(dir) </del> <ins> return volume.UnmountViaEmptyDir(dir, c.plugin.host, c.volName, wrappedVolumeSpec(), c.podUID) </ins> } func getVolumeSource(spec *volume.Spec) (*v1.ConfigMapVolumeSource, bool) {

} func (c *downwardAPIVolumeUnmounter) TearDownAt(dir string) error { <del> glog.V(3).Infof("Tearing down volume %v for pod %v at %v", c.volName, c.podUID, dir) // Wrap EmptyDir, let it do the teardown. wrapped, err := c.plugin.host.NewWrapperUnmounter(c.volName, wrappedVolumeSpec(), c.podUID) if err != nil { return err } return wrapped.TearDownAt(dir) </del> <ins> return volume.UnmountViaEmptyDir(dir, c.plugin.host, c.volName, wrappedVolumeSpec(), c.podUID) </ins> } func (b *downwardAPIVolumeMounter) getMetaDir() string {

// TearDownAt simply discards everything in the directory. func (ed *emptyDir) TearDownAt(dir string) error { <ins> if pathExists, pathErr := volumeutil.PathExists(dir); pathErr != nil { return fmt.Errorf("Error checking if path exists: %v", pathErr) } else if !pathExists { glog.Warningf("Warning: Unmount skipped because path does not exist: %v", dir) return nil } </ins> // Figure out the medium. medium, isMnt, err := ed.mountDetector.GetMountMedium(dir) if err != nil {

// TearDownAt simply deletes everything in the directory. func (c *gitRepoVolumeUnmounter) TearDownAt(dir string) error { <del> // Wrap EmptyDir, let it do the teardown. wrapped, err := c.plugin.host.NewWrapperUnmounter(c.volName, wrappedVolumeSpec(), c.podUID) if err != nil { return err } return wrapped.TearDownAt(dir) </del> <ins> return volume.UnmountViaEmptyDir(dir, c.plugin.host, c.volName, wrappedVolumeSpec(), c.podUID) </ins> } func getVolumeSource(spec *volume.Spec) (*v1.GitRepoVolumeSource, bool) {

} func (c *secretVolumeUnmounter) TearDownAt(dir string) error { <del> glog.V(3).Infof("Tearing down volume %v for pod %v at %v", c.volName, c.podUID, dir) // Wrap EmptyDir, let it do the teardown. wrapped, err := c.plugin.host.NewWrapperUnmounter(c.volName, wrappedVolumeSpec(), c.podUID) if err != nil { return err } return wrapped.TearDownAt(dir) </del> <ins> return volume.UnmountViaEmptyDir(dir, c.plugin.host, c.volName, wrappedVolumeSpec(), c.podUID) </ins> } func getVolumeSource(spec *volume.Spec) (*v1.SecretVolumeSource, bool) {

"github.com/golang/glog" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/resource" <ins> "k8s.io/kubernetes/pkg/types" </ins> "k8s.io/kubernetes/pkg/util/sets" <ins> volutil "k8s.io/kubernetes/pkg/volume/util" </ins> ) type RecycleEventRecorder func(eventtype, message string)

glog.V(2).Infof("Creating volume for PVC %q; chose zone=%q from zones=%q", pvcName, zone, zoneSlice) return zone } <ins> // UnmountViaEmptyDir delegates the tear down operation for secret, configmap, git_repo and downwardapi // to empty_dir func UnmountViaEmptyDir(dir string, host VolumeHost, volName string, volSpec Spec, podUID types.UID) error { glog.V(3).Infof("Tearing down volume %v for pod %v at %v", volName, podUID, dir) if pathExists, pathErr := volutil.PathExists(dir); pathErr != nil { return fmt.Errorf("Error checking if path exists: %v", pathErr) } else if !pathExists { glog.Warningf("Warning: Unmount skipped because path does not exist: %v", dir) return nil } // Wrap EmptyDir, let it do the teardown. wrapped, err := host.NewWrapperUnmounter(volName, volSpec, podUID) if err != nil { return err } return wrapped.TearDownAt(dir) } </ins>

"Generated release_1_5 clientset should create pods, delete pods, watch pods",rrati,0 "Generated release_1_5 clientset should create v2alpha1 cronJobs, delete cronJobs, watch cronJobs",soltysh,1 HA-master survive addition/removal replicas different zones,derekwaynecarr,0 <ins> HA-master survive addition/removal replicas multizone workers,rkouj,0 </ins> HA-master survive addition/removal replicas same zone,derekwaynecarr,0 Hazelcast should create and scale hazelcast,mikedanese,1 Horizontal pod autoscaling (scale resource: CPU) Deployment Should scale from 1 pod to 3 pods and from 3 to 5,jszczepkowski,0

k8s.io/kubernetes/pkg/kubelet/lifecycle,yujuhong,1 k8s.io/kubernetes/pkg/kubelet/network,freehan,0 k8s.io/kubernetes/pkg/kubelet/network/cni,freehan,0 <del> k8s.io/kubernetes/pkg/kubelet/network/exec,freehan,0 </del> k8s.io/kubernetes/pkg/kubelet/network/hairpin,freehan,0 k8s.io/kubernetes/pkg/kubelet/network/hostport,erictune,1 k8s.io/kubernetes/pkg/kubelet/network/kubenet,freehan,0