Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // Package cipd implements client side of Chrome Infra Package Deployer. | 5 // Package cipd implements client side of Chrome Infra Package Deployer. |
| 6 // | 6 // |
| 7 // Binary package file format (in free form representation): | 7 // Binary package file format (in free form representation): |
| 8 // <binary package> := <zipped data> | 8 // <binary package> := <zipped data> |
| 9 // <zipped data> := DeterministicZip(<all input files> + <manifest json>) | 9 // <zipped data> := DeterministicZip(<all input files> + <manifest json>) |
| 10 // <manifest json> := File{ | 10 // <manifest json> := File{ |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 // built it, revision of the source code it was built from, etc. All that | 25 // built it, revision of the source code it was built from, etc. All that |
| 26 // information will be distributed as a separate metadata packet associated with | 26 // information will be distributed as a separate metadata packet associated with |
| 27 // the package when it gets uploaded to the server. | 27 // the package when it gets uploaded to the server. |
| 28 // | 28 // |
| 29 // TODO: expand more when there's server-side package data model (labels | 29 // TODO: expand more when there's server-side package data model (labels |
| 30 // and stuff). | 30 // and stuff). |
| 31 package cipd | 31 package cipd |
| 32 | 32 |
| 33 import ( | 33 import ( |
| 34 "bufio" | 34 "bufio" |
| 35 "encoding/json" | |
| 35 "fmt" | 36 "fmt" |
| 36 "io" | 37 "io" |
| 37 "net/http" | 38 "net/http" |
| 38 "os" | 39 "os" |
| 39 "path/filepath" | 40 "path/filepath" |
| 40 "runtime" | 41 "runtime" |
| 41 "sort" | 42 "sort" |
| 42 "strings" | 43 "strings" |
| 43 "sync" | 44 "sync" |
| 44 "time" | 45 "time" |
| 45 | 46 |
| 46 "golang.org/x/net/context" | 47 "golang.org/x/net/context" |
| 47 | 48 |
| 48 "github.com/luci/luci-go/common/clock" | 49 "github.com/luci/luci-go/common/clock" |
| 49 "github.com/luci/luci-go/common/errors" | 50 "github.com/luci/luci-go/common/errors" |
| 50 "github.com/luci/luci-go/common/logging" | 51 "github.com/luci/luci-go/common/logging" |
| 51 | 52 |
| 52 "github.com/luci/luci-go/cipd/client/cipd/common" | 53 "github.com/luci/luci-go/cipd/client/cipd/common" |
| 53 "github.com/luci/luci-go/cipd/client/cipd/internal" | 54 "github.com/luci/luci-go/cipd/client/cipd/internal" |
| 54 "github.com/luci/luci-go/cipd/client/cipd/local" | 55 "github.com/luci/luci-go/cipd/client/cipd/local" |
| 56 "github.com/luci/luci-go/cipd/version" | |
| 55 ) | 57 ) |
| 56 | 58 |
| 57 // PackageACLChangeAction defines a flavor of PackageACLChange. | 59 // PackageACLChangeAction defines a flavor of PackageACLChange. |
| 58 type PackageACLChangeAction string | 60 type PackageACLChangeAction string |
| 59 | 61 |
| 60 const ( | 62 const ( |
| 61 // GrantRole is used in PackageACLChange to request a role to be granted . | 63 // GrantRole is used in PackageACLChange to request a role to be granted . |
| 62 GrantRole PackageACLChangeAction = "GRANT" | 64 GrantRole PackageACLChangeAction = "GRANT" |
| 63 // RevokeRole is used in PackageACLChange to request a role to be revoke d. | 65 // RevokeRole is used in PackageACLChange to request a role to be revoke d. |
| 64 RevokeRole PackageACLChangeAction = "REVOKE" | 66 RevokeRole PackageACLChangeAction = "REVOKE" |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 712 clientFileName = "cipd.exe" | 714 clientFileName = "cipd.exe" |
| 713 } | 715 } |
| 714 | 716 |
| 715 arch := runtime.GOARCH | 717 arch := runtime.GOARCH |
| 716 if arch == "arm" { | 718 if arch == "arm" { |
| 717 arch = "armv6l" | 719 arch = "armv6l" |
| 718 } | 720 } |
| 719 clientPackage = fmt.Sprintf("%s/%s-%s", clientPackageBase, platform, arc h) | 721 clientPackage = fmt.Sprintf("%s/%s-%s", clientPackageBase, platform, arc h) |
| 720 } | 722 } |
| 721 | 723 |
| 724 func (client *clientImpl) ensureClientVersionInfo(ctx context.Context, fs local. FileSystem, pin common.Pin, exePath string) { | |
| 725 verFile := version.GetVersionFile(exePath) | |
| 726 vfStat, err := os.Stat(verFile) | |
|
Vadim Sh.
2016/11/27 01:25:55
I'd remove both of these checks and just read the
iannucci
2016/11/29 01:46:20
Done.
| |
| 727 if err == nil { | |
| 728 eStat, err := os.Stat(exePath) | |
| 729 if err == nil { | |
| 730 if vfStat.ModTime().After(eStat.ModTime()) { | |
| 731 // version file already up to date | |
| 732 return | |
| 733 } | |
| 734 } | |
| 735 } | |
| 736 // there was an error statting one or both files, or the version file is older | |
| 737 // than the exe. Proceed with EnsureFile. | |
| 738 | |
| 739 err = fs.EnsureFile(ctx, verFile, func(of *os.File) error { | |
|
Vadim Sh.
2016/11/27 01:25:55
I forgot, does it create a full path? i.e. if ".ve
iannucci
2016/11/29 01:46:20
Yes :)
| |
| 740 return json.NewEncoder(of).Encode(version.Info{ | |
| 741 PackageName: pin.PackageName, | |
| 742 InstanceID: pin.InstanceID, | |
| 743 }) | |
| 744 }) | |
| 745 if err != nil { | |
| 746 logging.Warningf(ctx, "Unable to update version info %q: %s", ve rFile, err) | |
| 747 } | |
| 748 } | |
| 749 | |
| 722 func (client *clientImpl) MaybeUpdateClient(ctx context.Context, fs local.FileSy stem, targetVersion, currentHash, destination string) error { | 750 func (client *clientImpl) MaybeUpdateClient(ctx context.Context, fs local.FileSy stem, targetVersion, currentHash, destination string) error { |
| 723 if err := common.ValidateFileHash(currentHash); err != nil { | 751 if err := common.ValidateFileHash(currentHash); err != nil { |
| 724 return err | 752 return err |
| 725 } | 753 } |
| 726 | 754 |
| 727 client.BeginBatch(ctx) | 755 client.BeginBatch(ctx) |
| 728 defer client.EndBatch(ctx) | 756 defer client.EndBatch(ctx) |
| 729 | 757 |
| 730 logging.Infof(ctx, "cipd: maybe updating client to version %q", targetVe rsion) | 758 logging.Infof(ctx, "cipd: maybe updating client to version %q", targetVe rsion) |
| 731 pin, err := client.ResolveVersion(ctx, clientPackage, targetVersion) | 759 pin, err := client.ResolveVersion(ctx, clientPackage, targetVersion) |
| 732 if err != nil { | 760 if err != nil { |
| 733 return err | 761 return err |
| 734 } | 762 } |
| 735 | 763 |
| 736 cache := client.getTagCache() | 764 cache := client.getTagCache() |
| 737 exeHash := "" | 765 exeHash := "" |
| 738 if cache != nil { | 766 if cache != nil { |
| 739 if exeHash, err = cache.ResolveFile(ctx, pin, clientFileName); e rr != nil { | 767 if exeHash, err = cache.ResolveFile(ctx, pin, clientFileName); e rr != nil { |
| 740 return err | 768 return err |
| 741 } | 769 } |
| 742 } | 770 } |
| 743 if exeHash == currentHash { | 771 if exeHash == currentHash { |
| 744 » » // already up-to-date | 772 » » // already up-to-date. Make sure version file is up to date. |
| 773 » » client.ensureClientVersionInfo(ctx, fs, pin, destination) | |
| 745 return nil | 774 return nil |
| 746 } | 775 } |
| 747 | 776 |
| 748 logging.Infof(ctx, "cipd: updating client to %s", pin) | 777 logging.Infof(ctx, "cipd: updating client to %s", pin) |
| 749 | 778 |
| 750 info, err := client.remote.fetchClientBinaryInfo(ctx, pin) | 779 info, err := client.remote.fetchClientBinaryInfo(ctx, pin) |
| 751 if err != nil { | 780 if err != nil { |
| 752 return err | 781 return err |
| 753 } | 782 } |
| 754 if cache != nil { | 783 if cache != nil { |
| 755 if err = cache.AddFile(ctx, pin, clientFileName, info.clientBina ry.SHA1); err != nil { | 784 if err = cache.AddFile(ctx, pin, clientFileName, info.clientBina ry.SHA1); err != nil { |
| 756 return err | 785 return err |
| 757 } | 786 } |
| 758 } | 787 } |
| 759 client.doBatchAwareOp(ctx, batchAwareOpSaveTagCache) | 788 client.doBatchAwareOp(ctx, batchAwareOpSaveTagCache) |
| 760 if info.clientBinary.SHA1 == currentHash { | 789 if info.clientBinary.SHA1 == currentHash { |
| 761 » » // already up-to-date, but the cache didn't know that. | 790 » » // already up-to-date, but the cache didn't know that. Make sure version |
| 791 » » // file is update. | |
| 792 » » client.ensureClientVersionInfo(ctx, fs, pin, destination) | |
| 762 return nil | 793 return nil |
| 763 } | 794 } |
| 764 | 795 |
| 765 » return client.installClient(ctx, fs, info.clientBinary.FetchURL, destina tion) | 796 » if err := client.installClient(ctx, fs, info.clientBinary.FetchURL, dest ination); err != nil { |
| 797 » » return err | |
| 798 » } | |
| 799 | |
| 800 » client.ensureClientVersionInfo(ctx, fs, pin, destination) | |
| 801 » return nil | |
| 766 } | 802 } |
| 767 | 803 |
| 768 func (client *clientImpl) RegisterInstance(ctx context.Context, instance local.P ackageInstance, timeout time.Duration) error { | 804 func (client *clientImpl) RegisterInstance(ctx context.Context, instance local.P ackageInstance, timeout time.Duration) error { |
| 769 // Attempt to register. | 805 // Attempt to register. |
| 770 logging.Infof(ctx, "cipd: registering %s", instance.Pin()) | 806 logging.Infof(ctx, "cipd: registering %s", instance.Pin()) |
| 771 result, err := client.remote.registerInstance(ctx, instance.Pin()) | 807 result, err := client.remote.registerInstance(ctx, instance.Pin()) |
| 772 if err != nil { | 808 if err != nil { |
| 773 return err | 809 return err |
| 774 } | 810 } |
| 775 | 811 |
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1302 } | 1338 } |
| 1303 | 1339 |
| 1304 // buildInstanceIDMap builds mapping {package name -> instance ID}. | 1340 // buildInstanceIDMap builds mapping {package name -> instance ID}. |
| 1305 func buildInstanceIDMap(pins []common.Pin) map[string]string { | 1341 func buildInstanceIDMap(pins []common.Pin) map[string]string { |
| 1306 out := map[string]string{} | 1342 out := map[string]string{} |
| 1307 for _, p := range pins { | 1343 for _, p := range pins { |
| 1308 out[p.PackageName] = p.InstanceID | 1344 out[p.PackageName] = p.InstanceID |
| 1309 } | 1345 } |
| 1310 return out | 1346 return out |
| 1311 } | 1347 } |
| OLD | NEW |