A sidecar ENV keeps the paths to backup. That will do for now but the BackupSession controller in the sidecar should do the job of computing the paths to backup every time it reconciles. In case the paths have changed
This commit is contained in:
parent
c89a522262
commit
1361f62045
@ -61,11 +61,6 @@ type Target struct {
|
|||||||
Retry int `json:"retry"`
|
Retry int `json:"retry"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TargetSidecarPath struct {
|
|
||||||
TargetName string `json:"targetName"`
|
|
||||||
SidecarPaths []string `json:"sidecarPaths"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Keep struct {
|
type Keep struct {
|
||||||
Last int32 `json:"last"`
|
Last int32 `json:"last"`
|
||||||
Daily int32 `json:"daily"`
|
Daily int32 `json:"daily"`
|
||||||
@ -91,8 +86,6 @@ type BackupConfigurationStatus struct {
|
|||||||
Suspended bool `json:"suspended"`
|
Suspended bool `json:"suspended"`
|
||||||
ActiveCronJob bool `json:"activeCronJob"`
|
ActiveCronJob bool `json:"activeCronJob"`
|
||||||
ActiveSidecar bool `json:"activeSidecar"`
|
ActiveSidecar bool `json:"activeSidecar"`
|
||||||
// +optional
|
|
||||||
Targets []TargetSidecarPath `json:"targets,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//+kubebuilder:object:root=true
|
//+kubebuilder:object:root=true
|
||||||
|
|||||||
@ -10,4 +10,6 @@ const (
|
|||||||
// Used by the backupsession controller
|
// Used by the backupsession controller
|
||||||
POD_NAME string = "POD_NAME"
|
POD_NAME string = "POD_NAME"
|
||||||
POD_NAMESPACE string = "POD_NAMESPACE"
|
POD_NAMESPACE string = "POD_NAMESPACE"
|
||||||
|
// Backup Paths list
|
||||||
|
BACKUP_PATHS = "BACKUP_PATHS"
|
||||||
)
|
)
|
||||||
|
|||||||
@ -145,13 +145,6 @@ func (in *BackupConfigurationStatus) DeepCopyInto(out *BackupConfigurationStatus
|
|||||||
in, out := &in.LastBackupTime, &out.LastBackupTime
|
in, out := &in.LastBackupTime, &out.LastBackupTime
|
||||||
*out = (*in).DeepCopy()
|
*out = (*in).DeepCopy()
|
||||||
}
|
}
|
||||||
if in.Targets != nil {
|
|
||||||
in, out := &in.Targets, &out.Targets
|
|
||||||
*out = make([]TargetSidecarPath, len(*in))
|
|
||||||
for i := range *in {
|
|
||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupConfigurationStatus.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupConfigurationStatus.
|
||||||
@ -617,26 +610,6 @@ func (in *TargetContainer) DeepCopy() *TargetContainer {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
|
||||||
func (in *TargetSidecarPath) DeepCopyInto(out *TargetSidecarPath) {
|
|
||||||
*out = *in
|
|
||||||
if in.SidecarPaths != nil {
|
|
||||||
in, out := &in.SidecarPaths, &out.SidecarPaths
|
|
||||||
*out = make([]string, len(*in))
|
|
||||||
copy(*out, *in)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetSidecarPath.
|
|
||||||
func (in *TargetSidecarPath) DeepCopy() *TargetSidecarPath {
|
|
||||||
if in == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := new(TargetSidecarPath)
|
|
||||||
in.DeepCopyInto(out)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *TargetStatus) DeepCopyInto(out *TargetStatus) {
|
func (in *TargetStatus) DeepCopyInto(out *TargetStatus) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
|||||||
@ -97,15 +97,9 @@ func (r *BackupConfigurationReconciler) Reconcile(ctx context.Context, req ctrl.
|
|||||||
switch target.BackupType {
|
switch target.BackupType {
|
||||||
case formolv1alpha1.OnlineKind:
|
case formolv1alpha1.OnlineKind:
|
||||||
// TODO: add a sidecar to the pod with the target.Containers[].Paths mounted
|
// TODO: add a sidecar to the pod with the target.Containers[].Paths mounted
|
||||||
if sidecarPaths, err := r.addOnlineSidecar(backupConf, target); err != nil {
|
if err := r.addOnlineSidecar(backupConf, target); err != nil {
|
||||||
r.Log.Error(err, "unable to add online sidecar")
|
r.Log.Error(err, "unable to add online sidecar")
|
||||||
return ctrl.Result{}, err
|
return ctrl.Result{}, err
|
||||||
} else if len(sidecarPaths) > 0 {
|
|
||||||
backupConf.Status.Targets = append(backupConf.Status.Targets,
|
|
||||||
formolv1alpha1.TargetSidecarPath{
|
|
||||||
TargetName: target.TargetName,
|
|
||||||
SidecarPaths: sidecarPaths,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
backupConf.Status.ActiveSidecar = true
|
backupConf.Status.ActiveSidecar = true
|
||||||
case formolv1alpha1.JobKind:
|
case formolv1alpha1.JobKind:
|
||||||
|
|||||||
@ -24,9 +24,11 @@ import (
|
|||||||
rbacv1 "k8s.io/api/rbac/v1"
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"strings"
|
||||||
|
|
||||||
formolv1alpha1 "github.com/desmo999r/formol/api/v1alpha1"
|
formolv1alpha1 "github.com/desmo999r/formol/api/v1alpha1"
|
||||||
)
|
)
|
||||||
@ -178,13 +180,18 @@ func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1.
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alpha1.BackupConfiguration, target formolv1alpha1.Target) (sidecarPaths []string, err error) {
|
func hasSidecar(podSpec *corev1.PodSpec) bool {
|
||||||
addTags := func(sideCar *corev1.Container, podSpec *corev1.PodSpec, target formolv1alpha1.Target) ([]string, bool) {
|
for _, container := range podSpec.Containers {
|
||||||
var sidecarPaths []string
|
if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alpha1.BackupConfiguration, target formolv1alpha1.Target) (err error) {
|
||||||
|
addTags := func(podSpec *corev1.PodSpec, target formolv1alpha1.Target) (sidecarPaths []string, vms []corev1.VolumeMount) {
|
||||||
for i, container := range podSpec.Containers {
|
for i, container := range podSpec.Containers {
|
||||||
if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME {
|
|
||||||
return sidecarPaths, false
|
|
||||||
}
|
|
||||||
for _, targetContainer := range target.Containers {
|
for _, targetContainer := range target.Containers {
|
||||||
if targetContainer.Name == container.Name {
|
if targetContainer.Name == container.Name {
|
||||||
// Found a target container. Tag it.
|
// Found a target container. Tag it.
|
||||||
@ -209,13 +216,13 @@ func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alph
|
|||||||
sidecarPath = filepath.Join(vm.MountPath, rel)
|
sidecarPath = filepath.Join(vm.MountPath, rel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sideCar.VolumeMounts = append(sideCar.VolumeMounts, vm)
|
vms = append(vms, vm)
|
||||||
sidecarPaths = append(sidecarPaths, sidecarPath)
|
sidecarPaths = append(sidecarPaths, sidecarPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sidecarPaths, true
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
repo := formolv1alpha1.Repo{}
|
repo := formolv1alpha1.Repo{}
|
||||||
@ -224,11 +231,11 @@ func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alph
|
|||||||
Name: backupConf.Spec.Repository,
|
Name: backupConf.Spec.Repository,
|
||||||
}, &repo); err != nil {
|
}, &repo); err != nil {
|
||||||
r.Log.Error(err, "unable to get Repo")
|
r.Log.Error(err, "unable to get Repo")
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
r.Log.V(1).Info("Got Repository", "repo", repo)
|
r.Log.V(1).Info("Got Repository", "repo", repo)
|
||||||
env := repo.GetResticEnv(backupConf)
|
env := repo.GetResticEnv(backupConf)
|
||||||
sideCar := corev1.Container{
|
sidecar := corev1.Container{
|
||||||
Name: formolv1alpha1.SIDECARCONTAINER_NAME,
|
Name: formolv1alpha1.SIDECARCONTAINER_NAME,
|
||||||
Image: backupConf.Spec.Image,
|
Image: backupConf.Spec.Image,
|
||||||
Args: []string{"backupsession", "server"},
|
Args: []string{"backupsession", "server"},
|
||||||
@ -247,33 +254,44 @@ func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alph
|
|||||||
}),
|
}),
|
||||||
VolumeMounts: []corev1.VolumeMount{},
|
VolumeMounts: []corev1.VolumeMount{},
|
||||||
}
|
}
|
||||||
|
var targetObject client.Object
|
||||||
|
var targetPodSpec *corev1.PodSpec
|
||||||
switch target.TargetKind {
|
switch target.TargetKind {
|
||||||
case formolv1alpha1.Deployment:
|
case formolv1alpha1.Deployment:
|
||||||
deployment := &appsv1.Deployment{}
|
deployment := appsv1.Deployment{}
|
||||||
if err = r.Get(r.Context, client.ObjectKey{
|
if err = r.Get(r.Context, client.ObjectKey{
|
||||||
Namespace: backupConf.Namespace,
|
Namespace: backupConf.Namespace,
|
||||||
Name: target.TargetName,
|
Name: target.TargetName,
|
||||||
}, deployment); err != nil {
|
}, &deployment); err != nil {
|
||||||
r.Log.Error(err, "cannot get deployment", "Deployment", target.TargetName)
|
r.Log.Error(err, "cannot get deployment", "Deployment", target.TargetName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if paths, add := addTags(&sideCar, &deployment.Spec.Template.Spec, target); add == true {
|
targetObject = &deployment
|
||||||
sidecarPaths = paths
|
targetPodSpec = &deployment.Spec.Template.Spec
|
||||||
if err = r.createRBACSidecar(corev1.ServiceAccount{
|
}
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
if !hasSidecar(targetPodSpec) {
|
||||||
Namespace: deployment.Namespace,
|
if err = r.createRBACSidecar(corev1.ServiceAccount{
|
||||||
Name: deployment.Spec.Template.Spec.ServiceAccountName,
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
},
|
Namespace: backupConf.Namespace,
|
||||||
}); err != nil {
|
Name: targetPodSpec.ServiceAccountName,
|
||||||
r.Log.Error(err, "unable to create RBAC for the sidecar container")
|
},
|
||||||
return
|
}); err != nil {
|
||||||
}
|
r.Log.Error(err, "unable to create RBAC for the sidecar container")
|
||||||
deployment.Spec.Template.Spec.Containers = append(deployment.Spec.Template.Spec.Containers, sideCar)
|
return
|
||||||
r.Log.V(1).Info("Updating deployment", "deployment", deployment, "containers", deployment.Spec.Template.Spec.Containers)
|
}
|
||||||
if err = r.Update(r.Context, deployment); err != nil {
|
sidecarPaths, vms := addTags(targetPodSpec, target)
|
||||||
r.Log.Error(err, "cannot update deployment", "Deployment", deployment)
|
sidecar.VolumeMounts = vms
|
||||||
return
|
sidecar.Env = append(sidecar.Env, corev1.EnvVar{
|
||||||
}
|
Name: formolv1alpha1.BACKUP_PATHS,
|
||||||
|
Value: strings.Join(sidecarPaths, string(os.PathListSeparator)),
|
||||||
|
})
|
||||||
|
|
||||||
|
// The sidecar definition is complete. Add it to the targetObject
|
||||||
|
targetPodSpec.Containers = append(targetPodSpec.Containers, sidecar)
|
||||||
|
r.Log.V(1).Info("Adding sidecar", "targetObject", targetObject, "sidecar", sidecar)
|
||||||
|
if err = r.Update(r.Context, targetObject); err != nil {
|
||||||
|
r.Log.Error(err, "unable to add sidecar", "targetObject", targetObject)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user