Skip to content
This repository was archived by the owner on Mar 16, 2024. It is now read-only.

Commit b5a6c7f

Browse files
authored
Merge pull request #2479 from StrongMonkey/fix-volume-delete
Fix: add logic to update volume reclaim policy to delete
2 parents 01ccd48 + df03e6e commit b5a6c7f

File tree

3 files changed

+85
-3
lines changed

3 files changed

+85
-3
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package volumes
2+
3+
import (
4+
"context"
5+
6+
"github.com/acorn-io/mink/pkg/strategy"
7+
"github.com/acorn-io/mink/pkg/strategy/remote"
8+
"github.com/acorn-io/mink/pkg/types"
9+
v1 "k8s.io/api/core/v1"
10+
)
11+
12+
type PolicySwitcherStrategy struct {
13+
strategy strategy.CompleteStrategy
14+
translator *Translator
15+
remote *remote.Remote
16+
}
17+
18+
// NewPolicySwitcherStrategy returns a new policy switcher strategy that switch persistvolume policy from retain to delete when the volume is being deleted.
19+
// This makes sure the actual storage resource is deleted when the volume is deleted.
20+
func NewPolicySwitcherStrategy(s strategy.CompleteStrategy, t *Translator, r *remote.Remote) strategy.Deleter {
21+
return &PolicySwitcherStrategy{
22+
translator: t,
23+
strategy: s,
24+
remote: r,
25+
}
26+
}
27+
28+
func (p *PolicySwitcherStrategy) Delete(ctx context.Context, obj types.Object) (types.Object, error) {
29+
pvName, err := p.translator.FromVolumeToPVName(ctx, obj.GetNamespace(), obj.GetName())
30+
if err != nil {
31+
return nil, err
32+
}
33+
pvObj, err := p.remote.Get(ctx, "", pvName)
34+
if err != nil {
35+
return nil, err
36+
}
37+
pv := pvObj.(*v1.PersistentVolume)
38+
pv.Spec.PersistentVolumeReclaimPolicy = v1.PersistentVolumeReclaimDelete
39+
_, err = p.remote.Update(ctx, pv)
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
return p.strategy.Delete(ctx, obj)
45+
}
46+
47+
func (p *PolicySwitcherStrategy) Get(ctx context.Context, namespace, name string) (types.Object, error) {
48+
return p.strategy.Get(ctx, namespace, name)
49+
}

pkg/server/registry/apigroups/acorn/volumes/storage.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,18 @@ import (
1313
)
1414

1515
func NewStorage(c kclient.WithWatch) rest.Storage {
16-
translated := translation.NewTranslationStrategy(&Translator{
16+
r := remote.NewRemote(&corev1.PersistentVolume{}, c)
17+
t := &Translator{
1718
c: c,
18-
}, remote.NewRemote(&corev1.PersistentVolume{}, c))
19+
}
20+
translated := translation.NewTranslationStrategy(t, r)
1921
remoteResource := publicname.NewStrategy(translated)
22+
policySwitcher := NewPolicySwitcherStrategy(remoteResource, t, r)
2023

2124
return stores.NewBuilder(c.Scheme(), &apiv1.Volume{}).
2225
WithGet(remoteResource).
2326
WithList(remoteResource).
24-
WithDelete(remoteResource).
27+
WithDelete(policySwitcher).
2528
WithWatch(remoteResource).
2629
WithTableConverter(tables.VolumeConverter).
2730
Build()

pkg/server/registry/apigroups/acorn/volumes/translator.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,36 @@ type Translator struct {
2121
c kclient.Client
2222
}
2323

24+
func (t *Translator) FromVolumeToPVName(ctx context.Context, namespace, name string) (string, error) {
25+
i := strings.LastIndex(name, ".")
26+
// If there is not a period, or string ends with period, parse it not as an alias
27+
if i == -1 || i+1 >= len(name) {
28+
return name, nil
29+
}
30+
31+
// parse it of the form <appName>.<shortVolName>
32+
prefix := name[:i]
33+
volumeName := name[i+1:]
34+
35+
pvs := &corev1.PersistentVolumeList{}
36+
err := t.c.List(ctx, pvs, &kclient.ListOptions{
37+
LabelSelector: klabels.SelectorFromSet(map[string]string{
38+
labels.AcornAppName: prefix,
39+
labels.AcornAppNamespace: namespace,
40+
labels.AcornVolumeName: volumeName,
41+
}),
42+
})
43+
if err != nil {
44+
return "", err
45+
}
46+
47+
if len(pvs.Items) == 1 {
48+
return pvs.Items[0].Name, nil
49+
}
50+
51+
return name, nil
52+
}
53+
2454
func (t *Translator) FromPublicName(ctx context.Context, namespace, name string) (string, string, error) {
2555
i := strings.LastIndex(name, ".")
2656
// If there is not a period, or string ends with period, parse it not as an alias

0 commit comments

Comments
 (0)