Skip to content

Commit

Permalink
Merge branch 'main' into gerard/sc-116844/minio
Browse files Browse the repository at this point in the history
  • Loading branch information
nvanthao authored Dec 11, 2024
2 parents 211487a + 92431cf commit 9157c48
Show file tree
Hide file tree
Showing 18 changed files with 644 additions and 84 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ debug-build:

.PHONY: debug
debug: debug-build
LOG_LEVEL=$(LOG_LEVEL) dlv --listen=:2345 --headless=true --api-version=2 exec ./bin/kotsadm-debug api
LOG_LEVEL=$(LOG_LEVEL) /dlv --listen=:30001 --headless=true --api-version=2 exec ./bin/kotsadm-debug api

.PHONY: web
web:
Expand Down
2 changes: 1 addition & 1 deletion dev/dockerfiles/kotsadm/Dockerfile.local
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM golang:1.23-alpine AS dlv-builder

RUN go install github.com/go-delve/delve/cmd/dlv@v1.22.1
RUN go install github.com/go-delve/delve/cmd/dlv@v1.23.1

FROM golang:1.23-alpine

Expand Down
1 change: 0 additions & 1 deletion dev/manifests/kotsadm/minio.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ spec:
volumeMounts:
- mountPath: /data
name: miniodata # this is where the data is stored

volumeClaimTemplates:
- metadata:
name: miniodata
Expand Down
2 changes: 1 addition & 1 deletion migrations/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ SCHEMAHERO_TAG ?= 0.17.12
DOCKER_BUILD_ARGS ?=

build_schema:
docker build --pull --build-arg SCHEMAHERO_TAG=${SCHEMAHERO_TAG} ${DOCKER_BUILD_ARGS} -f dev/Dockerfile.ttlsh -t ${IMAGE} .
docker build --pull --build-arg SCHEMAHERO_TAG=${SCHEMAHERO_TAG} ${DOCKER_BUILD_ARGS} -f ../dev/dockerfiles/kotsadm-migrations/Dockerfile.ttlsh -t ${IMAGE} .
docker push ${IMAGE}
3 changes: 2 additions & 1 deletion pkg/docker/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ func applicationPullSecretLabels() map[string]string {
var secretLabels map[string]string
if util.IsEmbeddedCluster() {
secretLabels = map[string]string{
kotsadmtypes.DisasterRecoveryLabel: kotsadmtypes.DisasterRecoveryLabelValueApp,
kotsadmtypes.DisasterRecoveryLabel: kotsadmtypes.DisasterRecoveryLabelValueInfra,
kotsadmtypes.DisasterRecoveryChartLabel: kotsadmtypes.DisasterRecoveryChartValue,
}
}

Expand Down
6 changes: 4 additions & 2 deletions pkg/docker/registry/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,8 @@ func TestPullSecretForRegistries(t *testing.T) {
"helm.sh/hook-weight": "-9999",
},
Labels: map[string]string{
"replicated.com/disaster-recovery": "app",
"replicated.com/disaster-recovery": "infra",
"replicated.com/disaster-recovery-chart": "admin-console",
},
},
Type: corev1.SecretTypeDockerConfigJson,
Expand Down Expand Up @@ -552,7 +553,8 @@ func TestGetDockerHubPullSecret(t *testing.T) {
"helm.sh/hook-weight": "-9999",
},
Labels: map[string]string{
"replicated.com/disaster-recovery": "app",
"replicated.com/disaster-recovery": "infra",
"replicated.com/disaster-recovery-chart": "admin-console",
},
},
Type: corev1.SecretTypeDockerConfigJson,
Expand Down
8 changes: 4 additions & 4 deletions pkg/handlers/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,21 +110,21 @@ func (h *Handler) ListBackups(w http.ResponseWriter, r *http.Request) {
}

type ListInstanceBackupsResponse struct {
Error string `json:"error,omitempty"`
Backups []*snapshottypes.Backup `json:"backups"`
Error string `json:"error,omitempty"`
Backups []*snapshottypes.ReplicatedBackup `json:"backups"`
}

func (h *Handler) ListInstanceBackups(w http.ResponseWriter, r *http.Request) {
listBackupsResponse := ListInstanceBackupsResponse{}

backups, err := snapshot.ListInstanceBackups(r.Context(), util.PodNamespace)
replicatedBackups, err := snapshot.ListInstanceBackups(r.Context(), util.PodNamespace)
if err != nil {
logger.Error(err)
listBackupsResponse.Error = "failed to list instance backups"
JSON(w, http.StatusInternalServerError, listBackupsResponse)
return
}
listBackupsResponse.Backups = backups
listBackupsResponse.Backups = replicatedBackups

JSON(w, http.StatusOK, listBackupsResponse)
}
Expand Down
22 changes: 22 additions & 0 deletions pkg/k8sutil/clientset.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import (
"github.com/pkg/errors"
embeddedclusterv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
flag "github.com/spf13/pflag"
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/discovery"
Expand Down Expand Up @@ -167,3 +169,23 @@ func GetKubeClient(ctx context.Context) (kbclient.Client, error) {
}
return kcli, nil
}

func GetVeleroKubeClient(ctx context.Context) (kbclient.Client, error) {
k8slogger := zap.New(func(o *zap.Options) {
o.DestWriter = io.Discard
})
log.SetLogger(k8slogger)
cfg, err := GetClusterConfig()
if err != nil {
return nil, errors.Wrap(err, "failed to get cluster config")
}
scheme := runtime.NewScheme()
velerov1.AddToScheme(scheme)
kcli, err := kbclient.New(cfg, kbclient.Options{
Scheme: scheme,
})
if err != nil {
return nil, errors.Wrap(err, "failed to create kubebuilder client")
}
return kcli, nil
}
81 changes: 50 additions & 31 deletions pkg/kotsadmsnapshot/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import (
"github.com/replicatedhq/kots/pkg/k8sutil"
"github.com/replicatedhq/kots/pkg/kotsadm"
kotsadmtypes "github.com/replicatedhq/kots/pkg/kotsadm/types"
"github.com/replicatedhq/kots/pkg/kotsadmsnapshot/k8sclient"
"github.com/replicatedhq/kots/pkg/kotsadmsnapshot/types"
"github.com/replicatedhq/kots/pkg/kotsadmsnapshot/veleroclient"
"github.com/replicatedhq/kots/pkg/kotsutil"
"github.com/replicatedhq/kots/pkg/kurl"
"github.com/replicatedhq/kots/pkg/logger"
Expand Down Expand Up @@ -81,12 +83,12 @@ func CreateApplicationBackup(ctx context.Context, a *apptypes.App, isScheduled b
return nil, errors.Wrap(err, "failed to get cluster config")
}

clientset, err := kubernetes.NewForConfig(cfg)
clientset, err := k8sclient.GetBuilder().GetClientset(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
veleroClient, err := veleroclient.GetBuilder().GetVeleroClient(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create velero clientset")
}
Expand Down Expand Up @@ -227,7 +229,7 @@ func CreateInstanceBackup(ctx context.Context, cluster *downstreamtypes.Downstre
return "", errors.Wrap(err, "failed to get cluster config")
}

k8sClient, err := kubernetes.NewForConfig(cfg)
k8sClient, err := k8sclient.GetBuilder().GetClientset(cfg)
if err != nil {
return "", errors.Wrap(err, "failed to create clientset")
}
Expand All @@ -237,7 +239,7 @@ func CreateInstanceBackup(ctx context.Context, cluster *downstreamtypes.Downstre
return "", fmt.Errorf("failed to get kubeclient: %w", err)
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
veleroClient, err := veleroclient.GetBuilder().GetVeleroClient(cfg)
if err != nil {
return "", errors.Wrap(err, "failed to create velero clientset")
}
Expand Down Expand Up @@ -269,14 +271,14 @@ func CreateInstanceBackup(ctx context.Context, cluster *downstreamtypes.Downstre
}
}

logger.Infof("Creating instance backup CR %s", veleroBackup.Name)
logger.Infof("Creating instance backup CR %s", veleroBackup.GenerateName)
backup, err := veleroClient.Backups(metadata.backupStorageLocationNamespace).Create(ctx, veleroBackup, metav1.CreateOptions{})
if err != nil {
return "", errors.Wrap(err, "failed to create velero backup")
}

if appVeleroBackup != nil {
logger.Infof("Creating instance app backup CR %s", appVeleroBackup.Name)
logger.Infof("Creating instance app backup CR %s", appVeleroBackup.GenerateName)
_, err := veleroClient.Backups(metadata.backupStorageLocationNamespace).Create(ctx, appVeleroBackup, metav1.CreateOptions{})
if err != nil {
return "", errors.Wrap(err, "failed to create application velero backup")
Expand Down Expand Up @@ -490,7 +492,7 @@ func getInfrastructureInstanceBackupSpec(ctx context.Context, k8sClient kubernet
}
}

veleroBackup.Annotations, err = appendCommonAnnotations(k8sClient, veleroBackup.Annotations, metadata, hasAppBackup)
veleroBackup.Annotations, err = appendCommonAnnotations(k8sClient, veleroBackup.Annotations, metadata)
if err != nil {
return nil, errors.Wrap(err, "failed to add annotations to backup")
}
Expand Down Expand Up @@ -519,13 +521,11 @@ func getInfrastructureInstanceBackupSpec(ctx context.Context, k8sClient kubernet
return veleroBackup, nil
}

var EnableImprovedDR = false

// getAppInstanceBackup returns a backup spec only if this is Embedded Cluster and the vendor has
// defined both a backup and restore custom resource (improved DR).
func getAppInstanceBackupSpec(k8sClient kubernetes.Interface, metadata instanceBackupMetadata) (*velerov1.Backup, error) {
// TODO(improveddr): remove this once we have fully implemented the improved DR
if !EnableImprovedDR {
if os.Getenv("ENABLE_IMPROVED_DR") != "true" {
return nil, nil
}

Expand Down Expand Up @@ -562,7 +562,7 @@ func getAppInstanceBackupSpec(k8sClient kubernetes.Interface, metadata instanceB
}

var err error
appVeleroBackup.Annotations, err = appendCommonAnnotations(k8sClient, appVeleroBackup.Annotations, metadata, true)
appVeleroBackup.Annotations, err = appendCommonAnnotations(k8sClient, appVeleroBackup.Annotations, metadata)
if err != nil {
return nil, errors.Wrap(err, "failed to add annotations to application backup")
}
Expand Down Expand Up @@ -624,6 +624,9 @@ func mergeAppBackupSpec(backup *velerov1.Backup, appMeta appInstanceBackupMetada
// excluded namespaces
backup.Spec.ExcludedNamespaces = append(backup.Spec.ExcludedNamespaces, kotskindsBackup.Spec.ExcludedNamespaces...)

// or label selectors
backup.Spec.OrLabelSelectors = append(backup.Spec.OrLabelSelectors, kotskindsBackup.Spec.OrLabelSelectors...)

// annotations
if len(kotskindsBackup.ObjectMeta.Annotations) > 0 {
if backup.Annotations == nil {
Expand Down Expand Up @@ -651,7 +654,7 @@ func mergeAppBackupSpec(backup *velerov1.Backup, appMeta appInstanceBackupMetada
}

// appendCommonAnnotations appends common annotations to the backup annotations
func appendCommonAnnotations(k8sClient kubernetes.Interface, annotations map[string]string, metadata instanceBackupMetadata, hasAppBackup bool) (map[string]string, error) {
func appendCommonAnnotations(k8sClient kubernetes.Interface, annotations map[string]string, metadata instanceBackupMetadata) (map[string]string, error) {
kotsadmImage, err := k8sutil.FindKotsadmImage(k8sClient, metadata.kotsadmNamespace)
if err != nil {
return nil, errors.Wrap(err, "failed to find kotsadm image")
Expand Down Expand Up @@ -713,12 +716,12 @@ func ListBackupsForApp(ctx context.Context, kotsadmNamespace string, appID strin
return nil, errors.Wrap(err, "failed to get cluster config")
}

clientset, err := kubernetes.NewForConfig(cfg)
clientset, err := k8sclient.GetBuilder().GetClientset(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
veleroClient, err := veleroclient.GetBuilder().GetVeleroClient(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create velero clientset")
}
Expand Down Expand Up @@ -840,18 +843,18 @@ func ListBackupsForApp(ctx context.Context, kotsadmNamespace string, appID strin
return backups, nil
}

func ListInstanceBackups(ctx context.Context, kotsadmNamespace string) ([]*types.Backup, error) {
func ListInstanceBackups(ctx context.Context, kotsadmNamespace string) ([]*types.ReplicatedBackup, error) {
cfg, err := k8sutil.GetClusterConfig()
if err != nil {
return nil, errors.Wrap(err, "failed to get cluster config")
}

clientset, err := kubernetes.NewForConfig(cfg)
clientset, err := k8sclient.GetBuilder().GetClientset(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
veleroClient, err := veleroclient.GetBuilder().GetVeleroClient(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create velero clientset")
}
Expand All @@ -870,7 +873,7 @@ func ListInstanceBackups(ctx context.Context, kotsadmNamespace string) ([]*types
return nil, errors.Wrap(err, "failed to list velero backups")
}

backups := []*types.Backup{}
replicatedBackupsMap := map[string]*types.ReplicatedBackup{}

for _, veleroBackup := range veleroBackups.Items {
// TODO: Enforce version?
Expand Down Expand Up @@ -970,10 +973,24 @@ func ListInstanceBackups(ctx context.Context, kotsadmNamespace string) ([]*types
}
}

backups = append(backups, &backup)
// group the velero backups by the name we present to the user
backupName := GetBackupName(veleroBackup)
if _, ok := replicatedBackupsMap[backupName]; !ok {
replicatedBackupsMap[backupName] = &types.ReplicatedBackup{
Name: backupName,
Backups: []types.Backup{},
ExpectedBackupCount: GetInstanceBackupCount(veleroBackup),
}
}
replicatedBackupsMap[backupName].Backups = append(replicatedBackupsMap[backupName].Backups, backup)
}

return backups, nil
replicatedBackups := []*types.ReplicatedBackup{}
for _, rb := range replicatedBackupsMap {
replicatedBackups = append(replicatedBackups, rb)
}

return replicatedBackups, nil
}

func getSnapshotVolumeSummary(ctx context.Context, veleroBackup *velerov1.Backup) (*types.VolumeSummary, error) {
Expand All @@ -982,7 +999,7 @@ func getSnapshotVolumeSummary(ctx context.Context, veleroBackup *velerov1.Backup
return nil, errors.Wrap(err, "failed to get cluster config")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
veleroClient, err := veleroclient.GetBuilder().GetVeleroClient(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}
Expand Down Expand Up @@ -1023,12 +1040,12 @@ func GetBackup(ctx context.Context, kotsadmNamespace string, backupID string) (*
return nil, errors.Wrap(err, "failed to get cluster config")
}

clientset, err := kubernetes.NewForConfig(cfg)
clientset, err := k8sclient.GetBuilder().GetClientset(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
veleroClient, err := veleroclient.GetBuilder().GetVeleroClient(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create velero clientset")
}
Expand Down Expand Up @@ -1069,12 +1086,12 @@ func DeleteBackup(ctx context.Context, kotsadmNamespace string, backupID string)
return errors.Wrap(err, "failed to get cluster config")
}

clientset, err := kubernetes.NewForConfig(cfg)
clientset, err := k8sclient.GetBuilder().GetClientset(cfg)
if err != nil {
return errors.Wrap(err, "failed to create clientset")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
veleroClient, err := veleroclient.GetBuilder().GetVeleroClient(cfg)
if err != nil {
return errors.Wrap(err, "failed to create velero clientset")
}
Expand Down Expand Up @@ -1122,14 +1139,16 @@ func HasUnfinishedApplicationBackup(ctx context.Context, kotsadmNamespace string
}

func HasUnfinishedInstanceBackup(ctx context.Context, kotsadmNamespace string) (bool, error) {
backups, err := ListInstanceBackups(ctx, kotsadmNamespace)
replicatedBackups, err := ListInstanceBackups(ctx, kotsadmNamespace)
if err != nil {
return false, errors.Wrap(err, "failed to list backups")
}

for _, backup := range backups {
if backup.Status == "New" || backup.Status == "InProgress" {
return true, nil
for _, replicatedBackup := range replicatedBackups {
for _, backup := range replicatedBackup.Backups {
if backup.Status == "New" || backup.Status == "InProgress" {
return true, nil
}
}
}

Expand All @@ -1142,12 +1161,12 @@ func GetBackupDetail(ctx context.Context, kotsadmNamespace string, backupID stri
return nil, errors.Wrap(err, "failed to get cluster config")
}

clientset, err := kubernetes.NewForConfig(cfg)
clientset, err := k8sclient.GetBuilder().GetClientset(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
veleroClient, err := veleroclient.GetBuilder().GetVeleroClient(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create velero clientset")
}
Expand Down
Loading

0 comments on commit 9157c48

Please sign in to comment.