Skip to content
This repository was archived by the owner on Oct 21, 2020. It is now read-only.
This repository was archived by the owner on Oct 21, 2020. It is now read-only.

Implementation of LabelSelector for snapshots #875

Closed
@alpe

Description

@alpe

This is more a question why they are disabled? And is there an alternative solution to this?

In my scenario I create snapshots on GCP by a cronjob every x hours. These snapshots are supposed to be used by a StatefulSet volumeClaimTemplates when spanning new Pods to speed up startup time (dramatically).
Unfortunately I can not modify the volumeClaimTemplates to match the new snapshot name due to k8s restrictions or reuse the snapshot name as I don't want to mess with the CRDs. I am keeping a history of y-versions.

So it feels very natural to me to use the LabelSelector within the volumeClaimTemplate to select by a label rather than a name.
I could have some definition like this in my STS:

...
  volumeClaimTemplates:
  - metadata:
      name: mydir
    spec:
      accessModes:
        - ReadWriteOnce
      storageClassName: snapshot-promoter
      resources:
        requests:
          storage: 10Gi
      selector:
        matchLabels:
          group: "my_group"
        matchExpressions:
        - {key: approved, operator: Exists}

A modification to the provisioner could load the snapshot via Selector. With priority to the SnapshotPVCAnnotation and for multiple matches to the snapshotMetadataTimeStamp:

func (p *snapshotProvisioner) loadSnapshot(options controller.VolumeOptions) (crdv1.VolumeSnapshot, error) {
	var snapshot crdv1.VolumeSnapshot
	snapshotName, ok := options.PVC.Annotations[crdclient.SnapshotPVCAnnotation]
	if ok { // by name first
		err := p.crdclient.Get().
			Resource(crdv1.VolumeSnapshotResourcePlural).
			Namespace(options.PVC.Namespace).
			Name(snapshotName).
			Do().Into(&snapshot)

		if err != nil {
			return snapshot, fmt.Errorf("failed to retrieve VolumeSnapshot %s: %v", snapshotName, err)
		}
	} else {
		// by selector
		selector := options.PVC.Spec.Selector
		if selector == nil {
			return snapshot, errors.New("no claim selector nor snapshot annotation found on PV")
		}
		if len(selector.MatchLabels) == 0 || len(selector.MatchExpressions) == 0 {
			return snapshot, errors.New("label selector must not be empty")
		}
		var snapshots crdv1.VolumeSnapshotList
		err := p.crdclient.Get().
			Resource(crdv1.VolumeSnapshotResourcePlural).
			Param("labelSelector", metav1.FormatLabelSelector(selector)).
			Do().Into(&snapshots)
		if err != nil {
			return snapshot, err
		}
		var latestTimestamp int64
		for _, s := range snapshots.Items {
			if item, ok := s.Metadata.Labels[snapshotMetadataTimeStamp]; ok {
				if newTimestamp, err := strconv.ParseInt(item, 10, 64); err == nil {
					if latestTimestamp < newTimestamp {
						snapshot = s
						latestTimestamp = newTimestamp
					}
				}
			}
		}
		if latestTimestamp == 0 {
			return snapshot, errors.New("not found")
		}
	}
	return snapshot, nil
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/snapshotlifecycle/rottenDenotes an issue or PR that has aged beyond stale and will be auto-closed.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions