-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(migrate): add support to rename spc while migrating to cspc #13
Changes from all commits
38230ef
9e26e89
4fc2334
3263818
7680ba2
c09a98d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
1.11.0 | ||
1.12.0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,6 +65,12 @@ type CSPCMigrator struct { | |
CSPCObj *cstor.CStorPoolCluster | ||
SPCObj *apis.StoragePoolClaim | ||
OpenebsNamespace string | ||
CSPCName string | ||
} | ||
|
||
// SetCSPCName is used to initialize custom name if provided | ||
func (c *CSPCMigrator) SetCSPCName(name string) { | ||
c.CSPCName = name | ||
} | ||
|
||
// Migrate ... | ||
|
@@ -86,6 +92,13 @@ func (c *CSPCMigrator) Migrate(name, namespace string) error { | |
if err != nil { | ||
return err | ||
} | ||
if c.CSPCName == "" { | ||
c.CSPCName = name | ||
shubham14bajpai marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
err = c.checkForExistingCSPC(name) | ||
if err != nil { | ||
return err | ||
} | ||
err = c.migrate(name) | ||
return err | ||
} | ||
|
@@ -133,12 +146,12 @@ func (c *CSPCMigrator) migrate(spcName string) error { | |
if err != nil { | ||
return errors.Wrapf(err, "failed to validate spc %s", spcName) | ||
} | ||
err = c.updateBDCLabels(spcName) | ||
err = c.updateBDCLabels() | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to update bdc labels for spc %s", spcName) | ||
} | ||
klog.Infof("Creating equivalent cspc for spc %s", spcName) | ||
c.CSPCObj, err = c.generateCSPC() | ||
klog.Infof("Creating equivalent cspc %s for spc %s", c.CSPCName, spcName) | ||
c.CSPCObj, err = c.generateCSPC(spcName) | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -178,6 +191,63 @@ func (c *CSPCMigrator) migrate(spcName string) error { | |
return nil | ||
} | ||
|
||
// checkForExistingCSPC verifies the migration as follows: | ||
// spc = getSPC | ||
// 1. if spc does not exist | ||
// return nil (getSPCWithMigrationStatus will handle it) | ||
// cspc = getCSPC(from flag or same as spc) | ||
// 2. if cspc exist && | ||
// a. spc has anno with cspc-name && cspc has migration anno with spc-name | ||
// return nil | ||
// b. else | ||
// return err cspc already exists | ||
// 3. if cspc does not exist && | ||
// a. spc has no anno | ||
// patch spc with anno | ||
// b. spc has diff anno than current cspc-name | ||
// return err | ||
func (c *CSPCMigrator) checkForExistingCSPC(spcName string) error { | ||
spcObj, err := spc.NewKubeClient().Get(spcName, metav1.GetOptions{}) | ||
if err != nil && !k8serrors.IsNotFound(err) { | ||
return err | ||
} | ||
if k8serrors.IsNotFound(err) { | ||
return nil | ||
} | ||
cspc, err := c.OpenebsClientset.CstorV1(). | ||
CStorPoolClusters(c.OpenebsNamespace). | ||
Get(c.CSPCName, metav1.GetOptions{}) | ||
if err != nil && !k8serrors.IsNotFound(err) { | ||
return err | ||
} | ||
if err == nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now I have another concern with configuration if the user does in below manner:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can overcome this by adding old spc name on the cspc and verify that it isn't from another migrated spc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still, this problem exists but now it will patch SPC and fail(Can we prevent updating SPC annotation itself?) @shubham14bajpai |
||
if spcObj.Annotations[types.CStorPoolClusterLabelKey] == c.CSPCName && | ||
cspc.Annotations["openebs.io/migrated-from"] == spcName { | ||
return nil | ||
} | ||
return errors.Errorf( | ||
"failed to validate migration: the spc %s is set to be renamed as %s, but got cspc-name %s instead", | ||
spcName, | ||
spcObj.Annotations[types.CStorPoolClusterLabelKey], | ||
c.CSPCName, | ||
) | ||
} | ||
if k8serrors.IsNotFound(err) { | ||
if spcObj.Annotations == nil || spcObj.Annotations[types.CStorPoolClusterLabelKey] == "" { | ||
return addCSPCAnnotationToSPC(spcObj, c.CSPCName) | ||
} | ||
if spcObj.Annotations[types.CStorPoolClusterLabelKey] != c.CSPCName { | ||
return errors.Errorf( | ||
"failed to validate migration: the spc %s is set to be renamed as %s, but got cspc-name %s instead", | ||
spcName, | ||
spcObj.Annotations[types.CStorPoolClusterLabelKey], | ||
c.CSPCName, | ||
) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// validateSPC determines that if the spc is allowed to migrate or not. | ||
// If the max pool count does not match the number of csp in case auto spc provisioning, | ||
// or the blocldevice list in spc does not match bds from the csp, in case of manual provisioning | ||
|
@@ -232,9 +302,9 @@ func (c *CSPCMigrator) getSPCWithMigrationStatus(spcName string) (*apis.StorageP | |
if k8serrors.IsNotFound(err) { | ||
klog.Infof("spc %s not found.", spcName) | ||
_, err = c.OpenebsClientset.CstorV1(). | ||
CStorPoolClusters(c.OpenebsNamespace).Get(spcName, metav1.GetOptions{}) | ||
CStorPoolClusters(c.OpenebsNamespace).Get(c.CSPCName, metav1.GetOptions{}) | ||
if err != nil { | ||
return nil, false, errors.Wrapf(err, "failed to get equivalent cspc for spc %s", spcName) | ||
return nil, false, errors.Wrapf(err, "failed to get equivalent cspc %s for spc %s", c.CSPCName, spcName) | ||
} | ||
return nil, true, nil | ||
} | ||
|
@@ -248,7 +318,7 @@ func (c *CSPCMigrator) getSPCWithMigrationStatus(spcName string) (*apis.StorageP | |
func (c *CSPCMigrator) cspTocspi(cspiObj *cstor.CStorPoolInstance) error { | ||
var err1 error | ||
hostnameLabel := types.HostNameLabelKey + "=" + cspiObj.Labels[types.HostNameLabelKey] | ||
spcLabel := string(apis.StoragePoolClaimCPK) + "=" + c.CSPCObj.Name | ||
spcLabel := string(apis.StoragePoolClaimCPK) + "=" + c.SPCObj.Name | ||
cspLabel := hostnameLabel + "," + spcLabel | ||
cspObj, err := getCSP(cspLabel) | ||
if err != nil { | ||
|
@@ -374,9 +444,9 @@ func (c *CSPCMigrator) scaleDownDeployment(cspObj *apis.CStorPool, openebsNamesp | |
|
||
// Update the bdc with the cspc labels instead of spc labels to allow | ||
// filtering of bds claimed by the migrated cspc. | ||
func (c *CSPCMigrator) updateBDCLabels(cspcName string) error { | ||
func (c *CSPCMigrator) updateBDCLabels() error { | ||
bdcList, err := c.OpenebsClientset.OpenebsV1alpha1().BlockDeviceClaims(c.OpenebsNamespace).List(metav1.ListOptions{ | ||
LabelSelector: string(apis.StoragePoolClaimCPK) + "=" + cspcName, | ||
LabelSelector: string(apis.StoragePoolClaimCPK) + "=" + c.SPCObj.Name, | ||
}) | ||
if err != nil { | ||
return err | ||
|
@@ -387,7 +457,7 @@ func (c *CSPCMigrator) updateBDCLabels(cspcName string) error { | |
bdcObj := &bdcItem | ||
klog.Infof("Updating bdc %s with cspc labels & finalizer.", bdcObj.Name) | ||
delete(bdcObj.Labels, string(apis.StoragePoolClaimCPK)) | ||
bdcObj.Labels[types.CStorPoolClusterLabelKey] = cspcName | ||
bdcObj.Labels[types.CStorPoolClusterLabelKey] = c.CSPCName | ||
for i, finalizer := range bdcObj.Finalizers { | ||
if finalizer == spcFinalizer { | ||
bdcObj.Finalizers[i] = cspcFinalizer | ||
|
@@ -466,13 +536,28 @@ func (c *CSPCMigrator) updateCVRsLabels(cspObj *apis.CStorPool, cspiObj *cstor.C | |
|
||
func addSkipAnnotationToSPC(spcObj *apis.StoragePoolClaim) error { | ||
retry: | ||
spcObj.Annotations = map[string]string{ | ||
"openebs.io/skip-validations": "true", | ||
if spcObj.Annotations == nil { | ||
spcObj.Annotations = map[string]string{} | ||
} | ||
spcObj.Annotations["openebs.io/skip-validations"] = "true" | ||
_, err := spc.NewKubeClient().Update(spcObj) | ||
if k8serrors.IsConflict(err) { | ||
klog.Errorf("failed to update spc with skip-validation annotation due to conflict error") | ||
goto retry | ||
} | ||
return err | ||
} | ||
|
||
func addCSPCAnnotationToSPC(spcObj *apis.StoragePoolClaim, cspcName string) error { | ||
retry: | ||
if spcObj.Annotations == nil { | ||
spcObj.Annotations = map[string]string{} | ||
} | ||
spcObj.Annotations[types.CStorPoolClusterLabelKey] = cspcName | ||
_, err := spc.NewKubeClient().Update(spcObj) | ||
if k8serrors.IsConflict(err) { | ||
klog.Errorf("failed to update spc with cspc annotation due to conflict error") | ||
shubham14bajpai marked this conversation as resolved.
Show resolved
Hide resolved
|
||
goto retry | ||
} | ||
return err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Instead of passing spcName as an argument we can make use of
c.SPCObj.Name