feat: handle multiple commands sync and list duplicates
This commit is contained in:
parent
2ca045913d
commit
022d56dc8e
|
@ -0,0 +1,52 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"gitea.urkob.com/urko/backblaze-backup/internal/services"
|
||||
"gitea.urkob.com/urko/backblaze-backup/kit/config"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var Versions = &cobra.Command{
|
||||
Use: "versions",
|
||||
Short: "Handle versions of files in Backblaze",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
log.SetFlags(log.Lmicroseconds)
|
||||
ctx, cancel := context.WithCancel(signalContext(cmd.Context()))
|
||||
defer cancel()
|
||||
|
||||
envFile := ""
|
||||
if os.Getenv("BACKBLAZE_ENV") == "dev" {
|
||||
envFile = ".env"
|
||||
}
|
||||
cfg := config.NewConfig(envFile)
|
||||
|
||||
bbService := services.NewBackBlaze(cfg.BbId, cfg.BbKey)
|
||||
if err := bbService.ListDuplicateVersions(ctx); err != nil {
|
||||
log.Fatalln("bbService.ListDuplicateVersions()", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func signalContext(ctx context.Context) context.Context {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
log.Println("listening for shutdown signal")
|
||||
<-sigs
|
||||
log.Println("shutdown signal received")
|
||||
signal.Stop(sigs)
|
||||
close(sigs)
|
||||
cancel()
|
||||
}()
|
||||
|
||||
return ctx
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
|
@ -10,11 +10,14 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "backblaze-backup",
|
||||
Short: "Backblaze backup tool",
|
||||
var Sync = &cobra.Command{
|
||||
Use: "sync",
|
||||
Short: "Sync files or directories to Backblaze",
|
||||
Long: `A tool to backup files and directories to Backblaze.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
ctx, cancel := context.WithCancel(signalContext(cmd.Context()))
|
||||
defer cancel()
|
||||
|
||||
log.SetFlags(log.Lmicroseconds)
|
||||
filePath, err := cmd.Flags().GetString("file")
|
||||
if err != nil {
|
||||
|
@ -36,21 +39,8 @@ var rootCmd = &cobra.Command{
|
|||
cfg := config.NewConfig(envFile)
|
||||
|
||||
bbService := services.NewBackBlaze(cfg.BbId, cfg.BbKey).WithBucket(bucketName).WithDir(dir).WithFile(filePath)
|
||||
if err := bbService.Sync(); err != nil {
|
||||
if err := bbService.Sync(ctx); err != nil {
|
||||
log.Fatalln("bbService.Sync()", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.PersistentFlags().String("file", "", "absolute path of the file you want to upload to backblaze")
|
||||
rootCmd.PersistentFlags().String("dir", "", "absolute path of the directory you want to upload to backblaze")
|
||||
rootCmd.PersistentFlags().String("bucket", "", "backblaze bucket name")
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -50,7 +50,7 @@ func (b *BackBalze) WithFile(filePath string) *BackBalze {
|
|||
b.filePath = filePath
|
||||
return b
|
||||
}
|
||||
func (b *BackBalze) Sync() error {
|
||||
func (b *BackBalze) Sync(ctx context.Context) error {
|
||||
if b.bucketName == "" && (b.filePath == "" || b.dir == "") {
|
||||
return fmt.Errorf("bucket name is %v | filePath is %v | dir is %v", b.bucketName, b.filePath, b.dir)
|
||||
}
|
||||
|
@ -59,7 +59,6 @@ func (b *BackBalze) Sync() error {
|
|||
return errors.New("you must select just 1 option, dir or file")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
b2Client, err := b2.NewClient(ctx, b.bbID, b.bbKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("b2.NewClient %w", err)
|
||||
|
@ -302,3 +301,63 @@ func bucketFiles(ctx context.Context, bucket *b2.Bucket) ([]string, error) {
|
|||
}
|
||||
return files, nil
|
||||
}
|
||||
|
||||
type duplicate struct {
|
||||
bucket string
|
||||
file string
|
||||
count int
|
||||
}
|
||||
|
||||
func (b *BackBalze) ListDuplicateVersions(ctx context.Context) error {
|
||||
b2Client, err := b2.NewClient(ctx, b.bbID, b.bbKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("b2.NewClient %w", err)
|
||||
}
|
||||
log.Println("b2Client ok")
|
||||
|
||||
buckets, err := b2Client.ListBuckets(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("b2Client.Bucket %w", err)
|
||||
}
|
||||
|
||||
dups := make([]duplicate, 0)
|
||||
|
||||
log.Println("len(buckets)", len(buckets))
|
||||
for _, bc := range buckets {
|
||||
files := make(map[string]int, 0)
|
||||
|
||||
bucketIter := bc.List(ctx, b2.ListHidden())
|
||||
if bucketIter == nil {
|
||||
return fmt.Errorf("bucket list cannot be nil")
|
||||
}
|
||||
|
||||
for {
|
||||
if !bucketIter.Next() {
|
||||
if bucketIter.Err() != nil {
|
||||
return fmt.Errorf("bucketIter err %w", bucketIter.Err())
|
||||
}
|
||||
break
|
||||
}
|
||||
if bucketIter.Object() == nil {
|
||||
log.Println("bucketIter Object is nil")
|
||||
continue
|
||||
}
|
||||
files[bucketIter.Object().Name()]++
|
||||
}
|
||||
|
||||
// Search duplicates
|
||||
for file, count := range files {
|
||||
if count > 1 {
|
||||
dups = append(dups, duplicate{
|
||||
bucket: bc.Name(),
|
||||
file: file,
|
||||
count: count,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(dups) > 0 {
|
||||
return fmt.Errorf("found duplicates: %+v", dups)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"gitea.urkob.com/urko/backblaze-backup/cmd"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "backblaze-backup",
|
||||
Short: "Backblaze backup tool",
|
||||
Long: `A tool to backup files and directories to Backblaze.`,
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(cmd.Sync, cmd.Versions)
|
||||
cmd.Sync.PersistentFlags().String("file", "", "absolute path of the file you want to upload to backblaze")
|
||||
cmd.Sync.PersistentFlags().String("dir", "", "absolute path of the directory you want to upload to backblaze")
|
||||
cmd.Sync.PersistentFlags().String("bucket", "", "backblaze bucket name")
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := cmd.Sync.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue