diff --git a/pkg/ccl/baseccl/encryption_spec.go b/pkg/ccl/baseccl/encryption_spec.go index 16547632e47a..ef14ee1b953f 100644 --- a/pkg/ccl/baseccl/encryption_spec.go +++ b/pkg/ccl/baseccl/encryption_spec.go @@ -11,6 +11,7 @@ package baseccl import ( "bytes" "fmt" + "path/filepath" "strings" "time" @@ -220,3 +221,24 @@ func PopulateStoreSpecWithEncryption( } return nil } + +// EncryptionOptionsForStore takes a store directory and returns its ExtraOptions +// if a matching entry if found in the StoreEncryptionSpecList. +// The caller should appropriately set UseFileRegistry on a non-nil result. +func EncryptionOptionsForStore( + dir string, encryptionSpecs StoreEncryptionSpecList, +) ([]byte, error) { + // We need an absolute path, but the input may have come in relative. + path, err := filepath.Abs(dir) + if err != nil { + return nil, errors.Wrapf(err, "could not find absolute path for %s ", dir) + } + + for _, es := range encryptionSpecs.Specs { + if es.Path == path { + return es.toEncryptionOptions() + } + } + + return nil, nil +} diff --git a/pkg/ccl/cliccl/debug.go b/pkg/ccl/cliccl/debug.go new file mode 100644 index 000000000000..5b28dd4168aa --- /dev/null +++ b/pkg/ccl/cliccl/debug.go @@ -0,0 +1,43 @@ +// Copyright 2018 The Cockroach Authors. +// +// Licensed as a CockroachDB Enterprise file under the Cockroach Community +// License (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt + +package cliccl + +import ( + "github.com/cockroachdb/cockroach/pkg/ccl/baseccl" + "github.com/cockroachdb/cockroach/pkg/ccl/cliccl/cliflagsccl" + "github.com/cockroachdb/cockroach/pkg/cli" + "github.com/cockroachdb/cockroach/pkg/storage/engine" +) + +// This does not define new commands, only adds the encryption flag to debug commands in +// `pkg/cli/debug.go` and registers a callback to generate encryption options. + +func init() { + for _, cmd := range cli.DebugCmdsForRocksDB { + // storeEncryptionSpecs is in start.go. + cli.VarFlag(cmd.Flags(), &storeEncryptionSpecs, cliflagsccl.EnterpriseEncryption) + } + + cli.PopulateRocksDBConfigHook = fillEncryptionOptionsForStore +} + +// fillEncryptionOptionsForStore fills the RocksDBConfig fields +// based on the --enterprise-encryption flag value. +func fillEncryptionOptionsForStore(cfg *engine.RocksDBConfig) error { + opts, err := baseccl.EncryptionOptionsForStore(cfg.Dir, storeEncryptionSpecs) + if err != nil { + return err + } + + if opts != nil { + cfg.ExtraOptions = opts + cfg.UseFileRegistry = true + } + return nil +} diff --git a/pkg/cli/debug.go b/pkg/cli/debug.go index 3ba6476e435f..e4f830351df6 100644 --- a/pkg/cli/debug.go +++ b/pkg/cli/debug.go @@ -77,6 +77,11 @@ Create a ballast file to fill the store directory up to a given amount RunE: runDebugBallast, } +// PopulateRocksDBConfigHook is a callback set by CCL code. +// It populates any needed fields in the RocksDBConfig. +// It must do nothing in OSS code. +var PopulateRocksDBConfigHook func(*engine.RocksDBConfig) error + func parseRangeID(arg string) (roachpb.RangeID, error) { rangeIDInt, err := strconv.ParseInt(arg, 10, 64) if err != nil { @@ -95,19 +100,26 @@ func openExistingStore(dir string, stopper *stop.Stopper, readOnly bool) (*engin if err != nil { return nil, err } - db, err := engine.NewRocksDB( - engine.RocksDBConfig{ - Settings: serverCfg.Settings, - Dir: dir, - MaxOpenFiles: maxOpenFiles, - MustExist: true, - ReadOnly: readOnly, - }, - cache, - ) + + cfg := engine.RocksDBConfig{ + Settings: serverCfg.Settings, + Dir: dir, + MaxOpenFiles: maxOpenFiles, + MustExist: true, + ReadOnly: readOnly, + } + + if PopulateRocksDBConfigHook != nil { + if err := PopulateRocksDBConfigHook(&cfg); err != nil { + return nil, err + } + } + + db, err := engine.NewRocksDB(cfg, cache) if err != nil { return nil, err } + stopper.AddCloser(db) return db, nil } @@ -850,6 +862,7 @@ as 'ldb'. https://github.com/facebook/rocksdb/wiki/Administration-and-Data-Access-Tool#ldb-tool `, // LDB does its own flag parsing. + // TODO(mberhault): support encrypted stores. DisableFlagParsing: true, Run: func(cmd *cobra.Command, args []string) { engine.RunLDB(args) @@ -1097,23 +1110,28 @@ func init() { "only write to the WAL, not to sstables") } -var debugCmds = []*cobra.Command{ - debugBallastCmd, +// DebugCmdsForRocksDB lists debug commands that access rocksdb. +var DebugCmdsForRocksDB = []*cobra.Command{ + debugCheckStoreCmd, + debugCompactCmd, + debugGCCmd, debugKeysCmd, + debugRaftLogCmd, debugRangeDataCmd, debugRangeDescriptorsCmd, + debugSSTablesCmd, +} + +// All other debug commands go here. +var debugCmds = append(DebugCmdsForRocksDB, + debugBallastCmd, debugDecodeKeyCmd, - debugRaftLogCmd, - debugGCCmd, - debugCheckStoreCmd, debugRocksDBCmd, - debugCompactCmd, - debugSSTablesCmd, debugGossipValuesCmd, debugSyncTestCmd, debugEnvCmd, debugZipCmd, -} +) var debugCmd = &cobra.Command{ Use: "debug [command]",