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

remove network request before enter component #1539

Merged
merged 9 commits into from
Sep 1, 2021
59 changes: 24 additions & 35 deletions pkg/environment/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,21 +187,14 @@ 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
}

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
}
Expand All @@ -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
Expand Down
48 changes: 31 additions & 17 deletions pkg/exec/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
Expand All @@ -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)
}
}
Expand Down Expand Up @@ -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)
Expand Down
65 changes: 49 additions & 16 deletions pkg/repository/v1_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,54 @@ 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 {
err = r.ensureManifests()
if err != nil {
return nil, err
}
_, _, err := r.Local().LoadManifest(&index)

if err != nil {
return nil, err
}
}

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)
Expand Down Expand Up @@ -873,23 +921,8 @@ 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)
versionItem, err := r.LocalComponentVersion(componentID, ver, true)
if err != nil {
return "", err
}
Expand Down