Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add backups for nextcloud #207

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions pkg/comp-functions/functions/common/backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ func AddPodAnnotationToValues(valueMap map[string]any, scriptName, fileExt strin

// AddBackupCMToValues adds the volume mount for the given configMap to the helm values.
// volumePath and mountPath specify the value path within the values map.
// It will mount the configmap under /scripts in the pod.
func AddBackupCMToValues(values map[string]any, volumePath []string, mountPath []string) error {
volumes := []interface{}{
corev1.Volume{
Expand Down Expand Up @@ -248,3 +249,19 @@ func AddBackupCMToValues(values map[string]any, volumePath []string, mountPath [

return nil
}

// AddBackupScriptCM will add a configmap containing the given script.
// This can then be used to mount into the resulting pod by whatever means applicable (helm values, pod-definition, etc)
func AddBackupScriptCM(svc *runtime.ServiceRuntime, comp common.Composite, script string) error {
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "backup-script",
Namespace: comp.GetInstanceNamespace(),
},
Data: map[string]string{
"backup.sh": script,
},
}

return svc.SetDesiredKubeObject(cm, comp.GetName()+"-backup-script")
}
4 changes: 3 additions & 1 deletion pkg/comp-functions/functions/common/postgresql.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package common

import (
"dario.cat/mergo"
"encoding/json"

"dario.cat/mergo"
xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
sgv1 "github.com/vshn/appcat/v4/apis/stackgres/v1"
vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1"
Expand Down Expand Up @@ -76,6 +77,7 @@ func (a *PostgreSQLDependencyBuilder) CreateDependency() error {
Retention: retention,
DeletionProtection: ptr.To(true),
DeletionRetention: 7,
Schedule: a.comp.GetBackupSchedule(),
},
Service: vshnv1.VSHNPostgreSQLServiceSpec{
PgBouncerSettings: &sgv1.SGPoolingConfigSpecPgBouncerPgbouncerIni{
Expand Down
18 changes: 1 addition & 17 deletions pkg/comp-functions/functions/vshnmariadb/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import (
"github.com/vshn/appcat/v4/pkg/comp-functions/functions/common"
"github.com/vshn/appcat/v4/pkg/comp-functions/functions/common/backup"
"github.com/vshn/appcat/v4/pkg/comp-functions/runtime"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
controllerruntime "sigs.k8s.io/controller-runtime"
)

Expand Down Expand Up @@ -43,7 +41,7 @@ func AddBackupMariadb(ctx context.Context, svc *runtime.ServiceRuntime) *xfnprot
}

l.Info("Adding backup script config map")
err = addBackupScriptCM(svc, comp)
err = backup.AddBackupScriptCM(svc, comp, mariadbBackupScript)
if err != nil {
return runtime.NewWarningResult(fmt.Sprintf("cannot create backup script configMap: %s", err.Error()))
}
Expand All @@ -57,20 +55,6 @@ func AddBackupMariadb(ctx context.Context, svc *runtime.ServiceRuntime) *xfnprot
return nil
}

func addBackupScriptCM(svc *runtime.ServiceRuntime, comp *vshnv1.VSHNMariaDB) error {
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "backup-script",
Namespace: comp.GetInstanceNamespace(),
},
Data: map[string]string{
"backup.sh": mariadbBackupScript,
},
}

return svc.SetDesiredKubeObject(cm, comp.GetName()+"-backup-script")
}

func updateRelease(ctx context.Context, svc *runtime.ServiceRuntime, comp *vshnv1.VSHNMariaDB) error {
l := controllerruntime.LoggerFrom(ctx)

Expand Down
81 changes: 81 additions & 0 deletions pkg/comp-functions/functions/vshnnextcloud/backup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package vshnnextcloud

import (
"context"
"encoding/json"
"fmt"

_ "embed"

xfnproto "github.com/crossplane/function-sdk-go/proto/v1beta1"
xhelmv1 "github.com/vshn/appcat/v4/apis/helm/release/v1beta1"
vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1"
"github.com/vshn/appcat/v4/pkg/comp-functions/functions/common"
"github.com/vshn/appcat/v4/pkg/comp-functions/functions/common/backup"
"github.com/vshn/appcat/v4/pkg/comp-functions/runtime"
)

//go:embed files/backup.sh
var nextcloudBackupScript string

func AddBackup(ctx context.Context, svc *runtime.ServiceRuntime) *xfnproto.Result {
comp := &vshnv1.VSHNNextcloud{}
err := svc.GetDesiredComposite(comp)
if err != nil {
return runtime.NewFatalResult(fmt.Errorf("can't get composite: %w", err))
}

err = backup.AddK8upBackup(ctx, svc, comp)
if err != nil {
return runtime.NewFatalResult(fmt.Errorf("cannot add k8s backup to the desired state: %w", err))
}

err = backup.AddBackupScriptCM(svc, comp, nextcloudBackupScript)
if err != nil {
return runtime.NewFatalResult(err)
}

err = updateRelease(svc, comp)
if err != nil {
return runtime.NewWarningResult(fmt.Sprintf("cannot update release with backup configuration: %s", err))
}

return nil
}

func updateRelease(svc *runtime.ServiceRuntime, comp *vshnv1.VSHNNextcloud) error {
release := &xhelmv1.Release{}

err := svc.GetDesiredComposedResourceByName(release, comp.GetName()+"-release")
if err != nil {
return err
}

values, err := common.GetReleaseValues(release)
if err != nil {
return err
}

err = backup.AddPVCAnnotationToValues(values, "persistence", "annotations")
if err != nil {
return fmt.Errorf("cannot add pvc annotations to values: %w", err)
}

err = backup.AddPodAnnotationToValues(values, "/scripts/backup.sh", ".tar", "podAnnotations")
if err != nil {
return fmt.Errorf("cannot add pod annotations to values: %w", err)
}

err = backup.AddBackupCMToValues(values, []string{"nextcloud", "extraVolumes"}, []string{"nextcloud", "extraVolumeMounts"})
if err != nil {
return fmt.Errorf("cannot add backup cm to values: %w", err)
}

byteValues, err := json.Marshal(values)
if err != nil {
return err
}
release.Spec.ForProvider.Values.Raw = byteValues

return svc.SetDesiredComposedResourceWithName(release, comp.GetName()+"-release")
}
36 changes: 3 additions & 33 deletions pkg/comp-functions/functions/vshnnextcloud/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,16 @@ import (
"context"
_ "embed"
"encoding/json"
"strings"
"testing"

"github.com/stretchr/testify/assert"
xhelmv1 "github.com/vshn/appcat/v4/apis/helm/release/v1beta1"
vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1"
"github.com/vshn/appcat/v4/pkg/comp-functions/functions/commontest"
"github.com/vshn/appcat/v4/pkg/comp-functions/runtime"
"k8s.io/utils/ptr"
"strings"
"testing"
)

func Test_addPostgreSQL(t *testing.T) {

svc := commontest.LoadRuntimeFromFile(t, "vshn-postgres/empty.yaml")

comp := &vshnv1.VSHNNextcloud{}

assert.NoError(t, addPostgreSQL(svc, comp))

pg := &vshnv1.XVSHNPostgreSQL{}

assert.NoError(t, svc.GetDesiredComposedResourceByName(pg, comp.GetName()+pgInstanceNameSuffix))

// Assert default values
assert.True(t, *pg.Spec.Parameters.Backup.DeletionProtection)
assert.Equal(t, 6, pg.Spec.Parameters.Backup.Retention)

// Assert default overrides
comp.Spec.Parameters.Service.PostgreSQLParameters = &vshnv1.VSHNPostgreSQLParameters{
Backup: vshnv1.VSHNPostgreSQLBackup{
DeletionProtection: ptr.To(false),
Retention: 1,
},
}

assert.NoError(t, addPostgreSQL(svc, comp))
assert.NoError(t, svc.GetDesiredComposedResourceByName(pg, comp.GetName()+pgInstanceNameSuffix))
assert.False(t, *pg.Spec.Parameters.Backup.DeletionProtection)
assert.Equal(t, 1, pg.Spec.Parameters.Backup.Retention)
}

func Test_addNextcloud(t *testing.T) {
svc, comp := getNextcloudComp(t, "vshnnextcloud/01_default.yaml")

Expand Down
17 changes: 17 additions & 0 deletions pkg/comp-functions/functions/vshnnextcloud/files/backup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

set -e

# We need to run the occ command as the www-data user, but there's no sudo by default
apt update 1>&2 && apt install sudo -y 1>&2

function disableMaintenance {
>&2 echo "Disabling maintenance"
sudo -u www-data /var/www/html/occ maintenance:mode --off 1>&2
}

trap disableMaintenance EXIT

sudo -u www-data /var/www/html/occ maintenance:mode --on 1>&2

tar -cf - /var/www
5 changes: 5 additions & 0 deletions pkg/comp-functions/functions/vshnnextcloud/maintenance.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ func AddMaintenanceJob(ctx context.Context, svc *runtime.ServiceRuntime) *xfnpro
instanceNamespace := comp.GetInstanceNamespace()
schedule := comp.GetFullMaintenanceSchedule()

err = svc.SetDesiredCompositeStatus(comp)
if err != nil {
return runtime.NewFatalResult(fmt.Errorf("cannot update composite status: %w", err))
}

return maintenance.New(comp, svc, schedule, instanceNamespace, comp.GetServiceName()).
WithHelmBasedService().
Run(ctx)
Expand Down
4 changes: 4 additions & 0 deletions pkg/comp-functions/functions/vshnnextcloud/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ func init() {
Name: "maintenance",
Execute: AddMaintenanceJob,
},
{
Name: "backup",
Execute: AddBackup,
},
},
})
}
Loading