github.com/percona/percona-xtradb-cluster-operator@v1.14.0/cmd/pitr/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "log" 8 "os" 9 "os/signal" 10 "syscall" 11 "time" 12 13 "github.com/percona/percona-xtradb-cluster-operator/cmd/pitr/collector" 14 "github.com/percona/percona-xtradb-cluster-operator/cmd/pitr/recoverer" 15 16 "github.com/caarlos0/env" 17 ) 18 19 func main() { 20 command := "collect" 21 if len(os.Args) > 1 { 22 command = os.Args[1] 23 } 24 ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGTERM, os.Interrupt) 25 defer stop() 26 switch command { 27 case "collect": 28 runCollector(ctx) 29 case "recover": 30 runRecoverer(ctx) 31 default: 32 fmt.Fprintf(os.Stderr, "ERROR: unknown command \"%s\".\nCommands:\n collect - collect binlogs\n recover - recover from binlogs\n", command) 33 os.Exit(1) 34 } 35 } 36 37 func runCollector(ctx context.Context) { 38 config, err := getCollectorConfig() 39 if err != nil { 40 log.Fatalln("ERROR: get config:", err) 41 } 42 c, err := collector.New(ctx, config) 43 if err != nil { 44 log.Fatalln("ERROR: new controller:", err) 45 } 46 log.Println("run binlog collector") 47 for { 48 timeout, cancel := context.WithTimeout(ctx, time.Duration(config.CollectSpanSec)*time.Second) 49 defer cancel() 50 51 err := c.Run(timeout) 52 if err != nil { 53 log.Fatalln("ERROR:", err) 54 } 55 56 t := time.NewTimer(time.Duration(config.CollectSpanSec) * time.Second) 57 select { 58 case <-ctx.Done(): 59 log.Fatalln("ERROR:", ctx.Err().Error()) 60 case <-t.C: 61 break 62 } 63 } 64 } 65 66 func runRecoverer(ctx context.Context) { 67 config, err := getRecovererConfig() 68 if err != nil { 69 log.Fatalln("ERROR: get recoverer config:", err) 70 } 71 c, err := recoverer.New(ctx, config) 72 if err != nil { 73 log.Fatalln("ERROR: new recoverer controller:", err) 74 } 75 log.Println("run recover") 76 err = c.Run(ctx) 77 if err != nil { 78 log.Fatalln("ERROR: recover:", err) 79 } 80 } 81 82 func getCollectorConfig() (collector.Config, error) { 83 cfg := collector.Config{} 84 err := env.Parse(&cfg) 85 switch cfg.StorageType { 86 case "s3": 87 if err := env.Parse(&cfg.BackupStorageS3); err != nil { 88 return cfg, err 89 } 90 case "azure": 91 if err := env.Parse(&cfg.BackupStorageAzure); err != nil { 92 return cfg, err 93 } 94 default: 95 return cfg, errors.New("unknown STORAGE_TYPE") 96 } 97 98 return cfg, err 99 } 100 101 func getRecovererConfig() (recoverer.Config, error) { 102 cfg := recoverer.Config{} 103 if err := env.Parse(&cfg); err != nil { 104 return cfg, err 105 } 106 switch cfg.StorageType { 107 case "s3": 108 if err := env.Parse(&cfg.BackupStorageS3); err != nil { 109 return cfg, err 110 } 111 if err := env.Parse(&cfg.BinlogStorageS3); err != nil { 112 return cfg, err 113 } 114 case "azure": 115 if err := env.Parse(&cfg.BackupStorageAzure); err != nil { 116 return cfg, err 117 } 118 if err := env.Parse(&cfg.BinlogStorageAzure); err != nil { 119 return cfg, err 120 } 121 default: 122 return cfg, errors.New("unknown STORAGE_TYPE") 123 } 124 125 return cfg, nil 126 }