Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(340)

Side by Side Diff: client/cmd/isolate/exp_archive.go

Issue 2986773002: isolate: pull uploading of deps out of exparchive main. (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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,
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 walker := partitioningWalker{fsView: fsView} 162 walker := partitioningWalker{fsView: fsView}
163 for _, dep := range deps { 163 for _, dep := range deps {
164 // Try to walk dep. If dep is a file (or symlink), the inner fun ction is called exactly once. 164 // Try to walk dep. If dep is a file (or symlink), the inner fun ction is called exactly once.
165 if err := filepath.Walk(filepath.Clean(dep), walker.walkFn); err != nil { 165 if err := filepath.Walk(filepath.Clean(dep), walker.walkFn); err != nil {
166 return partitionedDeps{}, err 166 return partitionedDeps{}, err
167 } 167 }
168 } 168 }
169 return walker.parts, nil 169 return walker.parts, nil
170 } 170 }
171 171
172 // main contains the core logic for experimental archive. 172 func uploadDeps(parts partitionedDeps, checker *Checker, uploader *Uploader) (ma p[string]isolated.File, error) {
173 func (c *expArchiveRun) main() error {
174 » // TODO(djd): This func is long and has a lot of internal complexity (li ke,
175 » // such as, archiveCallback). Refactor.
176
177 » start := time.Now()
178 » archiveOpts := &c.isolateFlags.ArchiveOptions
179 » // Parse the incoming isolate file.
180 » deps, rootDir, isol, err := isolate.ProcessIsolate(archiveOpts)
181 » if err != nil {
182 » » return fmt.Errorf("failed to process isolate: %v", err)
183 » }
184 » log.Printf("Isolate referenced %d deps", len(deps))
185
186 » // Set up a background context which is cancelled when this function ret urns.
187 » ctx, cancel := context.WithCancel(context.Background())
188 » defer cancel()
189
190 » // Create the isolated client which connects to the isolate server.
191 » authCl, err := c.createAuthClient()
192 » if err != nil {
193 » » return err
194 » }
195 » client := isolatedclient.New(nil, authCl, c.isolatedFlags.ServerURL, c.i solatedFlags.Namespace, nil, nil)
196
197 » // Set up a checker and uploader. We limit the uploader to one concurren t
198 » // upload, since the uploads are all coming from disk (with the exceptio n of
199 » // the isolated JSON itself) and we only want a single goroutine reading from
200 » // disk at once.
201 » checker := NewChecker(ctx, client)
202 » uploader := NewUploader(ctx, client, 1)
203
204 » parts, err := partitionDeps(deps, rootDir, c.isolateFlags.ArchiveOptions .Blacklist)
205 » if err != nil {
206 » » return fmt.Errorf("partitioning deps: %v", err)
207 » }
208
209 // Construct a map of the files that constitute the isolate. 173 // Construct a map of the files that constitute the isolate.
210 files := make(map[string]isolated.File) 174 files := make(map[string]isolated.File)
211 175
212 numFiles := len(parts.filesToArchive.items) + len(parts.indivFiles.items )
213 filesSize := uint64(parts.filesToArchive.totalSize + parts.indivFiles.to talSize)
214 log.Printf("Isolate expanded to %d files (total size %s) and %d symlinks ", numFiles, humanize.Bytes(filesSize), len(parts.links.items))
215 log.Printf("\t%d files (%s) to be isolated individually", len(parts.indi vFiles.items), humanize.Bytes(uint64(parts.indivFiles.totalSize)))
216 log.Printf("\t%d files (%s) to be isolated in archives", len(parts.files ToArchive.items), humanize.Bytes(uint64(parts.filesToArchive.totalSize)))
217
218 // Handle the symlinks. 176 // Handle the symlinks.
219 for _, item := range parts.links.items { 177 for _, item := range parts.links.items {
220 l, err := os.Readlink(item.Path) 178 l, err := os.Readlink(item.Path)
221 if err != nil { 179 if err != nil {
222 » » » return fmt.Errorf("unable to resolve symlink for %q: %v" , item.Path, err) 180 » » » return nil, fmt.Errorf("unable to resolve symlink for %q : %v", item.Path, err)
223 } 181 }
224 files[item.RelPath] = isolated.SymLink(l) 182 files[item.RelPath] = isolated.SymLink(l)
225 } 183 }
226 184
227 // Handle the small to-be-archived files. 185 // Handle the small to-be-archived files.
228 bundles := ShardItems(parts.filesToArchive.items, archiveMaxSize) 186 bundles := ShardItems(parts.filesToArchive.items, archiveMaxSize)
229 log.Printf("\t%d TAR archives to be isolated", len(bundles)) 187 log.Printf("\t%d TAR archives to be isolated", len(bundles))
230 188
231 for _, bundle := range bundles { 189 for _, bundle := range bundles {
232 bundle := bundle 190 bundle := bundle
233 digest, tarSize, err := bundle.Digest() 191 digest, tarSize, err := bundle.Digest()
234 if err != nil { 192 if err != nil {
235 » » » return err 193 » » » return nil, err
236 } 194 }
237 195
238 log.Printf("Created tar archive %q (%s)", digest, humanize.Bytes (uint64(tarSize))) 196 log.Printf("Created tar archive %q (%s)", digest, humanize.Bytes (uint64(tarSize)))
239 log.Printf("\tcontains %d files (total %s)", len(bundle.Items), humanize.Bytes(uint64(bundle.ItemSize))) 197 log.Printf("\tcontains %d files (total %s)", len(bundle.Items), humanize.Bytes(uint64(bundle.ItemSize)))
240 // Mint an item for this tar. 198 // Mint an item for this tar.
241 item := &Item{ 199 item := &Item{
242 Path: fmt.Sprintf(".%s.tar", digest), 200 Path: fmt.Sprintf(".%s.tar", digest),
243 RelPath: fmt.Sprintf(".%s.tar", digest), 201 RelPath: fmt.Sprintf(".%s.tar", digest),
244 Size: tarSize, 202 Size: tarSize,
245 Mode: 0644, // Read 203 Mode: 0644, // Read
246 Digest: digest, 204 Digest: digest,
247 } 205 }
248 files[item.RelPath] = isolated.TarFile(item.Digest, int(item.Mod e), item.Size) 206 files[item.RelPath] = isolated.TarFile(item.Digest, int(item.Mod e), item.Size)
249 207
250 checker.AddItem(item, false, func(item *Item, ps *isolatedclient .PushState) { 208 checker.AddItem(item, false, func(item *Item, ps *isolatedclient .PushState) {
251 if ps == nil { 209 if ps == nil {
252 return 210 return
253 } 211 }
254 log.Printf("QUEUED %q for upload", item.RelPath) 212 log.Printf("QUEUED %q for upload", item.RelPath)
255 uploader.Upload(item.RelPath, bundle.Contents, ps, func( ) { 213 uploader.Upload(item.RelPath, bundle.Contents, ps, func( ) {
256 log.Printf("UPLOADED %q", item.RelPath) 214 log.Printf("UPLOADED %q", item.RelPath)
257 }) 215 })
258 }) 216 })
259 } 217 }
260 218
261 // Handle the large individually-uploaded files. 219 // Handle the large individually-uploaded files.
262 for _, item := range parts.indivFiles.items { 220 for _, item := range parts.indivFiles.items {
263 d, err := hashFile(item.Path) 221 d, err := hashFile(item.Path)
264 if err != nil { 222 if err != nil {
265 » » » return err 223 » » » return nil, err
266 } 224 }
267 item.Digest = d 225 item.Digest = d
268 files[item.RelPath] = isolated.BasicFile(item.Digest, int(item.M ode), item.Size) 226 files[item.RelPath] = isolated.BasicFile(item.Digest, int(item.M ode), item.Size)
269 checker.AddItem(item, false, func(item *Item, ps *isolatedclient .PushState) { 227 checker.AddItem(item, false, func(item *Item, ps *isolatedclient .PushState) {
270 if ps == nil { 228 if ps == nil {
271 return 229 return
272 } 230 }
273 log.Printf("QUEUED %q for upload", item.RelPath) 231 log.Printf("QUEUED %q for upload", item.RelPath)
274 uploader.UploadFile(item, ps, func() { 232 uploader.UploadFile(item, ps, func() {
275 log.Printf("UPLOADED %q", item.RelPath) 233 log.Printf("UPLOADED %q", item.RelPath)
276 }) 234 })
277 }) 235 })
278 } 236 }
237 return files, nil
238 }
239
240 // main contains the core logic for experimental archive.
241 func (c *expArchiveRun) main() error {
242 // TODO(djd): This func is long and has a lot of internal complexity (li ke,
243 // such as, archiveCallback). Refactor.
244
245 start := time.Now()
246 archiveOpts := &c.isolateFlags.ArchiveOptions
247 // Parse the incoming isolate file.
248 deps, rootDir, isol, err := isolate.ProcessIsolate(archiveOpts)
249 if err != nil {
250 return fmt.Errorf("failed to process isolate: %v", err)
251 }
252 log.Printf("Isolate referenced %d deps", len(deps))
253
254 // Set up a background context which is cancelled when this function ret urns.
255 ctx, cancel := context.WithCancel(context.Background())
256 defer cancel()
257
258 // Create the isolated client which connects to the isolate server.
259 authCl, err := c.createAuthClient()
260 if err != nil {
261 return err
262 }
263 client := isolatedclient.New(nil, authCl, c.isolatedFlags.ServerURL, c.i solatedFlags.Namespace, nil, nil)
264
265 // Set up a checker and uploader. We limit the uploader to one concurren t
266 // upload, since the uploads are all coming from disk (with the exceptio n of
267 // the isolated JSON itself) and we only want a single goroutine reading from
268 // disk at once.
269 checker := NewChecker(ctx, client)
270 uploader := NewUploader(ctx, client, 1)
271
272 parts, err := partitionDeps(deps, rootDir, c.isolateFlags.ArchiveOptions .Blacklist)
273 if err != nil {
274 return fmt.Errorf("partitioning deps: %v", err)
275 }
276
277 numFiles := len(parts.filesToArchive.items) + len(parts.indivFiles.items )
278 filesSize := uint64(parts.filesToArchive.totalSize + parts.indivFiles.to talSize)
279 log.Printf("Isolate expanded to %d files (total size %s) and %d symlinks ", numFiles, humanize.Bytes(filesSize), len(parts.links.items))
280 log.Printf("\t%d files (%s) to be isolated individually", len(parts.indi vFiles.items), humanize.Bytes(uint64(parts.indivFiles.totalSize)))
281 log.Printf("\t%d files (%s) to be isolated in archives", len(parts.files ToArchive.items), humanize.Bytes(uint64(parts.filesToArchive.totalSize)))
282
283 files, err := uploadDeps(parts, checker, uploader)
284 if err != nil {
285 return err
286 }
279 287
280 // Marshal the isolated file into JSON, and create an Item to describe i t. 288 // Marshal the isolated file into JSON, and create an Item to describe i t.
281 isol.Files = files 289 isol.Files = files
282 var isolJSON []byte 290 var isolJSON []byte
283 isolJSON, err = json.Marshal(isol) 291 isolJSON, err = json.Marshal(isol)
284 if err != nil { 292 if err != nil {
285 return err 293 return err
286 } 294 }
287 isolItem := &Item{ 295 isolItem := &Item{
288 Path: archiveOpts.Isolated, 296 Path: archiveOpts.Isolated,
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 } 394 }
387 395
388 func hashFile(path string) (isolated.HexDigest, error) { 396 func hashFile(path string) (isolated.HexDigest, error) {
389 f, err := os.Open(path) 397 f, err := os.Open(path)
390 if err != nil { 398 if err != nil {
391 return "", err 399 return "", err
392 } 400 }
393 defer f.Close() 401 defer f.Close()
394 return isolated.Hash(f) 402 return isolated.Hash(f)
395 } 403 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698