Compare commits

..

2 Commits

Author SHA1 Message Date
Jean-Marc ANDRE
cfea083594 sharedprocess and local restic repostory 2023-02-21 01:12:47 +01:00
Jean-Marc ANDRE
9f91876dd2 updated the tests 2023-02-21 01:12:43 +01:00
6 changed files with 106 additions and 36 deletions

View File

@ -30,8 +30,6 @@ const (
AWS_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY" AWS_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY"
) )
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
type S3 struct { type S3 struct {
Server string `json:"server"` Server string `json:"server"`
Bucket string `json:"bucket"` Bucket string `json:"bucket"`
@ -39,11 +37,15 @@ type S3 struct {
Prefix string `json:"prefix,omitempty"` Prefix string `json:"prefix,omitempty"`
} }
type Local struct {
Path string `json:"path"`
}
type Backend struct { type Backend struct {
// +optional // +optional
S3 *S3 `json:"s3,omitempty"` S3 *S3 `json:"s3,omitempty"`
// +optional // +optional
Nfs *string `json:"nfs,omitempty"` Local *Local `json:"local,omitempty"`
} }
// RepoSpec defines the desired state of Repo // RepoSpec defines the desired state of Repo
@ -96,7 +98,6 @@ func (repo *Repo) GetResticEnv(backupConf BackupConfiguration) []corev1.EnvVar {
for _, key := range []string{ for _, key := range []string{
AWS_ACCESS_KEY_ID, AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY, AWS_SECRET_ACCESS_KEY,
RESTIC_PASSWORD,
} { } {
env = append(env, corev1.EnvVar{ env = append(env, corev1.EnvVar{
Name: key, Name: key,
@ -111,6 +112,23 @@ func (repo *Repo) GetResticEnv(backupConf BackupConfiguration) []corev1.EnvVar {
}) })
} }
} }
if repo.Spec.Backend.Local != nil {
env = append(env, corev1.EnvVar{
Name: RESTIC_REPOSITORY,
Value: repo.Spec.Backend.Local.Path,
})
}
env = append(env, corev1.EnvVar{
Name: RESTIC_PASSWORD,
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: repo.Spec.RepositorySecrets,
},
Key: RESTIC_PASSWORD,
},
},
})
return env return env
} }

View File

@ -34,9 +34,9 @@ func (in *Backend) DeepCopyInto(out *Backend) {
*out = new(S3) *out = new(S3)
**out = **in **out = **in
} }
if in.Nfs != nil { if in.Local != nil {
in, out := &in.Nfs, &out.Nfs in, out := &in.Local, &out.Local
*out = new(string) *out = new(Local)
**out = **in **out = **in
} }
} }
@ -347,6 +347,21 @@ func (in *Keep) DeepCopy() *Keep {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Local) DeepCopyInto(out *Local) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Local.
func (in *Local) DeepCopy() *Local {
if in == nil {
return nil
}
out := new(Local)
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 *Repo) DeepCopyInto(out *Repo) { func (in *Repo) DeepCopyInto(out *Repo) {
*out = *in *out = *in

View File

@ -150,30 +150,54 @@ func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1.
} }
} }
} }
repo := formolv1alpha1.Repo{}
if err := r.Get(r.Context, client.ObjectKey{
Namespace: backupConf.Namespace,
Name: backupConf.Spec.Repository,
}, &repo); err != nil {
r.Log.Error(err, "unable to get Repo")
return err
}
r.Log.V(1).Info("Got Repository", "repo", repo)
for _, target := range backupConf.Spec.Targets { for _, target := range backupConf.Spec.Targets {
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 err return err
} }
restoreContainers := []corev1.Container{} targetObject = &deployment
for _, container := range deployment.Spec.Template.Spec.Containers { targetPodSpec = &deployment.Spec.Template.Spec
if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME {
}
restoreContainers := []corev1.Container{}
for _, container := range targetPodSpec.Containers {
if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME {
continue
}
restoreContainers = append(restoreContainers, container)
}
targetPodSpec.Containers = restoreContainers
if repo.Spec.Backend.Local != nil {
restoreVolumes := []corev1.Volume{}
for _, volume := range targetPodSpec.Volumes {
if volume.Name == "restic-local-repo" {
continue continue
} }
restoreContainers = append(restoreContainers, container) restoreVolumes = append(restoreVolumes, volume)
}
deployment.Spec.Template.Spec.Containers = restoreContainers
removeTags(&deployment.Spec.Template.Spec, target)
if err := r.Update(r.Context, deployment); err != nil {
r.Log.Error(err, "unable to update deployment", "deployment", deployment)
return err
} }
targetPodSpec.Volumes = restoreVolumes
}
removeTags(targetPodSpec, target)
if err := r.Update(r.Context, targetObject); err != nil {
r.Log.Error(err, "unable to remove sidecar", "targetObject", targetObject)
return err
} }
} }
@ -280,14 +304,28 @@ func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alph
return return
} }
sidecarPaths, vms := addTags(targetPodSpec, target) sidecarPaths, vms := addTags(targetPodSpec, target)
sidecar.VolumeMounts = vms
sidecar.Env = append(sidecar.Env, corev1.EnvVar{ sidecar.Env = append(sidecar.Env, corev1.EnvVar{
Name: formolv1alpha1.BACKUP_PATHS, Name: formolv1alpha1.BACKUP_PATHS,
Value: strings.Join(sidecarPaths, string(os.PathListSeparator)), Value: strings.Join(sidecarPaths, string(os.PathListSeparator)),
}) })
if repo.Spec.Backend.Local != nil {
sidecar.VolumeMounts = append(vms, corev1.VolumeMount{
Name: "restic-local-repo",
MountPath: "/repo",
})
targetPodSpec.Volumes = append(targetPodSpec.Volumes, corev1.Volume{
Name: "restic-local-repo",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
})
} else {
sidecar.VolumeMounts = vms
}
// The sidecar definition is complete. Add it to the targetObject // The sidecar definition is complete. Add it to the targetObject
targetPodSpec.Containers = append(targetPodSpec.Containers, sidecar) targetPodSpec.Containers = append(targetPodSpec.Containers, sidecar)
targetPodSpec.ShareProcessNamespace = func() *bool { b := true; return &b }()
r.Log.V(1).Info("Adding sidecar", "targetObject", targetObject, "sidecar", sidecar) r.Log.V(1).Info("Adding sidecar", "targetObject", targetObject, "sidecar", sidecar)
if err = r.Update(r.Context, targetObject); err != nil { if err = r.Update(r.Context, targetObject); err != nil {
r.Log.Error(err, "unable to add sidecar", "targetObject", targetObject) r.Log.Error(err, "unable to add sidecar", "targetObject", targetObject)
@ -333,7 +371,7 @@ func (r *BackupConfigurationReconciler) createRBACSidecar(sa corev1.ServiceAccou
rbacv1.PolicyRule{ rbacv1.PolicyRule{
Verbs: []string{"get", "list", "watch"}, Verbs: []string{"get", "list", "watch"},
APIGroups: []string{"formol.desmojim.fr"}, APIGroups: []string{"formol.desmojim.fr"},
Resources: []string{"backupsessions", "backupconfigurations"}, Resources: []string{"backupsessions", "backupconfigurations", "functions", "repos"},
}, },
rbacv1.PolicyRule{ rbacv1.PolicyRule{
Verbs: []string{"get", "list", "watch", "create", "update", "patch", "delete"}, Verbs: []string{"get", "list", "watch", "create", "update", "patch", "delete"},

View File

@ -74,11 +74,12 @@ data:
apiVersion: formol.desmojim.fr/v1alpha1 apiVersion: formol.desmojim.fr/v1alpha1
kind: Repo kind: Repo
metadata: metadata:
name: repo-empty name: repo-local
namespace: demo namespace: demo
spec: spec:
backend: backend:
nfs: "toto" local:
path: /repo
repositorySecrets: secret-minio repositorySecrets: secret-minio
--- ---
apiVersion: formol.desmojim.fr/v1alpha1 apiVersion: formol.desmojim.fr/v1alpha1
@ -162,7 +163,7 @@ metadata:
namespace: demo namespace: demo
spec: spec:
name: maintenance-off name: maintenance-off
command: ["/bin/bash", "-c", "echo $(date +%Y/%m/%d-%H:%M:%S) maintenance-off >> /data/logs.txt"] command: ["/bin/sh", "-c", "echo $(date +%Y/%m/%d-%H:%M:%S) maintenance-off >> /data/logs.txt"]
--- ---
apiVersion: formol.desmojim.fr/v1alpha1 apiVersion: formol.desmojim.fr/v1alpha1
kind: Function kind: Function
@ -171,4 +172,4 @@ metadata:
namespace: demo namespace: demo
spec: spec:
name: maintenance-on name: maintenance-on
command: ["/bin/bash", "-c", "echo $(date +%Y/%m/%d-%H:%M:%S) maintenance-on >> /data/logs.txt"] command: ["/bin/sh", "-c", "echo $(date +%Y/%m/%d-%H:%M:%S) maintenance-on >> /data/logs.txt"]

View File

@ -2,27 +2,27 @@
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx-deployment name: apache-deployment
namespace: demo namespace: demo
labels: labels:
app: nginx app: apache
spec: spec:
replicas: 1 replicas: 1
strategy: strategy:
type: Recreate type: Recreate
selector: selector:
matchLabels: matchLabels:
app: nginx app: apache
template: template:
metadata: metadata:
labels: labels:
app: nginx app: apache
spec: spec:
imagePullSecrets: imagePullSecrets:
- name: regcred - name: regcred
containers: containers:
- name: nginx - name: apache
image: docker.io/nginx:1.23.3 image: docker.io/httpd:alpine3.17
ports: ports:
- containerPort: 80 - containerPort: 80
volumeMounts: volumeMounts:

View File

@ -7,7 +7,7 @@ metadata:
spec: spec:
suspend: true suspend: true
image: desmo999r/formolcli:latest image: desmo999r/formolcli:latest
repository: repo-minio repository: repo-local
schedule: "15 * * * *" schedule: "15 * * * *"
keep: keep:
last: 5 last: 5
@ -18,13 +18,11 @@ spec:
targets: targets:
- backupType: Online - backupType: Online
targetKind: Deployment targetKind: Deployment
targetName: nginx-deployment targetName: apache-deployment
containers: containers:
- name: nginx - name: apache
steps: steps:
- name: maintenance-on - name: maintenance-on
- name: with-env
- name: with-envfrom
- name: maintenance-off - name: maintenance-off
finalize: true finalize: true
paths: paths: