snapshots #10
@ -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