Skip to content

Commit d2fd670

Browse files
committed
fix: handle the case that a data disk is in an invalid state and make sure the finalizer does not hang
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
1 parent 64abd8c commit d2fd670

File tree

9 files changed

+142
-9
lines changed

9 files changed

+142
-9
lines changed

onprem/cr.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ type DataDiskCustomResourceSpec struct {
4747
TargetSelector *metav1.LabelSelector `json:"targetSelector"`
4848
}
4949

50+
type DataDiskStatus struct {
51+
// description of the data disk status
52+
Description string `json:"description"`
53+
// the status flag
54+
Status int `json:"status"`
55+
}
56+
5057
type OnPremCustomResource struct {
5158
metav1.TypeMeta `json:",inline"`
5259
// Standard object's metadata.
@@ -71,6 +78,9 @@ type DataDiskCustomResource struct {
7178
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
7279
// +optional
7380
Spec DataDiskCustomResourceSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
81+
82+
// status of this custom resource
83+
Status DataDiskStatus `json:"status,omitempty"`
7484
}
7585

7686
type OnPremCustomResourceOptions struct {

onprem/datadisk.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,17 @@ func DataDisksFromRelated(data map[string]any) ([]*DataDiskCustomResource, error
212212
// decode each disk
213213
for _, dataDisk := range dataDisks {
214214
// transcode to the expected format
215-
cfg, err := common.Transcode[*DataDiskCustomResource](dataDisk)
215+
disk, err := common.Transcode[*DataDiskCustomResource](dataDisk)
216216
if err != nil {
217217
return nil, err
218218
}
219-
result = append(result, cfg)
219+
// validate the status of the data disk
220+
if disk.Status.Status == 1 {
221+
result = append(result, disk)
222+
} else {
223+
// disk is not in a valid status
224+
log.Printf("Data Disk [%s] is not in ready state, ignoring, cause: [%s]", disk.Name, disk.Status.Description)
225+
}
220226
}
221227
}
222228
}

onprem/domain.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,9 @@ func shutDownDomain(client *LivirtClient) func(domain *libvirt.Domain) error {
194194
// check if the domain is running
195195
state, _, err := conn.DomainGetState(*domain, 0)
196196
if err != nil {
197-
return err
197+
// if we cannot get the domain state, assume it's gone
198+
log.Printf("Unable to get the domain state for domain [%s], err: [%v]", domain.Name, err)
199+
return nil
198200
}
199201
if libvirt.DomainState(state) != libvirt.DomainRunning {
200202
return nil
@@ -211,7 +213,9 @@ func shutDownDomain(client *LivirtClient) func(domain *libvirt.Domain) error {
211213
state, reason, err := conn.DomainGetState(*domain, 0)
212214
log.Printf("Domain State [%d], reason [%d]", state, reason)
213215
if err != nil {
214-
return err
216+
// if we cannot get the domain state, assume it's gone
217+
log.Printf("Unable to get the domain state for domain [%s], err: [%v]", domain.Name, err)
218+
return nil
215219
}
216220
// check for states that depict a shutdown system
217221
switch libvirt.DomainState(state) {
@@ -267,10 +271,14 @@ func DeleteDomainByName(client *LivirtClient) func(name string) error {
267271
delDomain := deleteDomain(client)
268272

269273
return func(name string) error {
274+
// log this
275+
log.Printf("Deleting domain by name [%s] ...", name)
270276
// locate the domain
271277
domain, err := conn.DomainLookupByName(name)
272278
// TODO check for domain does not exist
273279
if err != nil {
280+
// log this fact
281+
log.Printf("Domain [%s] cannot be located, assuming it's been deleted, cause: [%v]", name, err)
274282
return nil
275283
}
276284
// delete

onprem/volume.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ func getStorageVolByNameXMLDesc(conn *libvirt.Libvirt) func(pool libvirt.Storage
6161
}
6262
}
6363

64+
func GetStorageVolXMLDesc(client *LivirtClient) func(vol *libvirt.StorageVol) (*libvirtxml.StorageVolume, error) {
65+
return getStorageVolXMLDesc(client.LibVirt)
66+
}
67+
6468
func getStorageVolXMLDesc(conn *libvirt.Libvirt) func(vol *libvirt.StorageVol) (*libvirtxml.StorageVolume, error) {
6569
return func(vol *libvirt.StorageVol) (*libvirtxml.StorageVolume, error) {
6670
// try to get more info

server/datadisk/actions.go

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,63 @@
1515
package datadisk
1616

1717
import (
18+
"log"
19+
1820
"github.com/ibm-hyper-protect/k8s-operator-hpcr/onprem"
1921
"github.com/ibm-hyper-protect/k8s-operator-hpcr/server/common"
22+
C "github.com/ibm-hyper-protect/terraform-provider-hpcr/contract"
23+
"libvirt.org/go/libvirtxml"
2024
)
2125

26+
// createDataDiskReadyAction create the action
27+
func createDataDiskReadyAction(disk *libvirtxml.StorageVolume) common.Action {
28+
29+
return func() (*common.ResourceStatus, error) {
30+
// metadata to attach
31+
metadata := C.RawMap{
32+
"Name": disk.Name,
33+
}
34+
// marshal the disk info into metadata
35+
diskStrg, err := onprem.XMLMarshall(disk)
36+
if err == nil {
37+
metadata["diskXML"] = diskStrg
38+
} else {
39+
log.Printf("Unable to marshal the disk XML, cause: [%v]", err)
40+
}
41+
return &common.ResourceStatus{
42+
Status: common.Ready,
43+
Description: diskStrg,
44+
Error: nil,
45+
Metadata: metadata,
46+
}, nil
47+
}
48+
}
49+
2250
// CreateSyncAction synchronizes the state of the resource and determines what to do next
2351
func CreateSyncAction(client *onprem.LivirtClient, opt *onprem.DataDiskOptions) common.Action {
2452
// checks for the validity of the data disk
2553
isDataDiskValid := onprem.IsDataDiskValid(client)
26-
_, ok := isDataDiskValid(opt)
54+
diskXML, ok := isDataDiskValid(opt)
2755
if ok {
2856
// ready
29-
return common.CreateReadyAction()
57+
return createDataDiskReadyAction(diskXML)
3058
}
3159
// create a disk (will resize if required)
3260
diskSync := onprem.CreateDataDiskSync(client)
33-
_, err := diskSync(opt)
61+
disk, err := diskSync(opt)
3462
if err != nil {
63+
log.Printf("Unable to create data disk [%s], cause: [%v]", opt.Name, err)
64+
return common.CreateErrorAction(err)
65+
}
66+
// try to get the XML description
67+
getDiskXML := onprem.GetStorageVolXMLDesc(client)
68+
diskXML, err = getDiskXML(disk)
69+
if err != nil {
70+
log.Printf("Unable to get disk XML [%s], cause: [%v]", opt.Name, err)
3571
return common.CreateErrorAction(err)
3672
}
3773
// ready
38-
return common.CreateReadyAction()
74+
return createDataDiskReadyAction(diskXML)
3975
}
4076

4177
func CreateFinalizeAction(client *onprem.LivirtClient, opt *onprem.DataDiskOptions) common.Action {

server/onprem/actions.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ func CreateSyncAction(client *onprem.LivirtClient, opt *onprem.InstanceOptions)
116116
instSync := onprem.CreateInstanceSync(client)
117117
result, err := instSync(opt)
118118
if err != nil {
119+
log.Printf("Unable to create the VSI [%s], cause: [%v]", opt.Name, err)
119120
return common.CreateErrorAction(err)
120121
}
121122
// log the result
@@ -135,6 +136,7 @@ func CreateFinalizeAction(client *onprem.LivirtClient, opt *onprem.InstanceOptio
135136
deleteSync := onprem.DeleteInstanceSync(client)
136137
err := deleteSync(opt.StoragePool, opt.Name)
137138
if err != nil {
139+
log.Printf("Unable to delete the VSI [%s], cause: [%v]", opt.Name, err)
138140
return common.CreateErrorAction(err)
139141
}
140142
// done

server/onprem/onprem.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
C "github.com/ibm-hyper-protect/k8s-operator-hpcr/common"
2525
"github.com/ibm-hyper-protect/k8s-operator-hpcr/onprem"
2626
"github.com/ibm-hyper-protect/k8s-operator-hpcr/server/common"
27+
A "github.com/ibm-hyper-protect/terraform-provider-hpcr/fp/array"
2728
v1 "k8s.io/api/core/v1"
2829
)
2930

@@ -67,7 +68,15 @@ func syncOnPrem(req map[string]any) common.Action {
6768
return common.CreateErrorAction(err)
6869
}
6970

70-
log.Printf("DataDisks: %v", dataDisks)
71+
// dump the attached data disks
72+
if A.IsNonEmpty(dataDisks) {
73+
// extract names
74+
dataDiskNames := A.MonadMap(dataDisks, func(disk *onprem.DataDiskCustomResource) string {
75+
return disk.Name
76+
})
77+
// log the disks
78+
log.Printf("DataDisks: %v", dataDiskNames)
79+
}
7180

7281
// attach data disks
7382
opt.DataDisks = onprem.DataDiskCustomResourcesToAttachedDataDisks(dataDisks)
@@ -76,6 +85,7 @@ func syncOnPrem(req map[string]any) common.Action {
7685
return CreateSyncAction(client, opt)
7786
}
7887

88+
// finalizeOnPrem deletes a VSI
7989
func finalizeOnPrem(req map[string]any) common.Action {
8090
if !lock.TryLock() {
8191
return common.CreateStatusAction(common.Waiting)

tooling/data/busybox.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
kind: HyperProtectContainerRuntimeOnPrem
2+
apiVersion: hpse.ibm.com/v1
3+
metadata:
4+
name: busybox
5+
labels:
6+
app: hpcr
7+
spec:
8+
contract: |
9+
env: hyper-protect-basic.kdp9q+bIqUWhHBQ+0Bt+lCVLb65UhaWBhfgznuLCVR3RzwCqCoGlRMcZJ7/DleW+/c3fiPxD92LuK9fXPtuM1K4DWOg+SCn4xR0Pvw0ACXvs8+gcrHMm3DHgL4pd8cLygAAiLjYQqjuvyNTyBrxHMWs3X/qasenKqYKd0SeJ0UIb+SECAefIjrFHGg2yIxYkSq/39P2Ssc2wfyYmHIY4CyGPViidL6dSASkdAPTBjk4T2k5gCvE9xZjSiPr2uO+9RCpbpZAzctpPouamCDCrve50pAruxY4Ypn2wDzstRsdhydu0ZFisaXxU5oBhYCcNzDWrGZSAly8BdRNMbSpQBaxjQ2vNc/DGVVOaNwoTcsYyvW3zCc6SIeQ88gW8sjHYeHLnvMWedYQHIyoPnPFQlz1xWJcJsFndGr7OYFges0iyIr7u2jVgVcXbOkQZcdgCVhpBVf40E4uNHhYc+dWdzTnfpRlSXOuMy/Oy1wAPB6Z+rsklm2T189OOlLkWj+9KCcr6BuiNp7o38OwSAnbstXDUZziS+gV+w7LJCuOt2VFzJJ+huHgs8nyUmXVFhcfFvwlZZuSS5PEHAJYZloumnXcJ3ptgQJY8Y+fBkv3xea+Ztjmg9MF/Tarky4FvEG2DEsK7D5deLhUOxPqDPeMz+DGjYaOo7qgn1DyQh9046K8=.U2FsdGVkX1+Br9ZWBatGTfZ9JAQf8OeBQlVKFda/T1kFG058Pw3Q6Gn20vQ/8Y8MwVZfiMLuOsVVjX/x8ERnfwvUE5GLK3XElBA6SxZWfXShKm28I1WXyAI1JHAbXg/607g5KFyHRbrCFOK0He7ZPoDV0cGqnnR6dgrfCEYpkWL6A103kGFckmjASBKEv2k/DHqpTTHDuWZMmKiqF8uQhbG9az5ziiKSEKoLt0iw4Lnh9zowkGThvNy+ul3vshqIkKTQeS590J4jr1iZPQyeHcK3IlplRBoGKMOSakitjVbWK+GLYmkDlAX8KR1D5X4psE82yETTGk0rzAseKSHvOYpVlLlM0ClPkNHLEwpm81zfKRynP9m+FqThTWE6z8yXod4Lxa/kToX6fJjhgFJrGRB/HZeqD3armdU2xAWi3RdJGv3tb0CHeB8P0VF47aR46eRBCBVxu0mbdGS8g7g4YAWvdXiHx4KxnLDEZw830cL2ovCo0AV7hLjJiFjd4w7CpXIRfUIRs0pLwPYPAwlvndDiDsjCNYv84ZJtUP78muKM6Y4RCEGWrXENKFsEITDoXhHi2FnYko62oeH++LnRkgMO/ggN6PnTBH82zh2K2z9tXOI2J3yAm8oYZbd4lodbqFWgC5SUaa1kHxE1pMkwjlM9Ic+zCYezhNogHGtCKXlESsbRsXQz2hPJANUkGjID2Frq+c97zIhzaSojVbuCOPTRXO6b3Wa1I+EzZ3kyUWD5TdHK6eNmULCC5pKR8V9mzPq6bBdkEv/TpNPjkt47S6CjtuSvR5AqOiZjtNQ/nVK2jy8BPPsT4hYMOYs0s9Z0g35HwRbFKKdvtTLeho7JH676ohTvGV/6b8wHjUGCl9/A2jQTz1Yk8Npgd7z0R4TWHqChEiWfJyaE2hnhgCi09U/g/m//SZXOx8x/RDf9w1uA4L6tKYx7c64BA5YM7YgU1GPvhkFvDSrP1rXIE3qmJ+K8VMWovq5qhMg1Jw3OQRxp6tjA5bbXdaurBkKcjd6+JZDkiPpoAsaYGxGIehs43DvKtBObOjmilQLQuHVKrvalFZtTvEkAQ2ESweLafdoLcSc/D/gMip8grnVOxccM4s1FpY2bnbfVvD0s4YEIJb/DHNQLgZD++kmwx18efgqUpQs7v3c/NeLYOElVLJlwe1bvmOg7H54isBBEjkKVdC5CNCJsBAglTZVuQ/W3ZJL9udBn8iI4LHBdf5hSwjM6NYFnY3QIpdo2/JvO0KorIW/od5XuKUjtVXMgZbMkPjtdm15wRL2C+Lhakto2FSb6pd+t0jxAkgxwEO9EKOrtDShDVqq9c0zMQGo7bsube+TjBWFdtKqI4/dSq6mr44dwEA==
10+
envWorkloadSignature: 8SxEIJI2fDiON+01D11c7DJEmOyf0h/XNC1pOv5iJIS9pLe8Kw6BW2bAw8LiGL5Tj7HxWsiknGTbiuKwVWi0KcT4G8C9994oyFPNLzSOA7jOT0XA6xj98kHO/Q9iD6ThWeCJAJiGWkqfStd4/U86rxbh6cYee7dlSlv3IbhAu9a+0ziFZQlYG1uPLDcKabZt8M4Tb3gDNjIVlgY8g9fSgNQk7UquhexVkvk4NU+oEjQVGCDZbYRukGoNNODd0+LMtQIDnkjhLGZY54E7XvN1iS9xMQj3an9/g9rCnpdpmEcv/03p/Fz6Lm5VvYLX3poSigN1TgGQv4hn3CsPdlDTkRXDXVkreHQygnXTv9CuvLv6SYhr9vhdPOiDMrjMDYKjiBDSf2aGVqSYuN+Z8kWVjzF9WmDyLQrT82e+UEVwM4hJxCKYdBQtoB4CyjDuDaqWvb0/MEqFEWFwSnuaNgDu9NyFyJDlTW7QEapPuEHLP7VI3rf9AoYSrNgr+bVj8lOCFf5/ros00WXOBgAApQRoiishusFhPTSIgFOcBFGHzy9Pr704hmtX+VNXvvEtuCD1bJ3Ub2BFWm3AD/UVu+qhwBV/M/pmeEVuhLHoWxc8Jq7OVlrZghjmh9Oo+OA1jrymlj9tB4aIC3o21Jh6vvWT2W5/5qVqHGfFffY440B0Q9w=
11+
workload: hyper-protect-basic.WQGY6mI2eBig9IxBoERb4/Q8F0nnuGq3bskYxNphbuiu/ticd0Z0HorZMF8cjbg7poROiYcni2dLJmzDtWAJe0rv/WFEnOBfJ/PsHwu218SwkKoc4RxkkiawbU/6+RVGKSYAuAMJoOdixeLbBSLSduZ+Go5DGd6PnleVc4mD83ET0itP4A4nNUE71Aw7fi3+/Mx/u4SPjCXEMaKaT5cLJWhNsNllLoz9c6Mjpj5rToBaOAV+qurhEOtHqhZ4Ki2z8RSM4jXctUTfHZmrVzs/a0aWT2Scw5rNtjE1/B71os5sTx3SJxXVNXOqkR31fUjpwD+Y/lmdfuX2E9ePLNqPGGzkkXZSQtnmn13PvvIY3JoD3h1zYgwxjkopyDwdEqpq90o3QT5Cq8Gf5tV0WOhtJZFHoDMJdU0urIxyf1YFkj8Hij0Sdpw/sXAyeCsQIBXOz0LBmCXsxvC6VZine/6JpgB7KokX8ueKq7tztq4Kz8elKf44GHmg8P9Jpc7RN1FzzZ/16rAafWKsJzPj1TNfvI0uYRdKHXdXqE9gaOYhXJmL4j6ARflVxoUiys7z1Pxt3VBw9FWpxRDlJxT/dcTK8SPBBHXBAsf4T67K/OSTkKlVVbYyy61aNIFPH6ZvXN74hGO/vc3UAh+dGioP6TnlXJ0P+9TaiJycbTvv1+pZ/vg=.U2FsdGVkX18EYcoHOF2mGE7tS3M81nYMuE6xIUYvj2LOOk9vNHsBhYuCs8J0lTLSTVjZ4uAle3rl1+Xnr0BIXtIHydeAylGS+0zQD/ukMdt+6Q4iP/LcYtNxyr5Pl1s8BZlE5fzJXNPQzHFRpYzrVO1zBZCtxbB4XI6ks0WxbvNpr6uD0KyWv5cBWbiqR4Y41YWd2UJc4eqmbVTrb0s7x9w3IgZu3YDA0+ab+1+WseM4P+dlwV92DUIFA9kXGc/cuboBemNwuVPhm1IbE/tSveuN0bJbVGmQ/oCs0u9Ae5n9vlqVb8q15r6GeoK0BwBw6zsIJVYiLEEWUffEmiwgxEfU54jcEi6wjZMwB/F5di3V4otusCrB5WtYb1OOhIt1uCi01Kz2kJ+SLBzoQdpxF4x4w4bUjytD6hpw2evZVUbj1jYrWf4HxiSZSAWXUkZodKzFjPVAifpUAD6Q9+ET6OfsvSY0iAD6dya+ufYyoK1btl4nCz4wu9mE2Vn++IV5pDF+7GcjOvCQjzw/X8ueOg2h1hG59GgWj6PIPMLex8Y+qlw5JW+GoqKcSg/CSruvx+EUQzZ/wpG5/IlSPi316xM/BAQq22i4Ii+n+KXtOdZIrdeG93KXAYT12JpVchq7tNEj0r9iIqs+dEXWMg1TSvR3SHZQpPIsYy9V1za2MChIk/JsGrG+hjKdLAAQZ/y4TFXHn9Gz/QKnW8gSx42ROk2fRaUV0wx7CIf2TLYsDed7pUjNFDPjczHynEmWBILZHAoqprt4XefQ+LoLn5Gux+X4NDjHbEOSIE9I+yffZnHewnnIwa+dkO5R3zqvT8eY
12+
imageURL: http://hpcr-qcow2-image.default:8080/hpcr.qcow2
13+
storagePool: images
14+
targetSelector:
15+
matchLabels:
16+
config: onpremsample
17+
diskSelector:
18+
matchLabels:
19+
app: hpcr

tooling/data/webhook.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
apiVersion: apps/v1
3+
kind: Deployment
4+
metadata:
5+
name: k8s-operator-hpcr
6+
labels:
7+
hpcr: pod
8+
spec:
9+
replicas: 1
10+
selector:
11+
matchLabels:
12+
app: k8s-operator-hpcr
13+
template:
14+
metadata:
15+
labels:
16+
app: k8s-operator-hpcr
17+
spec:
18+
containers:
19+
- name: controller
20+
image: ghcr.io/ibm-hyper-protect/k8s-operator-hpcr:latest
21+
imagePullPolicy: Never
22+
resources:
23+
limits:
24+
memory: 512Mi
25+
cpu: "1"
26+
requests:
27+
memory: 256Mi
28+
cpu: "0.2"
29+
---
30+
apiVersion: v1
31+
kind: Service
32+
metadata:
33+
name: k8s-operator-hpcr
34+
spec:
35+
selector:
36+
app: k8s-operator-hpcr
37+
ports:
38+
- port: 8080

0 commit comments

Comments
 (0)