Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The LUCI Authors. | 1 // Copyright 2015 The LUCI Authors. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. | 13 // limitations under the License. |
| 14 | 14 |
| 15 package main | 15 package main |
| 16 | 16 |
| 17 import ( | 17 import ( |
| 18 "encoding/json" | 18 "encoding/json" |
| 19 "errors" | 19 "errors" |
| 20 "fmt" | 20 "fmt" |
| 21 "io" | 21 "io" |
| 22 "log" | 22 "log" |
| 23 "os" | 23 "os" |
| 24 "time" | 24 "time" |
| 25 | 25 |
| 26 "github.com/golang/protobuf/proto" | 26 "github.com/golang/protobuf/proto" |
| 27 "github.com/maruel/subcommands" | 27 "github.com/maruel/subcommands" |
| 28 "golang.org/x/net/context" | 28 "golang.org/x/net/context" |
| 29 | 29 |
| 30 "github.com/luci/luci-go/client/isolate" | |
| 30 "github.com/luci/luci-go/common/auth" | 31 "github.com/luci/luci-go/common/auth" |
| 31 logpb "github.com/luci/luci-go/common/eventlog/proto" | 32 logpb "github.com/luci/luci-go/common/eventlog/proto" |
| 32 "github.com/luci/luci-go/common/isolated" | 33 "github.com/luci/luci-go/common/isolated" |
| 33 "github.com/luci/luci-go/common/isolatedclient" | 34 "github.com/luci/luci-go/common/isolatedclient" |
| 34 ) | 35 ) |
| 35 | 36 |
| 36 const ( | 37 const ( |
| 37 // archiveThreshold is the size (in bytes) used to determine whether to add | 38 // archiveThreshold is the size (in bytes) used to determine whether to add |
| 38 // files to a tar archive before uploading. Files smaller than this size will | 39 // files to a tar archive before uploading. Files smaller than this size will |
| 39 // be combined into archives before being uploaded to the server. | 40 // be combined into archives before being uploaded to the server. |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 67 // expArchiveRun contains the logic for the experimental archive subcommand. | 68 // expArchiveRun contains the logic for the experimental archive subcommand. |
| 68 // It implements subcommand.CommandRun | 69 // It implements subcommand.CommandRun |
| 69 type expArchiveRun struct { | 70 type expArchiveRun struct { |
| 70 commonServerFlags // Provides the GetFlags method. | 71 commonServerFlags // Provides the GetFlags method. |
| 71 isolateFlags isolateFlags | 72 isolateFlags isolateFlags |
| 72 loggingFlags loggingFlags | 73 loggingFlags loggingFlags |
| 73 dumpJSON string | 74 dumpJSON string |
| 74 } | 75 } |
| 75 | 76 |
| 76 // main contains the core logic for experimental archive. | 77 // main contains the core logic for experimental archive. |
| 77 func (c *expArchiveRun) main() error { | 78 func (c *expArchiveRun) main() error { |
|
mithro
2017/08/02 04:28:34
The main() in cmdExpArchive and cmdArchive should
mcgreevy
2017/08/02 05:16:38
Yes.
| |
| 78 start := time.Now() | 79 start := time.Now() |
| 79 archiveOpts := &c.isolateFlags.ArchiveOptions | 80 archiveOpts := &c.isolateFlags.ArchiveOptions |
| 80 | 81 |
| 81 // Set up a background context which is cancelled when this function ret urns. | 82 // Set up a background context which is cancelled when this function ret urns. |
| 82 ctx, cancel := context.WithCancel(context.Background()) | 83 ctx, cancel := context.WithCancel(context.Background()) |
| 83 defer cancel() | 84 defer cancel() |
| 84 | 85 |
| 85 // Create the isolated client which connects to the isolate server. | 86 // Create the isolated client which connects to the isolate server. |
| 86 authCl, err := c.createAuthClient() | 87 authCl, err := c.createAuthClient() |
| 87 if err != nil { | 88 if err != nil { |
| 88 return err | 89 return err |
| 89 } | 90 } |
| 90 client := isolatedclient.New(nil, authCl, c.isolatedFlags.ServerURL, c.i solatedFlags.Namespace, nil, nil) | 91 client := isolatedclient.New(nil, authCl, c.isolatedFlags.ServerURL, c.i solatedFlags.Namespace, nil, nil) |
| 91 | 92 |
| 93 eventlogger := NewLogger(ctx, c.loggingFlags.EventlogEndpoint) | |
| 94 | |
| 95 archiveDetails, err := doExpArchive(ctx, client, archiveOpts, c.dumpJSON ) | |
| 96 if err != nil { | |
| 97 return err | |
| 98 } | |
| 99 end := time.Now() | |
| 100 | |
| 101 op := logpb.IsolateClientEvent_ARCHIVE.Enum() | |
| 102 if err := eventlogger.logStats(ctx, op, start, end, archiveDetails); err != nil { | |
| 103 log.Printf("Failed to log to eventlog: %v", err) | |
| 104 } | |
| 105 | |
| 106 return nil | |
| 107 } | |
| 108 | |
| 109 // doExparchive performs the exparchive operation for an isolate specified by ar chiveOpts. | |
| 110 // dumpJSON is the path to write a JSON summary of the uploaded isolate, in the same format as batch_archive. | |
| 111 func doExpArchive(ctx context.Context, client *isolatedclient.Client, archiveOpt s *isolate.ArchiveOptions, dumpJSON string) (*logpb.IsolateClientEvent_ArchiveDe tails, error) { | |
| 92 // Set up a checker and uploader. We limit the uploader to one concurren t | 112 // Set up a checker and uploader. We limit the uploader to one concurren t |
| 93 // upload, since the uploads are all coming from disk (with the exceptio n of | 113 // upload, since the uploads are all coming from disk (with the exceptio n of |
| 94 // the isolated JSON itself) and we only want a single goroutine reading from | 114 // the isolated JSON itself) and we only want a single goroutine reading from |
| 95 // disk at once. | 115 // disk at once. |
| 96 checker := NewChecker(ctx, client) | 116 checker := NewChecker(ctx, client) |
| 97 uploader := NewUploader(ctx, client, 1) | 117 uploader := NewUploader(ctx, client, 1) |
| 98 archiver := NewTarringArchiver(checker, uploader) | 118 archiver := NewTarringArchiver(checker, uploader) |
| 99 | 119 |
| 100 isolSummary, err := archiver.Archive(archiveOpts) | 120 isolSummary, err := archiver.Archive(archiveOpts) |
| 121 if err != nil { | |
| 122 return nil, err | |
| 123 } | |
| 101 | 124 |
| 102 // Make sure that all pending items have been checked. | 125 // Make sure that all pending items have been checked. |
| 103 if err := checker.Close(); err != nil { | 126 if err := checker.Close(); err != nil { |
| 104 » » return err | 127 » » return nil, err |
| 105 } | 128 } |
| 106 | 129 |
| 107 // Make sure that all the uploads have completed successfully. | 130 // Make sure that all the uploads have completed successfully. |
| 108 if err := uploader.Close(); err != nil { | 131 if err := uploader.Close(); err != nil { |
| 109 » » return err | 132 » » return nil, err |
| 110 } | 133 } |
| 111 | 134 |
| 112 printSummary(isolSummary) | 135 printSummary(isolSummary) |
| 113 » if c.dumpJSON != "" { | 136 » if dumpJSON != "" { |
| 114 » » f, err := os.OpenFile(c.dumpJSON, os.O_RDWR|os.O_CREATE|os.O_TRU NC, 0644) | 137 » » f, err := os.OpenFile(dumpJSON, os.O_RDWR|os.O_CREATE|os.O_TRUNC , 0644) |
| 115 if err != nil { | 138 if err != nil { |
| 116 » » » return err | 139 » » » return nil, err |
| 117 } | 140 } |
| 118 writeSummaryJSON(f, isolSummary) | 141 writeSummaryJSON(f, isolSummary) |
| 119 f.Close() | 142 f.Close() |
| 120 } | 143 } |
| 121 | 144 |
| 122 end := time.Now() | |
| 123 | |
| 124 archiveDetails := &logpb.IsolateClientEvent_ArchiveDetails{ | 145 archiveDetails := &logpb.IsolateClientEvent_ArchiveDetails{ |
| 125 HitCount: proto.Int64(int64(checker.Hit.Count)), | 146 HitCount: proto.Int64(int64(checker.Hit.Count)), |
| 126 MissCount: proto.Int64(int64(checker.Miss.Count)), | 147 MissCount: proto.Int64(int64(checker.Miss.Count)), |
| 127 HitBytes: &checker.Hit.Bytes, | 148 HitBytes: &checker.Hit.Bytes, |
| 128 MissBytes: &checker.Miss.Bytes, | 149 MissBytes: &checker.Miss.Bytes, |
| 129 IsolateHash: []string{string(isolSummary.Digest)}, | 150 IsolateHash: []string{string(isolSummary.Digest)}, |
| 130 } | 151 } |
| 131 » eventlogger := NewLogger(ctx, c.loggingFlags.EventlogEndpoint) | 152 » return archiveDetails, nil |
| 132 » op := logpb.IsolateClientEvent_ARCHIVE.Enum() | |
| 133 » if err := eventlogger.logStats(ctx, op, start, end, archiveDetails); err != nil { | |
| 134 » » log.Printf("Failed to log to eventlog: %v", err) | |
| 135 » } | |
| 136 | |
| 137 » return nil | |
| 138 } | 153 } |
| 139 | 154 |
| 140 func writeSummaryJSON(w io.Writer, summaries ...IsolatedSummary) error { | 155 func writeSummaryJSON(w io.Writer, summaries ...IsolatedSummary) error { |
| 141 m := make(map[string]isolated.HexDigest) | 156 m := make(map[string]isolated.HexDigest) |
| 142 for _, summary := range summaries { | 157 for _, summary := range summaries { |
| 143 m[summary.Name] = summary.Digest | 158 m[summary.Name] = summary.Digest |
| 144 } | 159 } |
| 145 | 160 |
| 146 return json.NewEncoder(w).Encode(m) | 161 return json.NewEncoder(w).Encode(m) |
| 147 } | 162 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 172 if err := c.parseFlags(args); err != nil { | 187 if err := c.parseFlags(args); err != nil { |
| 173 fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err) | 188 fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err) |
| 174 return 1 | 189 return 1 |
| 175 } | 190 } |
| 176 if err := c.main(); err != nil { | 191 if err := c.main(); err != nil { |
| 177 fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err) | 192 fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err) |
| 178 return 1 | 193 return 1 |
| 179 } | 194 } |
| 180 return 0 | 195 return 0 |
| 181 } | 196 } |
| OLD | NEW |