github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/kbfstool/md_force_qr.go (about)

     1  package main
     2  
     3  import (
     4  	"errors"
     5  	"flag"
     6  	"fmt"
     7  
     8  	"github.com/keybase/client/go/kbfs/kbfsmd"
     9  	"github.com/keybase/client/go/kbfs/libkbfs"
    10  	"github.com/keybase/client/go/protocol/keybase1"
    11  	"golang.org/x/net/context"
    12  )
    13  
    14  func mdForceQROne(
    15  	ctx context.Context, config libkbfs.Config,
    16  	replacements replacementMap, input string, dryRun bool) error {
    17  	tlfStr, branchStr, startStr, stopStr, err := mdSplitInput(input)
    18  	if err != nil {
    19  		return err
    20  	}
    21  
    22  	_, branchID, start, stop, err :=
    23  		mdParseInput(ctx, config, tlfStr, branchStr, startStr, stopStr)
    24  	if err != nil {
    25  		return err
    26  	}
    27  
    28  	if branchID != kbfsmd.NullBranchID {
    29  		return errors.New("force-qr doesn't support branch IDs")
    30  	}
    31  	if start != stop {
    32  		return errors.New("force-qr doesn't support revision ranges")
    33  	}
    34  
    35  	// Get the latest head, and add a QR record up to that point.
    36  	irmd, err := mdGetMergedHeadForWriter(ctx, config, tlfStr)
    37  	if err != nil {
    38  		return err
    39  	}
    40  
    41  	rmdNext, err := irmd.MakeSuccessor(ctx, config.MetadataVersion(),
    42  		config.Codec(), config.KeyManager(),
    43  		config.KBPKI(), config.KBPKI(), config, irmd.MdID(), true)
    44  	if err != nil {
    45  		return err
    46  	}
    47  
    48  	// Pretend like we've done quota reclamation up through the
    49  	// specified revision.
    50  	gco := &libkbfs.GCOp{
    51  		LatestRev: start,
    52  	}
    53  	rmdNext.AddOp(gco)
    54  	rmdNext.SetLastGCRevision(start)
    55  
    56  	fmt.Printf(
    57  		"Will put a forced QR op up to revision %d:\n", start)
    58  	err = mdDumpReadOnlyRMD(ctx, config, "md forceQR", replacements, rmdNext.ReadOnly())
    59  	if err != nil {
    60  		return err
    61  	}
    62  
    63  	if dryRun {
    64  		fmt.Print("Dry-run set; not doing anything\n")
    65  		return nil
    66  	}
    67  
    68  	fmt.Printf("Putting revision %d...\n", rmdNext.Revision())
    69  
    70  	session, err := config.KBPKI().GetCurrentSession(ctx)
    71  	if err != nil {
    72  		return err
    73  	}
    74  
    75  	newIrmd, err := config.MDOps().Put(
    76  		ctx, rmdNext, session.VerifyingKey, nil, keybase1.MDPriorityNormal, nil)
    77  	if err != nil {
    78  		return err
    79  	}
    80  
    81  	fmt.Printf("New MD has revision %v\n", newIrmd.Revision())
    82  
    83  	return nil
    84  }
    85  
    86  const mdForceQRUsageStr = `Usage:
    87    kbfstool md forceQR /keybase/[public|private]/user1,assertion2
    88  
    89  `
    90  
    91  func mdForceQR(ctx context.Context, config libkbfs.Config,
    92  	args []string) (exitStatus int) {
    93  	flags := flag.NewFlagSet("kbfs md forceQR", flag.ContinueOnError)
    94  	dryRun := flags.Bool("d", false, "Dry run: don't actually do anything.")
    95  	err := flags.Parse(args)
    96  	if err != nil {
    97  		printError("md forceQR", err)
    98  		return 1
    99  	}
   100  
   101  	inputs := flags.Args()
   102  	if len(inputs) != 1 {
   103  		fmt.Print(mdForceQRUsageStr)
   104  		return 1
   105  	}
   106  
   107  	replacements := make(replacementMap)
   108  
   109  	err = mdForceQROne(ctx, config, replacements, inputs[0], *dryRun)
   110  	if err != nil {
   111  		printError("md forceQR", err)
   112  		return 1
   113  	}
   114  
   115  	fmt.Print("\n")
   116  
   117  	return 0
   118  }