formol/api/v1alpha1/common.go
2023-04-20 09:21:16 +02:00

108 lines
3.4 KiB
Go

package v1alpha1
import (
"fmt"
corev1 "k8s.io/api/core/v1"
"os"
"path/filepath"
"strings"
)
const (
RESTORECONTAINER_NAME string = "formol-restore"
// the name of the sidecar container
SIDECARCONTAINER_NAME string = "formol"
// the name of the container we backup when there are more than 1 container in the pod
TARGETCONTAINER_TAG string = "FORMOL_TARGET"
// Used by both the backupsession and restoresession controllers to identified the target deployment
TARGET_NAME string = "TARGET_NAME"
// Used by the backupsession controller
POD_NAME string = "POD_NAME"
POD_NAMESPACE string = "POD_NAMESPACE"
// Backup Paths list
BACKUP_PATHS = "BACKUP_PATHS"
)
func GetSharedPath(podSpec *corev1.PodSpec, index int, targetContainer TargetContainer) (vms []corev1.VolumeMount) {
// Create a shared mount between the target and sidecar container
// the output of the Job will be saved in the shared volume
// and restic will then backup the content of the volume
var addSharedVol bool = true
for _, vol := range podSpec.Volumes {
if vol.Name == FORMOL_SHARED_VOLUME {
addSharedVol = false
}
}
if addSharedVol {
podSpec.Volumes = append(podSpec.Volumes,
corev1.Volume{
Name: FORMOL_SHARED_VOLUME,
VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}},
})
}
podSpec.Containers[index].VolumeMounts = append(podSpec.Containers[index].VolumeMounts, corev1.VolumeMount{
Name: FORMOL_SHARED_VOLUME,
MountPath: targetContainer.SharePath,
})
vms = append(vms, corev1.VolumeMount{
Name: FORMOL_SHARED_VOLUME,
MountPath: targetContainer.SharePath,
})
return
}
func GetVolumeMounts(container corev1.Container, targetContainer TargetContainer) (sidecarPaths []string, vms []corev1.VolumeMount) {
// targetContainer.Paths are the paths to backup
// We have to find what volumes are mounted under those paths
// and mount them under a path that exists in the sidecar container
for i, path := range targetContainer.Paths {
vm := corev1.VolumeMount{ReadOnly: true}
var longest int = 0
var sidecarPath string
path = filepath.Clean(path)
splitPath := strings.Split(path, string(os.PathSeparator))
for _, volumeMount := range container.VolumeMounts {
splitMountPath := strings.Split(volumeMount.MountPath, string(os.PathSeparator))
for j, pathItem := range splitMountPath {
if j < len(splitPath) && pathItem == splitPath[j] && j > longest {
longest = j
vm.Name = volumeMount.Name
vm.MountPath = fmt.Sprintf("/%s%d", BACKUP_PREFIX_PATH, i)
vm.SubPath = volumeMount.SubPath
rel, _ := filepath.Rel(volumeMount.MountPath, path)
sidecarPath = filepath.Join(vm.MountPath, rel)
}
}
}
vms = append(vms, vm)
sidecarPaths = append(sidecarPaths, sidecarPath)
}
return
}
func GetSidecar(backupConf BackupConfiguration, target Target) corev1.Container {
sidecar := corev1.Container{
Name: SIDECARCONTAINER_NAME,
Image: backupConf.Spec.Image,
Args: []string{"server"},
Env: []corev1.EnvVar{
corev1.EnvVar{
Name: TARGET_NAME,
Value: target.TargetName,
},
corev1.EnvVar{
Name: POD_NAMESPACE,
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
FieldPath: "metadata.namespace",
},
},
}},
VolumeMounts: []corev1.VolumeMount{},
SecurityContext: &corev1.SecurityContext{
Privileged: func() *bool { b := true; return &b }(),
},
}
return sidecar
}