github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/cli/context.go (about)

     1  // Copyright 2016 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package cli
    12  
    13  import (
    14  	"context"
    15  	"net/url"
    16  	"os"
    17  	"time"
    18  
    19  	"github.com/cockroachdb/cockroach/pkg/base"
    20  	"github.com/cockroachdb/cockroach/pkg/config/zonepb"
    21  	"github.com/cockroachdb/cockroach/pkg/server"
    22  	"github.com/cockroachdb/cockroach/pkg/settings"
    23  	"github.com/cockroachdb/cockroach/pkg/settings/cluster"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    25  	"github.com/cockroachdb/cockroach/pkg/storage"
    26  	"github.com/cockroachdb/cockroach/pkg/util/log"
    27  	"github.com/mattn/go-isatty"
    28  	"github.com/spf13/cobra"
    29  	"github.com/spf13/pflag"
    30  )
    31  
    32  // serverCfg is used as the client-side copy of default server
    33  // parameters for CLI utilities.
    34  //
    35  // NB: `cockroach start` further annotates serverCfg for the newly created
    36  // server.
    37  var serverCfg = func() server.Config {
    38  	st := cluster.MakeClusterSettings()
    39  	settings.SetCanonicalValuesContainer(&st.SV)
    40  
    41  	s := server.MakeConfig(context.Background(), st)
    42  	s.AuditLogDirName = &sqlAuditLogDir
    43  	return s
    44  }()
    45  
    46  var sqlAuditLogDir log.DirName
    47  
    48  // GetServerCfgStores provides direct public access to the StoreSpecList inside
    49  // serverCfg. This is used by CCL code to populate some fields.
    50  //
    51  // WARNING: consider very carefully whether you should be using this.
    52  func GetServerCfgStores() base.StoreSpecList {
    53  	return serverCfg.Stores
    54  }
    55  
    56  var baseCfg = serverCfg.Config
    57  
    58  // initCLIDefaults serves as the single point of truth for
    59  // configuration defaults. It is suitable for calling between tests of
    60  // the CLI utilities inside a single testing process.
    61  func initCLIDefaults() {
    62  	// We don't reset the pointers (because they are tied into the
    63  	// flags), but instead overwrite the existing structs' values.
    64  	baseCfg.InitDefaults()
    65  
    66  	// isInteractive is only set to `true` by `cockroach sql` -- all
    67  	// other client commands are non-interactive, regardless of whether
    68  	// the standard input is a terminal.
    69  	cliCtx.isInteractive = false
    70  	// See also setCLIDefaultForTests() in cli_test.go.
    71  	cliCtx.terminalOutput = isatty.IsTerminal(os.Stdout.Fd())
    72  	cliCtx.tableDisplayFormat = tableDisplayTSV
    73  	if cliCtx.terminalOutput {
    74  		// See also setCLIDefaultForTests() in cli_test.go.
    75  		cliCtx.tableDisplayFormat = tableDisplayTable
    76  	}
    77  	cliCtx.cmdTimeout = 0 // no timeout
    78  	cliCtx.clientConnHost = ""
    79  	cliCtx.clientConnPort = base.DefaultPort
    80  	cliCtx.certPrincipalMap = nil
    81  	cliCtx.sqlConnURL = ""
    82  	cliCtx.sqlConnUser = ""
    83  	cliCtx.sqlConnPasswd = ""
    84  	cliCtx.sqlConnDBName = ""
    85  	cliCtx.extraConnURLOptions = nil
    86  
    87  	sqlCtx.setStmts = nil
    88  	sqlCtx.execStmts = nil
    89  	sqlCtx.repeatDelay = 0
    90  	sqlCtx.safeUpdates = false
    91  	sqlCtx.showTimes = false
    92  	sqlCtx.debugMode = false
    93  	sqlCtx.echo = false
    94  
    95  	zipCtx.nodes = nodeSelection{}
    96  
    97  	dumpCtx.dumpMode = dumpBoth
    98  	dumpCtx.asOf = ""
    99  	dumpCtx.dumpAll = false
   100  
   101  	debugCtx.startKey = storage.NilKey
   102  	debugCtx.endKey = storage.MVCCKeyMax
   103  	debugCtx.values = false
   104  	debugCtx.sizes = false
   105  	debugCtx.replicated = false
   106  	debugCtx.inputFile = ""
   107  	debugCtx.printSystemConfig = false
   108  	debugCtx.maxResults = 0
   109  	debugCtx.ballastSize = base.SizeSpec{InBytes: 1000000000}
   110  
   111  	serverCfg.GoroutineDumpDirName = ""
   112  	serverCfg.HeapProfileDirName = ""
   113  	serverCfg.ReadyFn = nil
   114  	serverCfg.DelayedBootstrapFn = nil
   115  	serverCfg.SocketFile = ""
   116  	serverCfg.JoinList = nil
   117  	serverCfg.JoinPreferSRVRecords = false
   118  	serverCfg.DefaultZoneConfig = zonepb.DefaultZoneConfig()
   119  	serverCfg.DefaultSystemZoneConfig = zonepb.DefaultSystemZoneConfig()
   120  	// Attempt to default serverCfg.MemoryPoolSize to 25% if possible.
   121  	if bytes, _ := memoryPercentResolver(25); bytes != 0 {
   122  		serverCfg.MemoryPoolSize = bytes
   123  	}
   124  
   125  	startCtx.serverInsecure = baseCfg.Insecure
   126  	startCtx.serverSSLCertsDir = base.DefaultCertsDirectory
   127  	startCtx.serverCertPrincipalMap = nil
   128  	startCtx.serverListenAddr = ""
   129  	startCtx.unencryptedLocalhostHTTP = false
   130  	startCtx.tempDir = ""
   131  	startCtx.externalIODir = ""
   132  	startCtx.listeningURLFile = ""
   133  	startCtx.pidFile = ""
   134  	startCtx.inBackground = false
   135  	startCtx.geoLibsDir = "/usr/local/lib"
   136  
   137  	quitCtx.drainWait = 10 * time.Minute
   138  
   139  	nodeCtx.nodeDecommissionWait = nodeDecommissionWaitAll
   140  	nodeCtx.statusShowRanges = false
   141  	nodeCtx.statusShowStats = false
   142  	nodeCtx.statusShowAll = false
   143  	nodeCtx.statusShowDecommission = false
   144  
   145  	cfg := tree.DefaultPrettyCfg()
   146  	sqlfmtCtx.len = cfg.LineWidth
   147  	sqlfmtCtx.useSpaces = !cfg.UseTabs
   148  	sqlfmtCtx.tabWidth = cfg.TabWidth
   149  	sqlfmtCtx.noSimplify = !cfg.Simplify
   150  	sqlfmtCtx.align = (cfg.Align != tree.PrettyNoAlign)
   151  	sqlfmtCtx.execStmts = nil
   152  
   153  	systemBenchCtx.concurrency = 1
   154  	systemBenchCtx.duration = 60 * time.Second
   155  	systemBenchCtx.tempDir = "."
   156  	systemBenchCtx.writeSize = 32 << 10
   157  	systemBenchCtx.syncInterval = 512 << 10
   158  
   159  	networkBenchCtx.server = true
   160  	networkBenchCtx.port = 8081
   161  	networkBenchCtx.addresses = []string{"localhost:8081"}
   162  
   163  	demoCtx.nodes = 1
   164  	demoCtx.sqlPoolMemorySize = 128 << 20 // 128MB, chosen to fit 9 nodes on 2GB machine.
   165  	demoCtx.cacheSize = 64 << 20          // 64MB, chosen to fit 9 nodes on 2GB machine.
   166  	demoCtx.useEmptyDatabase = false
   167  	demoCtx.simulateLatency = false
   168  	demoCtx.runWorkload = false
   169  	demoCtx.localities = nil
   170  	demoCtx.geoPartitionedReplicas = false
   171  	demoCtx.disableTelemetry = false
   172  	demoCtx.disableLicenseAcquisition = false
   173  	demoCtx.transientCluster = nil
   174  	demoCtx.insecure = false
   175  	demoCtx.geoLibsDir = "/usr/local/lib"
   176  
   177  	authCtx.validityPeriod = 1 * time.Hour
   178  
   179  	initPreFlagsDefaults()
   180  
   181  	// Clear the "Changed" state of all the registered command-line flags.
   182  	clearFlagChanges(cockroachCmd)
   183  }
   184  
   185  func clearFlagChanges(cmd *cobra.Command) {
   186  	cmd.LocalFlags().VisitAll(func(f *pflag.Flag) { f.Changed = false })
   187  	for _, subCmd := range cmd.Commands() {
   188  		clearFlagChanges(subCmd)
   189  	}
   190  }
   191  
   192  // cliContext captures the command-line parameters of most CLI commands.
   193  type cliContext struct {
   194  	// Embed the base context.
   195  	*base.Config
   196  
   197  	// isInteractive indicates whether the session is interactive, that
   198  	// is, the commands executed are extremely likely to be *input* from
   199  	// a human user: the standard input is a terminal and `-e` was not
   200  	// used (the shell has a prompt).
   201  	isInteractive bool
   202  
   203  	// terminalOutput indicates whether output is going to a terminal,
   204  	// that is, it is not going to a file, another program for automated
   205  	// processing, etc.: the standard output is a terminal.
   206  	terminalOutput bool
   207  
   208  	// tableDisplayFormat indicates how to format result tables.
   209  	tableDisplayFormat tableDisplayFormat
   210  
   211  	// cmdTimeout sets the maximum run time for the command.
   212  	// Commands that wish to use this must use cmdTimeoutContext().
   213  	cmdTimeout time.Duration
   214  
   215  	// clientConnHost is the hostname/address to use to connect to a server.
   216  	clientConnHost string
   217  
   218  	// clientConnPort is the port name/number to use to connect to a server.
   219  	clientConnPort string
   220  
   221  	// certPrincipalMap is the cert-principal:db-principal map.
   222  	certPrincipalMap []string
   223  
   224  	// for CLI commands that use the SQL interface, these parameters
   225  	// determine how to connect to the server.
   226  	sqlConnURL, sqlConnUser, sqlConnDBName string
   227  
   228  	// The client password to use. This can be set via the --url flag.
   229  	sqlConnPasswd string
   230  
   231  	// extraConnURLOptions contains any additional query URL options
   232  	// specified in --url that do not have discrete equivalents.
   233  	extraConnURLOptions url.Values
   234  }
   235  
   236  // cliCtx captures the command-line parameters common to most CLI utilities.
   237  // Defaults set by InitCLIDefaults() above.
   238  var cliCtx = cliContext{Config: baseCfg}
   239  
   240  // sqlCtx captures the command-line parameters of the `sql` command.
   241  // Defaults set by InitCLIDefaults() above.
   242  var sqlCtx = struct {
   243  	*cliContext
   244  
   245  	// setStmts is a list of \set commands to execute before entering the sql shell.
   246  	setStmts statementsValue
   247  
   248  	// execStmts is a list of statements to execute.
   249  	execStmts statementsValue
   250  
   251  	// repeatDelay indicates that the execStmts should be "watched"
   252  	// at the specified time interval. Zero disables
   253  	// the watch.
   254  	repeatDelay time.Duration
   255  
   256  	// safeUpdates indicates whether to set sql_safe_updates in the CLI
   257  	// shell.
   258  	safeUpdates bool
   259  
   260  	// showTimes indicates whether to display query times after each result line.
   261  	showTimes bool
   262  
   263  	// echo, when set, requests that SQL queries sent to the server are
   264  	// also printed out on the client.
   265  	echo bool
   266  
   267  	// debugMode, when set, overrides the defaults to disable as much
   268  	// "intelligent behavior" in the SQL shell as possible and become
   269  	// more verbose (sets echo).
   270  	debugMode bool
   271  }{cliContext: &cliCtx}
   272  
   273  // zipCtx captures the command-line parameters of the `zip` command.
   274  // Defaults set by InitCLIDefaults() above.
   275  var zipCtx struct {
   276  	nodes nodeSelection
   277  }
   278  
   279  // dumpCtx captures the command-line parameters of the `dump` command.
   280  // Defaults set by InitCLIDefaults() above.
   281  var dumpCtx struct {
   282  	// dumpMode determines which part of the database should be dumped.
   283  	dumpMode dumpMode
   284  
   285  	// asOf determines the time stamp at which the dump should be taken.
   286  	asOf string
   287  
   288  	// dumpAll determines whenever we going to dump all databases
   289  	dumpAll bool
   290  }
   291  
   292  // authCtx captures the command-line parameters of the `auth-session`
   293  // command.
   294  var authCtx struct {
   295  	onlyCookie     bool
   296  	validityPeriod time.Duration
   297  }
   298  
   299  // debugCtx captures the command-line parameters of the `debug` command.
   300  // Defaults set by InitCLIDefaults() above.
   301  var debugCtx struct {
   302  	startKey, endKey  storage.MVCCKey
   303  	values            bool
   304  	sizes             bool
   305  	replicated        bool
   306  	inputFile         string
   307  	ballastSize       base.SizeSpec
   308  	printSystemConfig bool
   309  	maxResults        int
   310  }
   311  
   312  // startCtx captures the command-line arguments for the `start` command.
   313  // Defaults set by InitCLIDefaults() above.
   314  var startCtx struct {
   315  	// server-specific values of some flags.
   316  	serverInsecure         bool
   317  	serverSSLCertsDir      string
   318  	serverCertPrincipalMap []string
   319  	serverListenAddr       string
   320  
   321  	// if specified, this forces the HTTP listen addr to localhost
   322  	// and disables TLS on the HTTP listener.
   323  	unencryptedLocalhostHTTP bool
   324  
   325  	// temporary directory to use to spill computation results to disk.
   326  	tempDir string
   327  
   328  	// directory to use for remotely-initiated operations that can
   329  	// specify node-local I/O paths, like BACKUP/RESTORE/IMPORT.
   330  	externalIODir string
   331  
   332  	// inBackground is set to true when restarting in the
   333  	// background after --background was processed.
   334  	inBackground bool
   335  
   336  	// listeningURLFile indicates the file to which the server writes
   337  	// its listening URL when it is ready.
   338  	listeningURLFile string
   339  
   340  	// pidFile indicates the file to which the server writes its PID
   341  	// when it is ready.
   342  	pidFile string
   343  
   344  	// logging settings specific to file logging.
   345  	logDir log.DirName
   346  
   347  	// geoLibsDir is used to specify locations of the GEOS library.
   348  	geoLibsDir string
   349  }
   350  
   351  // quitCtx captures the command-line parameters of the `quit` and
   352  // `node drain` commands.
   353  // Defaults set by InitCLIDefaults() above.
   354  var quitCtx struct {
   355  	// drainWait is the amount of time to wait for the server
   356  	// to drain. Set to 0 to disable a timeout (let the server decide).
   357  	drainWait time.Duration
   358  }
   359  
   360  // nodeCtx captures the command-line parameters of the `node` command.
   361  // Defaults set by InitCLIDefaults() above.
   362  var nodeCtx struct {
   363  	nodeDecommissionWait   nodeDecommissionWaitType
   364  	statusShowRanges       bool
   365  	statusShowStats        bool
   366  	statusShowDecommission bool
   367  	statusShowAll          bool
   368  }
   369  
   370  // systemBenchCtx captures the command-line parameters of the `systembench` command.
   371  // Defaults set by InitCLIDefaults() above.
   372  var systemBenchCtx struct {
   373  	concurrency  int
   374  	duration     time.Duration
   375  	tempDir      string
   376  	writeSize    int64
   377  	syncInterval int64
   378  }
   379  
   380  var networkBenchCtx struct {
   381  	server    bool
   382  	port      int
   383  	addresses []string
   384  	latency   bool
   385  }
   386  
   387  // sqlfmtCtx captures the command-line parameters of the `sqlfmt` command.
   388  // Defaults set by InitCLIDefaults() above.
   389  var sqlfmtCtx struct {
   390  	len        int
   391  	useSpaces  bool
   392  	tabWidth   int
   393  	noSimplify bool
   394  	align      bool
   395  	execStmts  statementsValue
   396  }
   397  
   398  // demoCtx captures the command-line parameters of the `demo` command.
   399  // Defaults set by InitCLIDefaults() above.
   400  var demoCtx struct {
   401  	nodes                     int
   402  	sqlPoolMemorySize         int64
   403  	cacheSize                 int64
   404  	disableTelemetry          bool
   405  	disableLicenseAcquisition bool
   406  	useEmptyDatabase          bool
   407  	runWorkload               bool
   408  	localities                demoLocalityList
   409  	geoPartitionedReplicas    bool
   410  	simulateLatency           bool
   411  	transientCluster          *transientCluster
   412  	insecure                  bool
   413  	geoLibsDir                string
   414  }