Implement syncClaim with bound claims.

This commit is contained in:
Jan Safranek
2016-05-17 14:55:09 +02:00
parent eff6b50b93
commit 5949b956f5
2 changed files with 222 additions and 21 deletions

View File

@@ -417,7 +417,82 @@ func (ctrl *PersistentVolumeController) syncUnboundClaim(claim *api.PersistentVo
// syncBoundClaim is the main controller method to decide what to do with a
// bound claim.
func (ctrl *PersistentVolumeController) syncBoundClaim(claim *api.PersistentVolumeClaim) error {
return nil
// hasAnnotation(pvc, annBindCompleted)
// This PVC has previously been bound
// OBSERVATION: pvc is not "Pending"
// [Unit test set 3]
if claim.Spec.VolumeName == "" {
// Claim was bound before but not any more.
if claim.Status.Phase != api.ClaimLost {
// Log the error only once, when we enter 'Lost' phase
glog.V(3).Infof("synchronizing bound PersistentVolumeClaim[%s]: volume reference lost!", claimToClaimKey(claim))
}
// TODO: emit event and save reason
if _, err := ctrl.updateClaimPhase(claim, api.ClaimLost); err != nil {
return err
}
return nil
}
obj, found, err := ctrl.volumes.store.GetByKey(claim.Spec.VolumeName)
if err != nil {
return err
}
if !found {
// Claim is bound to a non-existing volume.
if claim.Status.Phase != api.ClaimLost {
// Log the error only once, when we enter 'Lost' phase
glog.V(3).Infof("synchronizing bound PersistentVolumeClaim[%s]: volume %q lost!", claimToClaimKey(claim), claim.Spec.VolumeName)
}
// TODO: emit event and save reason
if _, err = ctrl.updateClaimPhase(claim, api.ClaimLost); err != nil {
return err
}
return nil
} else {
volume, ok := obj.(*api.PersistentVolume)
if !ok {
return fmt.Errorf("Cannot convert object from volume cache to volume %q!?: %+v", claim.Spec.VolumeName, obj)
}
glog.V(4).Infof("synchronizing bound PersistentVolumeClaim[%s]: volume %q found: %s", claimToClaimKey(claim), claim.Spec.VolumeName, ctrl.getVolumeStatusForLogging(volume))
if volume.Spec.ClaimRef == nil {
// Claim is bound but volume has come unbound.
// Or, a claim was bound and the controller has not received updated
// volume yet. We can't distinguish these cases.
// Bind the volume again and set all states to Bound.
glog.V(4).Infof("synchronizing bound PersistentVolumeClaim[%s]: volume is unbound, fixing", claimToClaimKey(claim))
if err = ctrl.bind(volume, claim); err != nil {
// Objects not saved, next syncPV or syncClaim will try again
return err
}
return nil
} else if volume.Spec.ClaimRef.UID == claim.UID {
// All is well
// NOTE: syncPV can handle this so it can be left out.
// NOTE: bind() call here will do nothing in most cases as
// everything should be already set.
glog.V(4).Infof("synchronizing bound PersistentVolumeClaim[%s]: claim is already correctly bound", claimToClaimKey(claim))
if err = ctrl.bind(volume, claim); err != nil {
// Objects not saved, next syncPV or syncClaim will try again
return err
}
return nil
} else {
// Claim is bound but volume has a different claimant.
// Set the claim phase to 'Lost', which is a terminal
// phase.
otherClaimName := fmt.Sprintf("%s/%s", volume.Spec.ClaimRef.Namespace, volume.Spec.ClaimRef.Name)
if claim.Status.Phase != api.ClaimLost {
// Log the error only once, when we enter 'Lost' phase
glog.V(3).Infof("synchronizing bound PersistentVolumeClaim[%s]: volume %q bound to another claim %q, this claim is lost!", claimToClaimKey(claim), claim.Spec.VolumeName, otherClaimName)
}
// TODO: emit event and save reason
if _, err = ctrl.updateClaimPhase(claim, api.ClaimLost); err != nil {
return err
}
return nil
}
}
}
// syncVolume is the main controller method to decide what to do with a volume.