github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/cmd/thanosconvert/main.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"flag"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"strings"
    10  
    11  	"github.com/weaveworks/common/logging"
    12  	"gopkg.in/yaml.v2"
    13  
    14  	"github.com/cortexproject/cortex/pkg/storage/bucket"
    15  	"github.com/cortexproject/cortex/pkg/util/log"
    16  	"github.com/cortexproject/cortex/tools/thanosconvert"
    17  )
    18  
    19  func main() {
    20  	var (
    21  		configFilename string
    22  		dryRun         bool
    23  		cfg            bucket.Config
    24  	)
    25  
    26  	logfmt, loglvl := logging.Format{}, logging.Level{}
    27  	logfmt.RegisterFlags(flag.CommandLine)
    28  	loglvl.RegisterFlags(flag.CommandLine)
    29  	cfg.RegisterFlags(flag.CommandLine)
    30  	flag.StringVar(&configFilename, "config", "", "Path to bucket config YAML")
    31  	flag.BoolVar(&dryRun, "dry-run", false, "Don't make changes; only report what needs to be done")
    32  	flag.Usage = func() {
    33  		fmt.Fprintf(flag.CommandLine.Output(), "%s is a tool to convert block metadata from Thanos to Cortex.\nPlease see %s for instructions on how to run it.\n\n", os.Args[0], "https://cortexmetrics.io/docs/blocks-storage/migrate-storage-from-thanos-and-prometheus/")
    34  		fmt.Fprintf(flag.CommandLine.Output(), "Flags:\n")
    35  		flag.PrintDefaults()
    36  	}
    37  	flag.Parse()
    38  
    39  	logger, err := log.NewPrometheusLogger(loglvl, logfmt)
    40  	if err != nil {
    41  		fatal("failed to create logger: %v", err)
    42  	}
    43  
    44  	if configFilename != "" {
    45  		buf, err := ioutil.ReadFile(configFilename)
    46  		if err != nil {
    47  			fatal("failed to load config file from %s: %v", configFilename, err)
    48  		}
    49  		err = yaml.UnmarshalStrict(buf, &cfg)
    50  		if err != nil {
    51  			fatal("failed to parse config file: %v", err)
    52  		}
    53  	}
    54  
    55  	if err := cfg.Validate(); err != nil {
    56  		fatal("bucket config is invalid: %v", err)
    57  	}
    58  
    59  	ctx := context.Background()
    60  
    61  	converter, err := thanosconvert.NewThanosBlockConverter(ctx, cfg, dryRun, logger)
    62  	if err != nil {
    63  		fatal("couldn't initilize converter: %v", err)
    64  	}
    65  
    66  	iterCtx := context.Background()
    67  	results, err := converter.Run(iterCtx)
    68  
    69  	fmt.Println("Results:")
    70  	for user, res := range results {
    71  		fmt.Printf("User %s:\n", user)
    72  		fmt.Printf("  Converted %d:\n  %s", len(res.ConvertedBlocks), strings.Join(res.ConvertedBlocks, ","))
    73  		fmt.Printf("  Unchanged %d:\n  %s", len(res.UnchangedBlocks), strings.Join(res.UnchangedBlocks, ","))
    74  		fmt.Printf("  Failed %d:\n  %s", len(res.FailedBlocks), strings.Join(res.FailedBlocks, ","))
    75  	}
    76  
    77  	if err != nil {
    78  		fatal("converter failed: %v", err)
    79  	}
    80  
    81  }
    82  
    83  func fatal(msg string, args ...interface{}) {
    84  	fmt.Fprintf(os.Stderr, msg+"\n", args...)
    85  	os.Exit(1)
    86  }