Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: don't assume bash when displaying interactive CLI prompts #21899

Merged
merged 1 commit into from
Jul 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Because of the version bump to `go`, the macOS build for this release requires a
1. [21868](https://github.com/influxdata/influxdb/pull/21868): Migrate restored KV snapshots to latest schema before using them.
1. [21869](https://github.com/influxdata/influxdb/pull/21869): Specify which fields are missing when rejecting an incomplete onboarding request.
1. [21864](https://github.com/influxdata/influxdb/pull/21864): Systemd unit should block on startup until http endpoint is ready
1. [21839](https://github.com/influxdata/influxdb/pull/21839): Fix display and parsing of `influxd upgrade` CLI prompts in PowerShell.

## v2.0.7 [2021-06-04]
----------------------
Expand Down
15 changes: 6 additions & 9 deletions cmd/influxd/upgrade/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@ import (
"strings"

"github.com/dustin/go-humanize"
"github.com/influxdata/influx-cli/v2/clients"
"github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/cmd/internal"
"github.com/influxdata/influxdb/v2/pkg/fs"
"github.com/influxdata/influxdb/v2/v1/services/meta"
"github.com/tcnksm/go-input"
"go.uber.org/zap"
)

// upgradeDatabases creates databases, buckets, retention policies and shard info according to 1.x meta and copies data
func upgradeDatabases(ctx context.Context, ui *input.UI, v1 *influxDBv1, v2 *influxDBv2, opts *options, orgID influxdb.ID, log *zap.Logger) (map[string][]influxdb.ID, error) {
func upgradeDatabases(ctx context.Context, cli clients.CLI, v1 *influxDBv1, v2 *influxDBv2, opts *options, orgID influxdb.ID, log *zap.Logger) (map[string][]influxdb.ID, error) {
v1opts := opts.source
v2opts := opts.target
db2BucketIds := make(map[string][]influxdb.ID)
Expand All @@ -38,7 +37,7 @@ func upgradeDatabases(ctx context.Context, ui *input.UI, v1 *influxDBv1, v2 *inf
log.Info("No database found in the 1.x meta")
return db2BucketIds, nil
}
if err := checkDiskSpace(ui, opts, log); err != nil {
if err := checkDiskSpace(cli, opts, log); err != nil {
return nil, err
}

Expand Down Expand Up @@ -197,7 +196,7 @@ func upgradeDatabases(ctx context.Context, ui *input.UI, v1 *influxDBv1, v2 *inf

// checkDiskSpace ensures there is enough room at the target path to store
// a full copy of all V1 data.
func checkDiskSpace(ui *input.UI, opts *options, log *zap.Logger) error {
func checkDiskSpace(cli clients.CLI, opts *options, log *zap.Logger) error {
log.Info("Checking available disk space")

size, err := DirSize(opts.source.dataDir)
Expand Down Expand Up @@ -225,12 +224,10 @@ func checkDiskSpace(ui *input.UI, opts *options, log *zap.Logger) error {
return fmt.Errorf("not enough space on target disk of %s: need %d, available %d", v2dir, size, diskInfo.Free)
}
if !opts.force {
if confirmed := internal.GetConfirm(ui, func() string {
return fmt.Sprintf(`Proceeding will copy all V1 data to %q
if confirmed := cli.StdIO.GetConfirm(fmt.Sprintf(`Proceeding will copy all V1 data to %q
Space available: %s
Space required: %s
`, v2dir, freeBytes, requiredBytes)
}); !confirmed {
`, v2dir, freeBytes, requiredBytes)); !confirmed {
return errors.New("upgrade was canceled")
}
}
Expand Down
101 changes: 26 additions & 75 deletions cmd/influxd/upgrade/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@ import (
"context"
"errors"
"fmt"
"math"
"path/filepath"
"strconv"
"time"

"github.com/influxdata/influx-cli/v2/clients"
"github.com/influxdata/influx-cli/v2/clients/setup"
"github.com/influxdata/influx-cli/v2/config"
"github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/cmd/internal"
"github.com/tcnksm/go-input"
"go.uber.org/zap"
)

Expand All @@ -25,81 +22,35 @@ func setupAdmin(ctx context.Context, v2 *influxDBv2, req *influxdb.OnboardingReq
return res, nil
}

func onboardingRequest(ui *input.UI, options *options) (*influxdb.OnboardingRequest, error) {
if (options.force || len(options.target.password) > 0) && len(options.target.password) < internal.MinPasswordLen {
return nil, internal.ErrPasswordIsTooShort
}

req := &influxdb.OnboardingRequest{
User: options.target.userName,
Password: options.target.password,
Org: options.target.orgName,
Bucket: options.target.bucket,
RetentionPeriodSeconds: influxdb.InfiniteRetention,
Token: options.target.token,
}

if options.target.retention != "" {
dur, err := internal.RawDurationToTimeDuration(options.target.retention)
if err != nil {
return nil, err
}
secs, nanos := math.Modf(dur.Seconds())
if nanos > 0 {
return nil, fmt.Errorf("retention policy %q is too precise, must be divisible by 1s", options.target.retention)
}
req.RetentionPeriodSeconds = int64(secs)
}

if options.force {
return req, nil
}

fmt.Fprintln(ui.Writer, string(internal.PromptWithColor("Welcome to InfluxDB 2.0!", internal.ColorYellow)))
if req.User == "" {
req.User = internal.GetInput(ui, "Please type your primary username", "")
}
if req.Password == "" {
req.Password = internal.GetPassword(ui, false)
func onboardingRequest(cli clients.CLI, options *options) (*influxdb.OnboardingRequest, error) {
setupClient := setup.Client{CLI: cli}
cliReq, err := setupClient.OnboardingRequest(&setup.Params{
Username: options.target.userName,
Password: options.target.password,
AuthToken: options.target.token,
Org: options.target.orgName,
Bucket: options.target.bucket,
Retention: options.target.retention,
Force: options.force,
})
if err != nil {
return nil, err
}
if req.Org == "" {
req.Org = internal.GetInput(ui, "Please type your primary organization name", "")
req := influxdb.OnboardingRequest{
User: cliReq.Username,
Org: cliReq.Org,
Bucket: cliReq.Bucket,
}
if req.Bucket == "" {
req.Bucket = internal.GetInput(ui, "Please type your primary bucket name", "")
if cliReq.Password != nil {
req.Password = *cliReq.Password
}

// Check the initial opts instead of the req to distinguish not-set from explicit 0 over the CLI.
if options.target.retention == "" {
infiniteStr := strconv.Itoa(influxdb.InfiniteRetention)
for {
rpStr := internal.GetInput(ui,
"Please type your retention period in hours.\nOr press ENTER for infinite", infiniteStr)
rp, err := strconv.Atoi(rpStr)
if rp >= 0 && err == nil {
req.RetentionPeriodSeconds = int64((time.Duration(rp) * time.Hour).Seconds())
break
}
}
if cliReq.RetentionPeriodSeconds != nil {
req.RetentionPeriodSeconds = *cliReq.RetentionPeriodSeconds
}

if confirmed := internal.GetConfirm(ui, func() string {
rp := "infinite"
if req.RetentionPeriodSeconds > 0 {
rp = (time.Duration(req.RetentionPeriodSeconds) * time.Second).String()
}
return fmt.Sprintf(`
You have entered:
Username: %s
Organization: %s
Bucket: %s
Retention Period: %s
`, req.User, req.Org, req.Bucket, rp)
}); !confirmed {
return nil, errors.New("setup was canceled")
if cliReq.Token != nil {
req.Token = *cliReq.Token
}

return req, nil
return &req, nil
}

func saveLocalConfig(sourceOptions *optionsV1, targetOptions *optionsV2, log *zap.Logger) error {
Expand Down
14 changes: 7 additions & 7 deletions cmd/influxd/upgrade/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"path/filepath"
"strings"

"github.com/influxdata/influx-cli/v2/clients"
"github.com/influxdata/influx-cli/v2/pkg/stdio"
"github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/authorization"
"github.com/influxdata/influxdb/v2/bolt"
Expand All @@ -29,7 +31,6 @@ import (
"github.com/influxdata/influxdb/v2/v1/services/meta/filestore"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tcnksm/go-input"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
Expand Down Expand Up @@ -153,8 +154,7 @@ func NewCommand(ctx context.Context, v *viper.Viper) (*cobra.Command, error) {
if err != nil {
return err
}
ui := &input.UI{Writer: cmd.OutOrStdout(), Reader: cmd.InOrStdin()}
return runUpgradeE(ctx, ui, options, logger)
return runUpgradeE(ctx, clients.CLI{StdIO: stdio.TerminalStdio}, options, logger)
},
Args: cobra.NoArgs,
}
Expand Down Expand Up @@ -232,7 +232,7 @@ func NewCommand(ctx context.Context, v *viper.Viper) (*cobra.Command, error) {
DestP: &options.target.retention,
Flag: "retention",
Default: "",
Desc: "optional: duration bucket will retain data. 0 is infinite. The default is 0.",
Desc: "optional: duration bucket will retain data (i.e '1w' or '72h'). Default is infinite.",
Short: 'r',
},
{
Expand Down Expand Up @@ -349,7 +349,7 @@ func buildLogger(options *logOptions, verbose bool) (*zap.Logger, error) {
return log, nil
}

func runUpgradeE(ctx context.Context, ui *input.UI, options *options, log *zap.Logger) error {
func runUpgradeE(ctx context.Context, cli clients.CLI, options *options, log *zap.Logger) error {
if options.source.configFile != "" && options.source.dbDir != "" {
return errors.New("only one of --v1-dir or --config-file may be specified")
}
Expand Down Expand Up @@ -443,7 +443,7 @@ func runUpgradeE(ctx context.Context, ui *input.UI, options *options, log *zap.L
return errors.New("InfluxDB has been already set up")
}

req, err := onboardingRequest(ui, options)
req, err := onboardingRequest(cli, options)
if err != nil {
return err
}
Expand All @@ -461,7 +461,7 @@ func runUpgradeE(ctx context.Context, ui *input.UI, options *options, log *zap.L
return err
}

db2BucketIds, err := upgradeDatabases(ctx, ui, v1, v2, options, or.Org.ID, log)
db2BucketIds, err := upgradeDatabases(ctx, cli, v1, v2, options, or.Org.ID, log)
if err != nil {
// remove all files
log.Error("Database upgrade error, removing data", zap.Error(err))
Expand Down
7 changes: 2 additions & 5 deletions cmd/influxd/upgrade/upgrade_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package upgrade

import (
"bytes"
"context"
"fmt"
"io/ioutil"
Expand All @@ -13,6 +12,7 @@ import (
"github.com/BurntSushi/toml"
"github.com/dustin/go-humanize"
"github.com/google/go-cmp/cmp"
"github.com/influxdata/influx-cli/v2/clients"
"github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/bolt"
"github.com/influxdata/influxdb/v2/cmd/influxd/launcher"
Expand All @@ -22,7 +22,6 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/tcnksm/go-input"
"go.uber.org/zap"
"go.uber.org/zap/zaptest"
)
Expand Down Expand Up @@ -225,10 +224,8 @@ func TestUpgradeRealDB(t *testing.T) {
}

opts := &options{source: *v1opts, target: *v2opts, force: true}
ui := &input.UI{Writer: &bytes.Buffer{}, Reader: &bytes.Buffer{}}

log := zaptest.NewLogger(t, zaptest.Level(zap.InfoLevel))
err = runUpgradeE(ctx, ui, opts, log)
err = runUpgradeE(ctx, clients.CLI{}, opts, log)
require.NoError(t, err)

v := viper.New()
Expand Down
Loading