From 9318464dcaf014aefa11e3f9d654f3860df24048 Mon Sep 17 00:00:00 2001 From: nexustar Date: Tue, 24 Aug 2021 18:42:33 +0800 Subject: [PATCH 1/5] remove repeated HasNightly check in BinaryPath() --- pkg/repository/v1_repository.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/pkg/repository/v1_repository.go b/pkg/repository/v1_repository.go index 42ea9e17b6..9b5c3b9d1b 100644 --- a/pkg/repository/v1_repository.go +++ b/pkg/repository/v1_repository.go @@ -875,21 +875,6 @@ func (r *V1Repository) LatestStableVersion(id string, withYanked bool) (utils.Ve // Support you have install the component, need to get entry from local manifest. // Load the manifest locally only to get then Entry, do not force do something need access mirror. func (r *V1Repository) BinaryPath(installPath string, componentID string, ver string) (string, error) { - component, err := r.updateComponentManifest(componentID, false) - if err != nil { - return "", err - } - - // Always use the newest nightly entry. - // Because the one the user installed may be scraped. - if utils.Version(ver).IsNightly() { - if !component.HasNightly(r.PlatformString()) { - return "", errors.Errorf("the component `%s` on platform %s does not have a nightly version", componentID, r.PlatformString()) - } - - ver = component.Nightly - } - // We need yanked version because we may have installed that version before it was yanked versionItem, err := r.ComponentVersion(componentID, ver, true) if err != nil { From bc7fb6b5481977519f0edf2a3e09cea4e0e02458 Mon Sep 17 00:00:00 2001 From: nexustar Date: Mon, 30 Aug 2021 15:49:20 +0800 Subject: [PATCH 2/5] remove network request before enter component --- pkg/environment/env.go | 59 ++++++++++++++------------------- pkg/exec/run.go | 48 +++++++++++++++++---------- pkg/repository/v1_repository.go | 42 ++++++++++++++++++++++- 3 files changed, 96 insertions(+), 53 deletions(-) diff --git a/pkg/environment/env.go b/pkg/environment/env.go index 88b21f7f32..b01abb7e54 100644 --- a/pkg/environment/env.go +++ b/pkg/environment/env.go @@ -187,13 +187,6 @@ func (env *Environment) downloadComponent(component string, version utils.Versio // SelectInstalledVersion selects the installed versions and the latest release version // will be chosen if there is an empty version func (env *Environment) SelectInstalledVersion(component string, ver utils.Version) (utils.Version, error) { - if ver == utils.NightlyVersionAlias { - var err error - if ver, _, err = env.v1Repo.LatestNightlyVersion(component); err != nil { - return ver, err - } - } - installed, err := env.Profile().InstalledVersions(component) if err != nil { return ver, err @@ -201,7 +194,7 @@ func (env *Environment) SelectInstalledVersion(component string, ver utils.Versi versions := []string{} for _, v := range installed { - vi, err := env.v1Repo.ComponentVersion(component, v, true) + vi, err := env.v1Repo.LocalComponentVersion(component, v, true) if errors.Cause(err) == repository.ErrUnknownVersion { continue } @@ -211,44 +204,40 @@ func (env *Environment) SelectInstalledVersion(component string, ver utils.Versi if vi.Yanked { continue } + if (string(ver) == utils.NightlyVersionAlias) != utils.Version(v).IsNightly() { + continue + } versions = append(versions, v) } + // Reverse sort: v5.0.0-rc,v5.0.0-nightly-20210305,v4.0.11 + sort.Slice(versions, func(i, j int) bool { + return semver.Compare(versions[i], versions[j]) > 0 + }) errInstallFirst := errors.Annotatef(ErrInstallFirst, "use `tiup install %s` to install component `%s` first", component, component) - if len(installed) == 0 { - return ver, errInstallFirst - } - if !ver.IsEmpty() { + if ver.IsEmpty() || string(ver) == utils.NightlyVersionAlias { + var selected utils.Version for _, v := range versions { - if utils.Version(v) == ver { - return ver, nil + if semver.Prerelease(v) == "" { + return utils.Version(v), nil + } + // select prerelease version when there is only prelease version on local + if selected.IsEmpty() { + selected = utils.Version(v) } } - return ver, errInstallFirst - } - - sort.Slice(versions, func(i, j int) bool { - // Reverse sort: v5.0.0-rc,v5.0.0-nightly-20210305,v4.0.11 - return semver.Compare(versions[i], versions[j]) > 0 - }) - - for _, v := range versions { - if utils.Version(v).IsNightly() { - continue + if !selected.IsEmpty() { + return selected, nil } - if semver.Prerelease(v) == "" { - ver = utils.Version(v) - break - } else if ver.IsEmpty() { - ver = utils.Version(v) + } else { + for _, v := range versions { + if utils.Version(v) == ver { + return ver, nil + } } } - - if ver.IsEmpty() { - return ver, errInstallFirst - } - return ver, nil + return ver, errInstallFirst } // DownloadComponentIfMissing downloads the specific version of a component if it is missing diff --git a/pkg/exec/run.go b/pkg/exec/run.go index 0c497550e7..1d0d636d4f 100644 --- a/pkg/exec/run.go +++ b/pkg/exec/run.go @@ -67,6 +67,7 @@ func RunComponent(env *environment.Environment, tag, spec, binPath string, args var sig syscall.Signal sc := make(chan os.Signal, 1) signal.Notify(sc, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) + updateC := make(chan string) defer func() { for err := range ch { @@ -87,6 +88,35 @@ func RunComponent(env *environment.Environment, tag, spec, binPath string, args ch <- p.Cmd.Wait() }() + // timeout for check update + go func() { + time.Sleep(time.Second) + updateC <- "" + }() + + go func() { + var updateInfo string + if version.IsEmpty() { + latestV, _, err := env.V1Repository().LatestStableVersion(p.Component, false) + if err != nil { + return + } + selectVer, _ := env.SelectInstalledVersion(component, version) + + if semver.Compare(selectVer.String(), latestV.String()) < 0 { + updateInfo = fmt.Sprint(color.YellowString(`Found %[1]s newer version: + + The latest version: %[2]s + Local installed version: %[3]s + Update current component: tiup update %[1]s + Update all components: tiup update --all +`, + p.Component, latestV.String(), selectVer.String())) + } + } + updateC <- updateInfo + }() + select { case s := <-sc: sig = s.(syscall.Signal) @@ -100,6 +130,7 @@ func RunComponent(env *environment.Environment, tag, spec, binPath string, args return nil case err := <-ch: + defer fmt.Println(<-updateC) return errors.Annotatef(err, "run `%s` (wd:%s) failed", p.Exec, p.Dir) } } @@ -151,23 +182,6 @@ func PrepareCommand(p *PrepareCommandParams) (*exec.Cmd, error) { return nil, err } - if p.Version.IsEmpty() && p.CheckUpdate { - latestV, _, err := env.V1Repository().LatestStableVersion(p.Component, false) - if err != nil { - return nil, err - } - if semver.Compare(selectVer.String(), latestV.String()) < 0 { - fmt.Fprintln(os.Stderr, color.YellowString(`Found %[1]s newer version: - - The latest version: %[2]s - Local installed version: %[3]s - Update current component: tiup update %[1]s - Update all components: tiup update --all -`, - p.Component, latestV.String(), selectVer.String())) - } - } - // playground && cluster version must greater than v1.0.0 if (p.Component == "playground" || p.Component == "cluster") && semver.Compare(selectVer.String(), "v1.0.0") < 0 { return nil, errors.Errorf("incompatible component version, please use `tiup update %s` to upgrade to the latest version", p.Component) diff --git a/pkg/repository/v1_repository.go b/pkg/repository/v1_repository.go index 9b5c3b9d1b..5925fb151e 100644 --- a/pkg/repository/v1_repository.go +++ b/pkg/repository/v1_repository.go @@ -758,6 +758,46 @@ func (r *V1Repository) ComponentVersion(id, ver string, includeYanked bool) (*v1 return vi, nil } +// LocalComponentVersion returns version item of a component from local manifest file +func (r *V1Repository) LocalComponentVersion(id, ver string, includeYanked bool) (*v1manifest.VersionItem, error) { + index := v1manifest.Index{} + _, exists, err := r.Local().LoadManifest(&index) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.Errorf("unreachable: index.json not found in manifests directory") + } + + components := index.ComponentList() + comp := components[id] + filename := v1manifest.ComponentManifestFilename(id) + manifest, err := r.Local().LoadComponentManifest(&comp, filename) + if err != nil { + return nil, err + } + + if ver == utils.NightlyVersionAlias { + if !manifest.HasNightly(r.PlatformString()) { + return nil, errors.Annotatef(ErrUnknownVersion, "component %s does not have nightly on %s", id, r.PlatformString()) + } + + ver = manifest.Nightly + } + if ver == "" { + v, _, err := r.LatestStableVersion(id, includeYanked) + if err != nil { + return nil, err + } + ver = v.String() + } + vi := manifest.VersionItem(r.PlatformString(), ver, includeYanked) + if vi == nil { + return nil, errors.Annotatef(ErrUnknownVersion, "version %s on %s for component %s not found", ver, r.PlatformString(), id) + } + return vi, nil +} + // ResolveComponentVersionWithPlatform resolves the latest version of a component that satisfies the constraint func (r *V1Repository) ResolveComponentVersionWithPlatform(id, constraint, platform string) (utils.Version, error) { manifest, err := r.FetchComponentManifest(id, false) @@ -876,7 +916,7 @@ func (r *V1Repository) LatestStableVersion(id string, withYanked bool) (utils.Ve // Load the manifest locally only to get then Entry, do not force do something need access mirror. func (r *V1Repository) BinaryPath(installPath string, componentID string, ver string) (string, error) { // We need yanked version because we may have installed that version before it was yanked - versionItem, err := r.ComponentVersion(componentID, ver, true) + versionItem, err := r.LocalComponentVersion(componentID, ver, true) if err != nil { return "", err } From bf077c25b282af5d2662e1ad6fe00c307b27cb15 Mon Sep 17 00:00:00 2001 From: nexustar Date: Tue, 31 Aug 2021 14:37:27 +0800 Subject: [PATCH 3/5] fix cant run component without local manifest --- pkg/repository/v1_repository.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg/repository/v1_repository.go b/pkg/repository/v1_repository.go index 86f0601988..656493b4de 100644 --- a/pkg/repository/v1_repository.go +++ b/pkg/repository/v1_repository.go @@ -764,7 +764,15 @@ func (r *V1Repository) LocalComponentVersion(id, ver string, includeYanked bool) return nil, err } if !exists { - return nil, errors.Errorf("unreachable: index.json not found in manifests directory") + err = r.ensureManifests() + if err != nil { + return nil, err + } + _, _, err := r.Local().LoadManifest(&index) + + if err != nil { + return nil, err + } } components := index.ComponentList() From bdae17ee7e8b517e1d9de2777275e199933a7dbb Mon Sep 17 00:00:00 2001 From: nexustar Date: Tue, 31 Aug 2021 17:45:09 +0800 Subject: [PATCH 4/5] adjust output when check update --- pkg/exec/run.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/exec/run.go b/pkg/exec/run.go index 1d0d636d4f..a70d1b7cac 100644 --- a/pkg/exec/run.go +++ b/pkg/exec/run.go @@ -104,8 +104,8 @@ func RunComponent(env *environment.Environment, tag, spec, binPath string, args selectVer, _ := env.SelectInstalledVersion(component, version) if semver.Compare(selectVer.String(), latestV.String()) < 0 { - updateInfo = fmt.Sprint(color.YellowString(`Found %[1]s newer version: - + updateInfo = fmt.Sprint(color.YellowString(` +Found %[1]s newer version: The latest version: %[2]s Local installed version: %[3]s Update current component: tiup update %[1]s @@ -130,7 +130,7 @@ func RunComponent(env *environment.Environment, tag, spec, binPath string, args return nil case err := <-ch: - defer fmt.Println(<-updateC) + defer fmt.Print(<-updateC) return errors.Annotatef(err, "run `%s` (wd:%s) failed", p.Exec, p.Dir) } } From 94bf2c8b25719ae493f24e926adf3f66e02a8712 Mon Sep 17 00:00:00 2001 From: nexustar Date: Tue, 31 Aug 2021 17:46:40 +0800 Subject: [PATCH 5/5] increase timeout when check update --- pkg/exec/run.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/exec/run.go b/pkg/exec/run.go index a70d1b7cac..773caffcef 100644 --- a/pkg/exec/run.go +++ b/pkg/exec/run.go @@ -90,7 +90,7 @@ func RunComponent(env *environment.Environment, tag, spec, binPath string, args // timeout for check update go func() { - time.Sleep(time.Second) + time.Sleep(2 * time.Second) updateC <- "" }()