diff --git a/Taskfile.yml b/Taskfile.yml index fc2d916..0efe41e 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,9 +1,26 @@ version: '3' +vars: + NAME: code.jhot.me/jhot/docker-s3-backup + tasks: + default: + vars: + TAG: latest build: cmds: - - docker buildx build -t {{.NAME}}:{{.TAG}} . - vars: - NAME: docker-s3-backup - TAG: latest + - docker buildx build --platform linux/amd64,linux/arm64 -t "{{.NAME}}:{{.TAG}}" . + push: + cmds: + - docker push "{{.NAME}}:{{.TAG}}" + tag: + prompt: This will push a git tag and docker image versioned {{.TAG}}... Do you want to continue? + cmds: + - task: build + vars: + NAME: "{{.NAME}}" + - task: push + vars: + NAME: "{{.NAME}}" + - git tag "{{.TAG}}" + - git push origin "{{.TAG}}" diff --git a/go.mod b/go.mod index 379c210..ae71762 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module code.jhot.me/jhot/docker-s3-backup -go 1.20 +go 1.21 require ( github.com/go-co-op/gocron v1.33.1 diff --git a/internal/backup.go b/internal/backup.go index ac1db2e..06d3171 100644 --- a/internal/backup.go +++ b/internal/backup.go @@ -10,29 +10,50 @@ import ( ) var ( - MinioClient *minio.Client + MinioClient *minio.Client + backupBuckets = []string{} + backupRoot string + s3Host string + s3Secure bool + s3Region string + s3User string + s3Pass string ) +func init() { + for _, bucket := range strings.Split(GetEnvWithDefault("BUCKET_NAMES", ""), ",") { + backupBuckets = append(backupBuckets, strings.TrimSpace(bucket)) + } + backupRoot = GetEnvWithDefault("BACKUP_ROOT", "/backup") + s3Host = GetEnvWithDefault("S3_HOST", "localhost:9000") + s3Secure = GetEnvWithDefault("S3_USE_SSL", "") == "true" + s3Region = GetEnvWithDefault("S3_REGION", "us-east-1") + s3User = GetEnvWithDefault("S3_ACCESS_KEY_ID", "") + s3Pass = GetEnvWithDefault("S3_ACCESS_KEY_SECRET", "") +} + func Backup(ctx context.Context) error { + logger.Info("Starting backup") var err error var getErrors = []string{} - bucketNames := GetEnvWithDefault("BUCKET_NAMES", "") - backupRoot := GetEnvWithDefault("BACKUP_ROOT", "/backup") - MinioClient, err = minio.New(GetEnvWithDefault("S3_HOST", "localhost"), &minio.Options{ - Creds: credentials.NewStaticV4(GetEnvWithDefault("S3_ACCESS_KEY_ID", ""), GetEnvWithDefault("S3_ACCESS_KEY_SECRET", ""), ""), - Secure: GetEnvWithDefault("S3_USE_SSL", "") == "true", - Region: GetEnvWithDefault("S3_REGION", "us-east-1"), + MinioClient, err = minio.New(s3Host, &minio.Options{ + Creds: credentials.NewStaticV4(s3User, s3Pass, ""), + Secure: s3Secure, + Region: s3Region, }) if err != nil { + logger.Error("Error connecting to S3", "error", err) return err } + logger.Debug("Connected to S3", "host", s3Host) - for _, bucket := range strings.Split(bucketNames, ",") { - bucket = strings.TrimSpace(bucket) + for _, bucket := range backupBuckets { + logger.Debug("Backing up bucket", "bucket", bucket) for object := range MinioClient.ListObjects(ctx, bucket, minio.ListObjectsOptions{Recursive: true}) { getError := MinioClient.FGetObject(ctx, bucket, object.Key, fmt.Sprintf("%s/%s/%s", backupRoot, bucket, object.Key), minio.GetObjectOptions{}) if getError != nil { + logger.Error("Error getting object", "bucket", bucket, "error", getError) getErrors = append(getErrors, getError.Error()) } } diff --git a/internal/logger.go b/internal/logger.go new file mode 100644 index 0000000..f84732c --- /dev/null +++ b/internal/logger.go @@ -0,0 +1,14 @@ +package internal + +import ( + "log/slog" + "os" +) + +var ( + logger *slog.Logger +) + +func init() { + logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})) +} diff --git a/internal/schedule.go b/internal/schedule.go index 25ab691..1e127b5 100644 --- a/internal/schedule.go +++ b/internal/schedule.go @@ -12,12 +12,14 @@ var ( ) func StartSchedule(ctx context.Context) error { + logger.Info("Starting schedule") cronExpression := GetEnvWithDefault("SCHEDULE_CRON", "0 0 * * *") scheduler = gocron.NewScheduler(time.Local) - _, err := scheduler.Cron(cronExpression).Do(Backup, ctx) + job, err := scheduler.Cron(cronExpression).Do(Backup, ctx) if err != nil { return err } + logger.Debug("Next scheduled backup", "time", job.NextRun()) scheduler.StartBlocking() return nil }