diff --git a/cmd/root.go b/cmd/root.go index a8cc188cab..0423099836 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -130,6 +130,9 @@ the latest stable version will be downloaded from the repository.`, } } teleCommand = fmt.Sprintf("%s %s", cmd.CommandPath(), componentSpec) + if tag != "" { + fmt.Fprintln(os.Stderr, color.YellowString("--tag/-T is Deprecated in TiUP and moved to playground, it is suggested to use `tiup playground --tag` instead")) + } return exec.RunComponent(env, tag, componentSpec, binPath, transparentParams) } return cmd.Help() @@ -146,7 +149,7 @@ the latest stable version will be downloaded from the repository.`, rootCmd.PersistentFlags().BoolVarP(&repoOpts.SkipVersionCheck, "skip-version-check", "", false, "Skip the strict version check, by default a version must be a valid SemVer string") rootCmd.Flags().StringVarP(&binary, "binary", "B", "", "Print binary path of a specific version of a component `[:version]`\n"+ "and the latest version installed will be selected if no version specified") - rootCmd.Flags().StringVarP(&tag, "tag", "T", "", "Specify a tag for component instance") + rootCmd.Flags().StringVarP(&tag, "tag", "T", "", "[Deprecated] Specify a tag for component instance") rootCmd.Flags().StringVar(&binPath, "binpath", "", "Specify the binary path of component instance") // Some components will define themself -h flag, eg: // $ tiup dumpling -h ${host}. diff --git a/components/playground/env.go b/components/playground/env.go index c312b596bf..9e84d8f584 100644 --- a/components/playground/env.go +++ b/components/playground/env.go @@ -18,7 +18,6 @@ import ( "path/filepath" "github.com/pingcap/errors" - "github.com/pingcap/tiup/pkg/localdata" ) // targetTag find the target playground we want to send the command. @@ -28,17 +27,13 @@ import ( // 1. tiup playground // 2. tiup playground display func targetTag() (port int, err error) { - myTag := os.Getenv(localdata.EnvTag) - dir := os.Getenv(localdata.EnvNameInstanceDataDir) - dir = filepath.Dir(dir) - - port, err = loadPort(filepath.Join(dir, myTag)) + port, err = loadPort(dataDir) if err == nil { return port, nil } err = nil - _ = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + _ = filepath.Walk(filepath.Dir(dataDir), func(path string, info os.FileInfo, err error) error { if port != 0 { return filepath.SkipDir } diff --git a/components/playground/main.go b/components/playground/main.go index b59bc9773d..73850f5f27 100644 --- a/components/playground/main.go +++ b/components/playground/main.go @@ -18,6 +18,7 @@ import ( "database/sql" "encoding/json" "fmt" + "math" "net/http" _ "net/http/pprof" "os" @@ -71,6 +72,9 @@ var ( teleReport *telemetry.Report playgroundReport *telemetry.PlaygroundReport options = &BootOptions{} + tag string + tiupDataDir string + dataDir string ) const ( @@ -154,6 +158,32 @@ Examples: Args: func(cmd *cobra.Command, args []string) error { return nil }, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + tiupDataDir = os.Getenv(localdata.EnvNameInstanceDataDir) + tiupHome := os.Getenv(localdata.EnvNameHome) + if tiupHome == "" { + tiupHome, _ = getAbsolutePath(filepath.Join("~", localdata.ProfileDirName)) + } + if tiupDataDir == "" { + if tag == "" { + dataDir = filepath.Join(tiupHome, localdata.DataParentDir, base62Tag()) + } else { + dataDir = filepath.Join(tiupHome, localdata.DataParentDir, tag) + } + if dataDir == "" { + return errors.Errorf("cannot read environment variable %s nor %s", localdata.EnvNameInstanceDataDir, localdata.EnvNameHome) + } + err := os.MkdirAll(dataDir, os.ModePerm) + if err != nil { + return err + } + } else { + dataDir = tiupDataDir + } + instanceName := dataDir[strings.LastIndex(dataDir, "/")+1:] + fmt.Printf("\033]0;TiUP Playground: %s\a", instanceName) + return nil + }, RunE: func(cmd *cobra.Command, args []string) error { teleReport = new(telemetry.Report) playgroundReport = new(telemetry.PlaygroundReport) @@ -178,11 +208,6 @@ Examples: return err } - dataDir := os.Getenv(localdata.EnvNameInstanceDataDir) - if dataDir == "" { - return errors.Errorf("cannot read environment variable %s", localdata.EnvNameInstanceDataDir) - } - port, err := utils.GetFreePort("0.0.0.0", 9527) if err != nil { return err @@ -223,6 +248,7 @@ Examples: if atomic.LoadUint32(&booted) == 0 { cancel() time.AfterFunc(time.Second, func() { + removeData() os.Exit(0) }) return @@ -233,6 +259,7 @@ Examples: sig = (<-sc).(syscall.Signal) atomic.StoreInt32(&p.curSig, int32(syscall.SIGKILL)) if sig == syscall.SIGINT { + removeData() p.terminate(syscall.SIGKILL) } }() @@ -298,6 +325,7 @@ If you'd like to use a TiDB version other than %s, cancel and retry with the fol defaultOptions := &BootOptions{} rootCmd.Flags().String(mode, defaultMode, "TiUP playground mode: 'tidb', 'tikv-slim'") + rootCmd.Flags().StringVarP(&tag, "tag", "T", "", "Specify a tag for playground") rootCmd.Flags().Bool(withoutMonitor, false, "Don't start prometheus and grafana component") rootCmd.Flags().Bool(withMonitor, true, "Start prometheus and grafana component") _ = rootCmd.Flags().MarkDeprecated(withMonitor, "Please use --without-monitor to control whether to disable monitor.") @@ -341,6 +369,19 @@ If you'd like to use a TiDB version other than %s, cancel and retry with the fol return rootCmd.Execute() } +func base62Tag() string { + const base = 62 + const sets = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + b := make([]byte, 0) + num := time.Now().UnixNano() / int64(time.Millisecond) + for num > 0 { + r := math.Mod(float64(num), float64(base)) + num /= base + b = append([]byte{sets[int(r)]}, b...) + } + return string(b) +} + func populateOpt(flagSet *pflag.FlagSet) (err error) { var modeVal string if modeVal, err = flagSet.GetString(mode); err != nil { @@ -613,9 +654,6 @@ func newEtcdClient(endpoint string) (*clientv3.Client, error) { } func main() { - dataDir := os.Getenv(localdata.EnvNameInstanceDataDir) - instanceName := dataDir[strings.LastIndex(dataDir, "/")+1:] - fmt.Printf("\033]0;TiUP Playground: %s\a", instanceName) start := time.Now() code := 0 err := execute() @@ -672,3 +710,10 @@ func main() { os.Exit(code) } } + +func removeData() { + // remove if not set tag when run at standalone mode + if tiupDataDir == "" && tag == "" { + os.RemoveAll(dataDir) + } +} diff --git a/pkg/exec/run.go b/pkg/exec/run.go index 4470e18b8b..0d196148ac 100644 --- a/pkg/exec/run.go +++ b/pkg/exec/run.go @@ -217,17 +217,24 @@ func PrepareCommand(p *PrepareCommandParams) (*exec.Cmd, error) { return nil, err } + tiupWd, err := os.Getwd() + if err != nil { + return nil, err + } + envs := []string{ fmt.Sprintf("%s=%s", localdata.EnvNameHome, profile.Root()), fmt.Sprintf("%s=%s", localdata.EnvNameUserInputVersion, p.Version.String()), fmt.Sprintf("%s=%s", localdata.EnvNameTiUPVersion, version.NewTiUPVersion().SemVer()), - fmt.Sprintf("%s=%s", localdata.EnvNameInstanceDataDir, p.InstanceDir), fmt.Sprintf("%s=%s", localdata.EnvNameComponentDataDir, sd), fmt.Sprintf("%s=%s", localdata.EnvNameComponentInstallDir, installPath), fmt.Sprintf("%s=%s", localdata.EnvNameTelemetryStatus, teleMeta.Status), fmt.Sprintf("%s=%s", localdata.EnvNameTelemetryUUID, teleMeta.UUID), fmt.Sprintf("%s=%s", localdata.EnvNameTelemetrySecret, teleMeta.Secret), + // to be removed in TiUP 2.0 + fmt.Sprintf("%s=%s", localdata.EnvNameWorkDir, tiupWd), fmt.Sprintf("%s=%s", localdata.EnvTag, p.Tag), + fmt.Sprintf("%s=%s", localdata.EnvNameInstanceDataDir, p.InstanceDir), } envs = append(envs, os.Environ()...) envs = append(envs, p.EnvVariables...) diff --git a/pkg/localdata/constant.go b/pkg/localdata/constant.go index 4ea3dac28f..eb843658d9 100644 --- a/pkg/localdata/constant.go +++ b/pkg/localdata/constant.go @@ -54,6 +54,9 @@ const ( // EnvNameComponentInstallDir represents the install directory of specific component EnvNameComponentInstallDir = "TIUP_COMPONENT_INSTALL_DIR" + // EnvNameWorkDir represents the work directory of TiUP where user type the command `tiup xxx` + EnvNameWorkDir = "TIUP_WORK_DIR" + // EnvNameUserInputVersion represents the version user specified when running a component by `tiup component:version` EnvNameUserInputVersion = "TIUP_USER_INPUT_VERSION"