Skip to content

Commit 895127d

Browse files
Cherrypick SKE changes
1 parent 8ec657b commit 895127d

File tree

5 files changed

+118
-49
lines changed

5 files changed

+118
-49
lines changed

Dockerfile

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -103,49 +103,6 @@ LABEL name="barbican-kms-plugin" \
103103

104104
CMD ["sh", "-c", "/bin/barbican-kms-plugin --socketpath ${socketpath} --cloud-config ${cloudconfig}"]
105105

106-
##
107-
## cinder-csi-plugin
108-
##
109-
110-
# step 1: copy all necessary files from Debian distro to /dest folder
111-
# all magic happens in tools/csi-deps.sh
112-
FROM --platform=${TARGETPLATFORM} ${DEBIAN_IMAGE} as cinder-csi-plugin-utils
113-
114-
RUN clean-install bash rsync mount udev btrfs-progs e2fsprogs xfsprogs util-linux
115-
COPY tools/csi-deps.sh /tools/csi-deps.sh
116-
RUN /tools/csi-deps.sh
117-
118-
# step 2: check if all necessary files are copied and work properly
119-
# the build have to finish without errors, but the result image will not be used
120-
FROM --platform=${TARGETPLATFORM} ${DISTROLESS_IMAGE} as cinder-csi-plugin-utils-check
121-
122-
COPY --from=cinder-csi-plugin-utils /dest /
123-
COPY --from=cinder-csi-plugin-utils /bin/sh /bin/sh
124-
COPY tools/csi-deps-check.sh /tools/csi-deps-check.sh
125-
126-
SHELL ["/bin/sh"]
127-
RUN /tools/csi-deps-check.sh
128-
129-
# step 3: build tiny cinder-csi-plugin image with only necessary files
130-
FROM --platform=${TARGETPLATFORM} ${DISTROLESS_IMAGE} as cinder-csi-plugin
131-
132-
# Copying csi-deps-check.sh simply ensures that the resulting image has a dependency
133-
# on cinder-csi-plugin-utils-check and therefore that the check has passed
134-
COPY --from=cinder-csi-plugin-utils-check /tools/csi-deps-check.sh /bin/csi-deps-check.sh
135-
COPY --from=cinder-csi-plugin-utils /dest /
136-
COPY --from=builder /build/cinder-csi-plugin /bin/cinder-csi-plugin
137-
COPY --from=certs /etc/ssl/certs /etc/ssl/certs
138-
139-
LABEL name="cinder-csi-plugin" \
140-
license="Apache Version 2.0" \
141-
maintainers="Kubernetes Authors" \
142-
description="Cinder CSI Plugin" \
143-
distribution-scope="public" \
144-
summary="Cinder CSI Plugin" \
145-
help="none"
146-
147-
CMD ["/bin/cinder-csi-plugin"]
148-
149106
##
150107
## k8s-keystone-auth
151108
##
@@ -222,3 +179,47 @@ LABEL name="octavia-ingress-controller" \
222179
help="none"
223180

224181
CMD ["/bin/octavia-ingress-controller"]
182+
183+
## SKE: Concourse only pushes the last built image. Therefore we have to move this to the bottom.
184+
##
185+
## cinder-csi-plugin
186+
##
187+
188+
# step 1: copy all necessary files from Debian distro to /dest folder
189+
# all magic heppens in tools/csi-deps.sh
190+
FROM --platform=${TARGETPLATFORM} ${DEBIAN_IMAGE} as cinder-csi-plugin-utils
191+
192+
RUN clean-install bash rsync mount udev btrfs-progs e2fsprogs xfsprogs
193+
COPY tools/csi-deps.sh /tools/csi-deps.sh
194+
RUN /tools/csi-deps.sh
195+
196+
# step 2: check if all necessary files are copied and work properly
197+
# the build have to finish without errors, but the result image will not be used
198+
FROM --platform=${TARGETPLATFORM} ${DISTROLESS_IMAGE} as cinder-csi-plugin-utils-check
199+
200+
COPY --from=cinder-csi-plugin-utils /dest /
201+
COPY --from=cinder-csi-plugin-utils /bin/sh /bin/sh
202+
COPY tools/csi-deps-check.sh /tools/csi-deps-check.sh
203+
204+
SHELL ["/bin/sh"]
205+
RUN /tools/csi-deps-check.sh
206+
207+
# step 3: build tiny cinder-csi-plugin image with only necessary files
208+
FROM --platform=${TARGETPLATFORM} ${DISTROLESS_IMAGE} as cinder-csi-plugin
209+
210+
# Copying csi-deps-check.sh simply ensures that the resulting image has a dependency
211+
# on cinder-csi-plugin-utils-check and therefore that the check has passed
212+
COPY --from=cinder-csi-plugin-utils-check /tools/csi-deps-check.sh /bin/csi-deps-check.sh
213+
COPY --from=cinder-csi-plugin-utils /dest /
214+
COPY --from=builder /build/cinder-csi-plugin /bin/cinder-csi-plugin
215+
COPY --from=certs /etc/ssl/certs /etc/ssl/certs
216+
217+
LABEL name="cinder-csi-plugin" \
218+
license="Apache Version 2.0" \
219+
maintainers="Kubernetes Authors" \
220+
description="Cinder CSI Plugin" \
221+
distribution-scope="public" \
222+
summary="Cinder CSI Plugin" \
223+
help="none"
224+
225+
CMD ["/bin/cinder-csi-plugin"]

pkg/csi/cinder/controllerserver.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"fmt"
2323
"sort"
2424
"strconv"
25+
"time"
2526

2627
"github.com/container-storage-interface/spec/lib/go/csi"
2728
"github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/backups"
@@ -32,6 +33,7 @@ import (
3233
"google.golang.org/grpc/codes"
3334
"google.golang.org/grpc/status"
3435
"google.golang.org/protobuf/types/known/timestamppb"
36+
"k8s.io/apimachinery/pkg/util/wait"
3537

3638
"k8s.io/cloud-provider-openstack/pkg/csi/cinder/openstack"
3739
"k8s.io/cloud-provider-openstack/pkg/util"
@@ -103,6 +105,10 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
103105
if volSizeGB != volumes[0].Size {
104106
return nil, status.Error(codes.AlreadyExists, "Volume Already exists with same name and different capacity")
105107
}
108+
109+
if volumes[0].Status != openstack.VolumeAvailableStatus {
110+
return nil, status.Error(codes.Internal, fmt.Sprintf("Volume %s is not in available state", volumes[0].ID))
111+
}
106112
klog.V(4).Infof("Volume %s already exists in Availability Zone: %s of size %d GiB", volumes[0].ID, volumes[0].AvailabilityZone, volumes[0].Size)
107113
return getCreateVolumeResponse(&volumes[0], ignoreVolumeAZ, req.GetAccessibilityRequirements()), nil
108114
} else if len(volumes) > 1 {
@@ -188,6 +194,18 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
188194
return nil, status.Errorf(codes.Internal, "CreateVolume failed with error %v", err)
189195
}
190196

197+
targetStatus := []string{openstack.VolumeAvailableStatus}
198+
err = cloud.WaitVolumeTargetStatusWithCustomBackoff(vol.ID, targetStatus,
199+
&wait.Backoff{
200+
Duration: 20 * time.Second,
201+
Steps: 5,
202+
Factor: 1.28,
203+
})
204+
if err != nil {
205+
klog.Errorf("Failed to WaitVolumeTargetStatus of volume %s: %v", vol.ID, err)
206+
return nil, status.Error(codes.Internal, fmt.Sprintf("CreateVolume Volume %s failed getting available in time: %v", vol.ID, err))
207+
}
208+
191209
klog.V(4).Infof("CreateVolume: Successfully created volume %s in Availability Zone: %s of size %d GiB", vol.ID, vol.AvailabilityZone, vol.Size)
192210

193211
return getCreateVolumeResponse(vol, ignoreVolumeAZ, req.GetAccessibilityRequirements()), nil

pkg/csi/cinder/openstack/openstack.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers"
3030
"github.com/spf13/pflag"
3131
gcfg "gopkg.in/gcfg.v1"
32+
"k8s.io/apimachinery/pkg/util/wait"
3233
"k8s.io/cloud-provider-openstack/pkg/client"
3334
"k8s.io/cloud-provider-openstack/pkg/metrics"
3435
"k8s.io/cloud-provider-openstack/pkg/util/metadata"
@@ -53,6 +54,7 @@ type IOpenStack interface {
5354
DetachVolume(instanceID, volumeID string) error
5455
WaitDiskDetached(instanceID string, volumeID string) error
5556
WaitVolumeTargetStatus(volumeID string, tStatus []string) error
57+
WaitVolumeTargetStatusWithCustomBackoff(volumeID string, tStatus []string, backoff *wait.Backoff) error
5658
GetAttachmentDiskPath(instanceID, volumeID string) (string, error)
5759
GetVolume(volumeID string) (*volumes.Volume, error)
5860
GetVolumesByName(name string) ([]volumes.Volume, error)

pkg/csi/cinder/openstack/openstack_mock.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/volumes"
2323
"github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers"
2424
"github.com/stretchr/testify/mock"
25+
"k8s.io/apimachinery/pkg/util/wait"
2526
"k8s.io/cloud-provider-openstack/pkg/util/metadata"
2627
)
2728

@@ -187,6 +188,20 @@ func (_m *OpenStackMock) WaitVolumeTargetStatus(volumeID string, tStatus []strin
187188
return r0
188189
}
189190

191+
// WaitVolumeTargetStatusWithCustomBackoff provides a mock function with given fields: volumeID, tStatus, backoff
192+
func (_m *OpenStackMock) WaitVolumeTargetStatusWithCustomBackoff(volumeID string, tStatus []string, backoff *wait.Backoff) error {
193+
ret := _m.Called(volumeID, tStatus, backoff)
194+
195+
var r0 error
196+
if rf, ok := ret.Get(0).(func(string, []string, *wait.Backoff) error); ok {
197+
r0 = rf(volumeID, tStatus, backoff)
198+
} else {
199+
r0 = ret.Error(0)
200+
}
201+
202+
return r0
203+
}
204+
190205
// WaitDiskDetached provides a mock function with given fields: instanceID, volumeID
191206
func (_m *OpenStackMock) WaitDiskDetached(instanceID string, volumeID string) error {
192207
ret := _m.Called(instanceID, volumeID)

pkg/csi/cinder/openstack/openstack_volumes.go

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ const (
3939
operationFinishInitDelay = 1 * time.Second
4040
operationFinishFactor = 1.1
4141
operationFinishSteps = 10
42-
diskAttachInitDelay = 1 * time.Second
43-
diskAttachFactor = 1.2
44-
diskAttachSteps = 15
45-
diskDetachInitDelay = 1 * time.Second
46-
diskDetachFactor = 1.2
47-
diskDetachSteps = 13
42+
diskAttachInitDelay = 7 * time.Second
43+
diskAttachFactor = 1.4
44+
diskAttachSteps = 10
45+
diskDetachInitDelay = 7 * time.Second
46+
diskDetachFactor = 1.4
47+
diskDetachSteps = 10
4848
volumeDescription = "Created by OpenStack Cinder CSI driver"
4949
)
5050

@@ -215,6 +215,12 @@ func (os *OpenStack) AttachVolume(instanceID, volumeID string) (string, error) {
215215
return "", fmt.Errorf("failed to attach %s volume to %s compute: %v", volumeID, instanceID, err)
216216
}
217217

218+
//redundant waitDiskAttached, workaround for raise condition in backend
219+
err = os.WaitDiskAttached(instanceID, volumeID)
220+
if err != nil {
221+
return "", err
222+
}
223+
218224
return volume.ID, nil
219225
}
220226

@@ -276,6 +282,33 @@ func (os *OpenStack) WaitVolumeTargetStatus(volumeID string, tStatus []string) e
276282
return waitErr
277283
}
278284

285+
// WaitVolumeTargetStatusWithCustomBackoff waits for volume to be in target state with custom backoff
286+
func (os *OpenStack) WaitVolumeTargetStatusWithCustomBackoff(volumeID string, tStatus []string, backoff *wait.Backoff) error {
287+
waitErr := wait.ExponentialBackoff(*backoff, func() (bool, error) {
288+
vol, err := os.GetVolume(volumeID)
289+
if err != nil {
290+
return false, err
291+
}
292+
for _, t := range tStatus {
293+
if vol.Status == t {
294+
return true, nil
295+
}
296+
}
297+
for _, eState := range volumeErrorStates {
298+
if vol.Status == eState {
299+
return false, fmt.Errorf("Volume is in Error State : %s", vol.Status)
300+
}
301+
}
302+
return false, nil
303+
})
304+
305+
if waitErr == wait.ErrWaitTimeout {
306+
waitErr = fmt.Errorf("Timeout on waiting for volume %s status to be in %v", volumeID, tStatus)
307+
}
308+
309+
return waitErr
310+
}
311+
279312
// DetachVolume detaches given cinder volume from the compute
280313
func (os *OpenStack) DetachVolume(instanceID, volumeID string) error {
281314
volume, err := os.GetVolume(volumeID)

0 commit comments

Comments
 (0)