prevent engine upgrade from API level when the volume is non-healthy or the current engine image is not ready on all replicas nodes and the attaching node
Longhorn
@@ -820,13 +820,6 @@ func (m *VolumeManager) EngineUpgrade(volumeName, image string) (v *longhorn.Vol
return nil, err
}
- if isReady, err := m.ds.CheckEngineImageReadyOnAllVolumeReplicas(image, v.Name, v.Status.CurrentNodeID); !isReady {
- if err != nil {
- return nil, fmt.Errorf("cannot upgrade engine image for volume %v from image %v to image %v: %v", v.Name, v.Spec.EngineImage, image, err)
- }
- return nil, fmt.Errorf("cannot upgrade engine image for volume %v from image %v to image %v because the engine image %v is not deployed on the replicas' nodes or the node that the volume is attaching to", v.Name, v.Spec.EngineImage, image, image)
- }
-
if v.Spec.EngineImage == image {
return nil, fmt.Errorf("upgrading in process for volume %v engine image from %v to %v already",
v.Name, v.Status.CurrentImage, v.Spec.EngineImage)
@@ -837,14 +830,28 @@ func (m *VolumeManager) EngineUpgrade(volumeName, image string) (v *longhorn.Vol
v.Name, v.Status.CurrentImage, v.Spec.EngineImage)
}
+ if isReady, err := m.ds.CheckEngineImageReadyOnAllVolumeReplicas(image, v.Name, v.Status.CurrentNodeID); !isReady {
+ if err != nil {
+ return nil, fmt.Errorf("cannot upgrade engine image for volume %v from image %v to image %v: %v", v.Name, v.Spec.EngineImage, image, err)
+ }
+ return nil, fmt.Errorf("cannot upgrade engine image for volume %v from image %v to image %v because the engine image %v is not deployed on the replicas' nodes or the node that the volume is attaching to", v.Name, v.Spec.EngineImage, image, image)
+ }
+
+ if isReady, err := m.ds.CheckEngineImageReadyOnAllVolumeReplicas(v.Status.CurrentImage, v.Name, v.Status.CurrentNodeID); !isReady {
+ if err != nil {
+ return nil, fmt.Errorf("cannot upgrade engine image for volume %v from image %v to image %v: %v", v.Name, v.Spec.EngineImage, image, err)
+ }
+ return nil, fmt.Errorf("cannot upgrade engine image for volume %v from image %v to image %v because the volume's current engine image %v is not deployed on the replicas' nodes or the node that the volume is attaching to", v.Name, v.Spec.EngineImage, image, v.Status.CurrentImage)
+ }
+
if v.Spec.MigrationNodeID != "" {
return nil, fmt.Errorf("cannot upgrade during migration")
}
- // TODO: Rebuild is not supported for old DR volumes and the handling of a degraded DR volume live upgrade will get stuck.
- // Hence the live upgrade should be prevented in API level. After all old DR volumes are gone, this check can be removed.
- if v.Status.State == types.VolumeStateAttached && v.Status.IsStandby && v.Status.Robustness != types.VolumeRobustnessHealthy {
- return nil, fmt.Errorf("cannot do live upgrade for a non-healthy DR volume %v", v.Name)
+ // Note: Rebuild is not supported for old DR volumes and the handling of a degraded DR volume live upgrade will get stuck.
+ // Hence if you modify this part, the live upgrade should be prevented in API level for all old DR volumes.
+ if v.Status.State == types.VolumeStateAttached && v.Status.Robustness != types.VolumeRobustnessHealthy {
+ return nil, fmt.Errorf("cannot do live upgrade for a non-healthy volume %v", v.Name)
}
oldImage := v.Spec.EngineImage
