Skip to content

Commit

Permalink
KUBEDR-4917: Skip copying PVCs that are not attached to any pod
Browse files Browse the repository at this point in the history
(cherry picked from commit 6cc9767)
  • Loading branch information
dzaninovic committed Nov 9, 2023
1 parent bdbe7eb commit f941cdc
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ BIN ?= velero
PKG := github.com/vmware-tanzu/velero

# Where to push the docker image.
REGISTRY ?= velero
REGISTRY ?= catalogicsoftware
GCR_REGISTRY ?= gcr.io/velero-gcp

# Image name
Expand Down Expand Up @@ -62,7 +62,7 @@ HUGO_IMAGE := hugo-builder
local : ARCH ?= $(shell go env GOOS)-$(shell go env GOARCH)
ARCH ?= linux-amd64

VERSION ?= main
VERSION ?= v1.11.1.1

TAG_LATEST ?= false

Expand Down
66 changes: 66 additions & 0 deletions pkg/backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
kubeerrs "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"

"github.com/vmware-tanzu/velero/internal/hook"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
Expand Down Expand Up @@ -86,6 +88,17 @@ type kubernetesBackupper struct {
uploaderType string
}

type veleroConfig struct {
ExcludedPvcs map[string]bool
}

const (
CloudCasaNamespace = "cloudcasa-io"

// VeleroConfigMapName is the name of the configmap used to store configuration parameters
VeleroConfigMapName = "cloudcasa-io-velero-config"
)

func (i *itemKey) String() string {
return fmt.Sprintf("resource=%s,namespace=%s,name=%s", i.resource, i.namespace, i.name)
}
Expand Down Expand Up @@ -290,6 +303,11 @@ func (kb *kubernetesBackupper) BackupWithResolvers(log logrus.FieldLogger,
}
backupRequest.Status.Progress = &velerov1api.BackupProgress{TotalItems: len(items)}

veleroConfig, err := GetVeleroConfig(log)
if err != nil {
return errors.Wrap(err, "Failed to get velero configuration")
}

itemBackupper := &itemBackupper{
backupRequest: backupRequest,
tarWriter: tw,
Expand All @@ -302,6 +320,7 @@ func (kb *kubernetesBackupper) BackupWithResolvers(log logrus.FieldLogger,
itemHookHandler: &hook.DefaultItemHookHandler{
PodCommandExecutor: kb.podCommandExecutor,
},
excludedPvcs: veleroConfig.ExcludedPvcs,
}

// helper struct to send current progress between the main
Expand Down Expand Up @@ -715,3 +734,50 @@ type tarWriter interface {
Write([]byte) (int, error)
WriteHeader(*tar.Header) error
}

// GetVeleroConfig reads the configmap that contains Velero config parameters
func GetVeleroConfig(log logrus.FieldLogger) (*veleroConfig, error) {
clientset, err := GetClientset(log)
if err != nil {
return nil, err
}

configMap, err := clientset.CoreV1().ConfigMaps(CloudCasaNamespace).Get(context.TODO(), VeleroConfigMapName, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
log.Infof("Velero configuration configmap %q not found", VeleroConfigMapName)
return &veleroConfig{}, nil
}
log.Error(errors.Wrapf(err, "Failed to get %q configmap in %q namespace", VeleroConfigMapName, CloudCasaNamespace))
return nil, err
}

var excludedPvcs map[string]bool
if excludedPvcsJson, found := configMap.BinaryData["excludedPvcs"]; found {
if err := json.Unmarshal(excludedPvcsJson, &excludedPvcs); err != nil {
log.Error(errors.Wrapf(err, "Failed to parse excludedPvcs value %q from %q",
string(excludedPvcsJson), VeleroConfigMapName))
return nil, err
}
}

return &veleroConfig{
ExcludedPvcs: excludedPvcs,
}, nil
}

func GetClientset(log logrus.FieldLogger) (*kubernetes.Clientset, error) {
// creates the in-cluster config
config, err := rest.InClusterConfig()
if err != nil {
log.Error(errors.Wrap(err, "Failed to create in-cluster config"))
return nil, err
}
// creates the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
log.Error(errors.Wrap(err, "Failed to create in-cluster clientset"))
return nil, err
}
return clientset, nil
}
26 changes: 26 additions & 0 deletions pkg/backup/item_backupper.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ type itemBackupper struct {

itemHookHandler hook.ItemHookHandler
snapshotLocationVolumeSnapshotters map[string]vsv1.VolumeSnapshotter

excludedPvcs map[string]bool
}

type FileForArchive struct {
Expand Down Expand Up @@ -158,6 +160,30 @@ func (ib *itemBackupper) backupItemInternal(logger logrus.FieldLogger, obj runti
return false, itemFiles, nil
}

if ib.excludedPvcs != nil {
switch groupResource {
case kuberesource.PersistentVolumes:
pv := new(corev1api.PersistentVolume)
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), pv); err != nil {
log.Errorf("Failed to convert unstructured PV %s to PersistentVolume structure: %v", metadata.GetName(), err)
return false, itemFiles, err
}

pvcPath := pv.Spec.ClaimRef.Namespace + "/" + pv.Spec.ClaimRef.Name
if _, isExcluded := ib.excludedPvcs[pvcPath]; isExcluded {
log.Infof("Excluding PV %s for PVC %s because it is excluded from backup", metadata.GetName(), pvcPath)
return false, itemFiles, nil
}

case kuberesource.PersistentVolumeClaims:
pvcPath := metadata.GetNamespace() + "/" + metadata.GetName()
if _, isExcluded := ib.excludedPvcs[pvcPath]; isExcluded {
log.Infof("Excluding PVC %s because it is excluded from backup", pvcPath)
return false, itemFiles, nil
}
}
}

key := itemKey{
resource: resourceKey(obj),
namespace: namespace,
Expand Down

0 comments on commit f941cdc

Please sign in to comment.