diff --git a/pkg/cli/demo.go b/pkg/cli/demo.go index db9d08d6a2b2..7c10b08d2094 100644 --- a/pkg/cli/demo.go +++ b/pkg/cli/demo.go @@ -14,7 +14,10 @@ import ( "context" gosql "database/sql" "fmt" + "io/ioutil" + "net/http" "net/url" + "time" "github.com/cockroachdb/cockroach/pkg/base" "github.com/cockroachdb/cockroach/pkg/cli/cliflags" @@ -41,7 +44,12 @@ interactive SQL prompt to it. Various datasets are available to be preloaded as subcommands: e.g. "cockroach demo startrek". See --help for a full list. By default, the 'movr' dataset is pre-loaded. You can also use --empty -to avoid pre-loading a dataset.`, +to avoid pre-loading a dataset. + +cockroach demo attempts to obtain a temporary enterprise license for demoing +enterprise features and enable telemetry back to Cockroach Labs. In order to +disable this behavior, set the environment variable "COCKROACH_SKIP_UPDATE_CHECK". +`, Example: ` cockroach demo`, Args: cobra.NoArgs, RunE: MaybeDecorateGRPCError(func(cmd *cobra.Command, _ []string) error { @@ -49,6 +57,11 @@ to avoid pre-loading a dataset.`, }), } +// TODO (rohany): change this once another endpoint is setup for getting licenses. +// This URL grants a license that is valid for 1 hour. +const licenseURL = "https://register.cockroachdb.com/api/prodtest" +const demoOrg = "Cockroach Labs - Production Testing" + const defaultGeneratorName = "movr" var defaultGenerator workload.Generator @@ -95,6 +108,39 @@ func init() { } } +func getLicense() (string, error) { + client := &http.Client{ + Timeout: 5 * time.Second, + } + resp, err := client.Get(licenseURL) + if err != nil { + return "", err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return "", errors.New("unable to connect to licensing endpoint") + } + bodyBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + return string(bodyBytes), nil +} + +func getAndApplyLicense(db *gosql.DB) error { + license, err := getLicense() + if err != nil { + return err + } + if _, err := db.Exec(`SET CLUSTER SETTING cluster.organization = $1`, demoOrg); err != nil { + return err + } + if _, err := db.Exec(`SET CLUSTER SETTING enterprise.license = $1`, license); err != nil { + return err + } + return nil +} + func setupTransientServers( cmd *cobra.Command, gen workload.Generator, ) (connURL string, adminURL string, cleanup func(), err error) { @@ -189,6 +235,29 @@ func setupTransientServers( } urlStr := url.String() + // Start up the update check loop. + // We don't do this in (*server.Server).Start() because we don't want it + // in tests. + if shouldEnableTelemetry() { + s.PeriodicallyCheckForUpdates(ctx) + // If we allow telemetry, then also try and get an enterprise license for the demo. + if cliCtx.isInteractive { + db, err := gosql.Open("postgres", urlStr) + if err != nil { + return ``, ``, cleanup, err + } + // Perform license acquisition asynchronously to avoid delay in cli startup. + go func() { + defer db.Close() + err := getAndApplyLicense(db) + if err != nil { + msg := `error attempting to acquire demo license %+v. Enterprise feature are not enabled in this session` + log.Warningf(ctx, msg, err) + } + }() + } + } + // If there is a load generator, create its database and load its // fixture. if gen != nil { @@ -218,14 +287,14 @@ func runDemo(cmd *cobra.Command, gen workload.Generator) error { gen = defaultGenerator } + checkInteractive() + connURL, adminURL, cleanup, err := setupTransientServers(cmd, gen) defer cleanup() if err != nil { return checkAndMaybeShout(err) } - checkInteractive() - if cliCtx.isInteractive { fmt.Printf(`# # Welcome to the CockroachDB demo database! diff --git a/pkg/cli/start.go b/pkg/cli/start.go index abfde3050f97..7163751bae89 100644 --- a/pkg/cli/start.go +++ b/pkg/cli/start.go @@ -715,7 +715,7 @@ If problems persist, please see ` + base.DocsURL("cluster-setup-troubleshooting. // Start up the update check loop. // We don't do this in (*server.Server).Start() because we don't want it // in tests. - if !envutil.EnvOrDefaultBool("COCKROACH_SKIP_UPDATE_CHECK", false) { + if shouldEnableTelemetry() { s.PeriodicallyCheckForUpdates(ctx) } @@ -1076,6 +1076,10 @@ func logOutputDirectory() string { return startCtx.logDir.String() } +func shouldEnableTelemetry() bool { + return !envutil.EnvOrDefaultBool("COCKROACH_SKIP_UPDATE_CHECK", false) +} + // setupAndInitializeLoggingAndProfiling does what it says on the label. // Prior to this however it determines suitable defaults for the // logging output directory and the verbosity level of stderr logging.