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

Side by Side Diff: fiddle/go/builder/builder.go

Issue 1933943002: fiddle: fix build (Closed) Base URL: https://skia.googlesource.com/buildbot@master
Patch Set: remove all the reversing Created 4 years, 7 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 | fiddle/go/builder/builder_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 package builder 1 package builder
2 2
3 import ( 3 import (
4 "errors" 4 "errors"
5 "fmt" 5 "fmt"
6 "io/ioutil" 6 "io/ioutil"
7 "os" 7 "os"
8 "path" 8 "path"
9 "path/filepath" 9 "path/filepath"
10 "regexp" 10 "regexp"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 // 71 //
72 // fiddleRoot - The root directory where fiddle stores its files. See DESIGN. md. 72 // fiddleRoot - The root directory where fiddle stores its files. See DESIGN. md.
73 // depotTools - The directory where depot_tools is checked out. 73 // depotTools - The directory where depot_tools is checked out.
74 // repo - A vcs to pull hash info from. 74 // repo - A vcs to pull hash info from.
75 func New(fiddleRoot, depotTools string, repo vcsinfo.VCS) *Builder { 75 func New(fiddleRoot, depotTools string, repo vcsinfo.VCS) *Builder {
76 b := &Builder{ 76 b := &Builder{
77 fiddleRoot: fiddleRoot, 77 fiddleRoot: fiddleRoot,
78 depotTools: depotTools, 78 depotTools: depotTools,
79 repo: repo, 79 repo: repo,
80 } 80 }
81 _, _ = b.AvailableBuilds() // Called for side-effect of loading hashes.
81 go b.startDecimation() 82 go b.startDecimation()
82 b.updateCurrent() 83 b.updateCurrent()
83 84
84 return b 85 return b
85 } 86 }
86 87
87 // branch is used to sort the chrome branches in the Skia repo. 88 // branch is used to sort the chrome branches in the Skia repo.
88 type branch struct { 89 type branch struct {
89 N int 90 N int
90 Name string 91 Name string
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 } else { 153 } else {
153 if githash, err = buildskia.GetSkiaHash(nil); err != nil { 154 if githash, err = buildskia.GetSkiaHash(nil); err != nil {
154 return nil, fmt.Errorf("Failed to retrieve Skia LKGR: %s ", err) 155 return nil, fmt.Errorf("Failed to retrieve Skia LKGR: %s ", err)
155 } 156 }
156 } 157 }
157 checkout := path.Join(versions, githash) 158 checkout := path.Join(versions, githash)
158 159
159 fi, err := os.Stat(checkout) 160 fi, err := os.Stat(checkout)
160 // If the file is present and a directory then only proceed if 'force' i s true. 161 // If the file is present and a directory then only proceed if 'force' i s true.
161 if err == nil && fi.IsDir() == true && !force { 162 if err == nil && fi.IsDir() == true && !force {
163 glog.Infof("Dir already exists: %s", checkout)
162 return nil, AlreadyExistsErr 164 return nil, AlreadyExistsErr
163 } 165 }
164 166
165 ret, err := buildskia.DownloadSkia("", githash, checkout, b.depotTools, false, deps) 167 ret, err := buildskia.DownloadSkia("", githash, checkout, b.depotTools, false, deps)
166 if err != nil { 168 if err != nil {
167 return nil, fmt.Errorf("Failed to fetch: %s", err) 169 return nil, fmt.Errorf("Failed to fetch: %s", err)
168 } 170 }
169 171
170 if err := buildLib(checkout, b.depotTools); err != nil { 172 if err := buildLib(checkout, b.depotTools); err != nil {
171 return nil, err 173 return nil, err
(...skipping 10 matching lines...) Expand all
182 _, err = fmt.Fprintf(fb, "%s\n", githash) 184 _, err = fmt.Fprintf(fb, "%s\n", githash)
183 if err != nil { 185 if err != nil {
184 return nil, fmt.Errorf("Failed to write %s: %s", GOOD_BUILDS_FIL ENAME, err) 186 return nil, fmt.Errorf("Failed to write %s: %s", GOOD_BUILDS_FIL ENAME, err)
185 } 187 }
186 return ret, nil 188 return ret, nil
187 } 189 }
188 190
189 // updateCurrent updates the value of b.current with the new gitinfo for the mos t recent build. 191 // updateCurrent updates the value of b.current with the new gitinfo for the mos t recent build.
190 // 192 //
191 // Or a mildly informative stand-in if somehow the update fails. 193 // Or a mildly informative stand-in if somehow the update fails.
194 //
195 // updateCurrent presumes the caller already has a lock on the mutex.
192 func (b *Builder) updateCurrent() { 196 func (b *Builder) updateCurrent() {
193 allBuilds, err := b.AvailableBuilds()
194 b.mutex.Lock()
195 defer b.mutex.Unlock()
196 fallback := &vcsinfo.LongCommit{ShortCommit: &vcsinfo.ShortCommit{Hash: "unknown"}} 197 fallback := &vcsinfo.LongCommit{ShortCommit: &vcsinfo.ShortCommit{Hash: "unknown"}}
197 » if err != nil { 198 » if len(b.hashes) == 0 {
198 » » glog.Errorf("Failed to get list of available builds: %s", err) 199 » » glog.Errorf("There are no hashes.")
199 if b.current == nil { 200 if b.current == nil {
200 b.current = fallback 201 b.current = fallback
201 } 202 }
202 return 203 return
203 } 204 }
204 » details, err := b.repo.Details(allBuilds[0], true) 205 » details, err := b.repo.Details(b.hashes[len(b.hashes)-1], true)
205 if err != nil { 206 if err != nil {
206 glog.Errorf("Unable to retrieve build info: %s", err) 207 glog.Errorf("Unable to retrieve build info: %s", err)
207 if b.current == nil { 208 if b.current == nil {
208 b.current = fallback 209 b.current = fallback
209 } 210 }
210 return 211 return
211 } 212 }
212 b.current = details 213 b.current = details
213 } 214 }
214 215
215 // AvailableBuilds returns a list of git hashes, all the versions of Skia that 216 // AvailableBuilds returns a list of git hashes, all the versions of Skia that
216 // can be built against. This returns the list with the newest builds first. 217 // can be built against. This returns the list with the newest builds last.
217 // The list will always be of length > 1, otherwise and error is returned. 218 // The list will always be of length > 1, otherwise and error is returned.
218 func (b *Builder) AvailableBuilds() ([]string, error) { 219 func (b *Builder) AvailableBuilds() ([]string, error) {
219 b.mutex.Lock() 220 b.mutex.Lock()
220 defer b.mutex.Unlock() 221 defer b.mutex.Unlock()
221 if len(b.hashes) > 0 { 222 if len(b.hashes) > 0 {
222 return b.hashes, nil 223 return b.hashes, nil
223 } 224 }
224 fi, err := os.Open(filepath.Join(b.fiddleRoot, GOOD_BUILDS_FILENAME)) 225 fi, err := os.Open(filepath.Join(b.fiddleRoot, GOOD_BUILDS_FILENAME))
225 if err != nil { 226 if err != nil {
226 return nil, fmt.Errorf("Failed to open %s for reading: %s", GOOD _BUILDS_FILENAME, err) 227 return nil, fmt.Errorf("Failed to open %s for reading: %s", GOOD _BUILDS_FILENAME, err)
227 } 228 }
228 defer util.Close(fi) 229 defer util.Close(fi)
229 buf, err := ioutil.ReadAll(fi) 230 buf, err := ioutil.ReadAll(fi)
230 if err != nil { 231 if err != nil {
231 return nil, fmt.Errorf("Failed to read: %s", err) 232 return nil, fmt.Errorf("Failed to read: %s", err)
232 } 233 }
233 hashes := strings.Split(string(buf), "\n") 234 hashes := strings.Split(string(buf), "\n")
234 » revHashes := []string{} 235 » realHashes := []string{}
235 » for i := len(hashes) - 1; i >= 0; i-- { 236 » for _, h := range hashes {
236 » » h := hashes[i]
237 if h != "" { 237 if h != "" {
238 » » » revHashes = append(revHashes, h) 238 » » » realHashes = append(realHashes, h)
239 } 239 }
240 } 240 }
241 » b.hashes = revHashes 241 » b.hashes = realHashes
242 if len(b.hashes) == 0 { 242 if len(b.hashes) == 0 {
243 return nil, fmt.Errorf("List of available builds is empty.") 243 return nil, fmt.Errorf("List of available builds is empty.")
244 } 244 }
245 » return revHashes, nil 245 » return realHashes, nil
246 } 246 }
247 247
248 func (b *Builder) Current() *vcsinfo.LongCommit { 248 func (b *Builder) Current() *vcsinfo.LongCommit {
249 b.mutex.Lock() 249 b.mutex.Lock()
250 defer b.mutex.Unlock() 250 defer b.mutex.Unlock()
251 return b.current 251 return b.current
252 } 252 }
253 253
254 // BuildLatestSkiaChromeBranch builds the most recent branch of Skia for Chrome 254 // BuildLatestSkiaChromeBranch builds the most recent branch of Skia for Chrome
255 // in the given fiddleRoot directory. 255 // in the given fiddleRoot directory.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 return branchName, res, nil 314 return branchName, res, nil
315 } 315 }
316 316
317 func (b *Builder) writeNewGoodBuilds(hashes []string) error { 317 func (b *Builder) writeNewGoodBuilds(hashes []string) error {
318 if len(hashes) < 1 { 318 if len(hashes) < 1 {
319 return fmt.Errorf("At least one good build must be kept around." ) 319 return fmt.Errorf("At least one good build must be kept around." )
320 } 320 }
321 b.mutex.Lock() 321 b.mutex.Lock()
322 defer b.mutex.Unlock() 322 defer b.mutex.Unlock()
323 323
324 revHashes := []string{}
325 for i := len(hashes) - 1; i >= 0; i-- {
326 h := hashes[i]
327 if h != "" {
328 revHashes = append(revHashes, h)
329 }
330 }
331 b.hashes = hashes 324 b.hashes = hashes
332 fb, err := os.Create(filepath.Join(b.fiddleRoot, GOOD_BUILDS_FILENAME)) 325 fb, err := os.Create(filepath.Join(b.fiddleRoot, GOOD_BUILDS_FILENAME))
333 if err != nil { 326 if err != nil {
334 return fmt.Errorf("Failed to open %s for writing: %s", GOOD_BUIL DS_FILENAME, err) 327 return fmt.Errorf("Failed to open %s for writing: %s", GOOD_BUIL DS_FILENAME, err)
335 } 328 }
336 defer util.Close(fb) 329 defer util.Close(fb)
337 » if _, err := fb.Write([]byte(strings.Join(revHashes, "\n") + "\n")); err != nil { 330 » if _, err := fb.Write([]byte(strings.Join(hashes, "\n") + "\n")); err != nil {
338 return fmt.Errorf("Failed to write %s: %s", GOOD_BUILDS_FILENAME , err) 331 return fmt.Errorf("Failed to write %s: %s", GOOD_BUILDS_FILENAME , err)
339 } 332 }
340 return nil 333 return nil
341 } 334 }
342 335
343 func (b *Builder) startDecimation() { 336 func (b *Builder) startDecimation() {
344 decimateLiveness := metrics2.NewLiveness("decimate") 337 decimateLiveness := metrics2.NewLiveness("decimate")
345 decimateFailures := metrics2.GetCounter("decimate-failed", nil) 338 decimateFailures := metrics2.GetCounter("decimate-failed", nil)
346 for _ = range time.Tick(DECIMATION_PERIOD) { 339 for _ = range time.Tick(DECIMATION_PERIOD) {
347 hashes, err := b.AvailableBuilds() 340 hashes, err := b.AvailableBuilds()
348 if err != nil { 341 if err != nil {
349 glog.Errorf("Failed to get available builds while decima ting: %s", err) 342 glog.Errorf("Failed to get available builds while decima ting: %s", err)
350 decimateFailures.Inc(1) 343 decimateFailures.Inc(1)
351 continue 344 continue
352 } 345 }
353 keep, remove, err := decimate(hashes, b.repo, PRESERVE_COUNT) 346 keep, remove, err := decimate(hashes, b.repo, PRESERVE_COUNT)
354 if err != nil { 347 if err != nil {
355 glog.Errorf("Failed to calc removals while decimating: % s", err) 348 glog.Errorf("Failed to calc removals while decimating: % s", err)
356 decimateFailures.Inc(1) 349 decimateFailures.Inc(1)
357 continue 350 continue
358 } 351 }
352 glog.Infof("Decimate: Keep %v Remove %v", keep, remove)
359 for _, hash := range remove { 353 for _, hash := range remove {
360 glog.Infof("Decimate: Beginning %s", hash) 354 glog.Infof("Decimate: Beginning %s", hash)
361 if err := os.RemoveAll(filepath.Join(b.fiddleRoot, "vers ions", hash)); err != nil { 355 if err := os.RemoveAll(filepath.Join(b.fiddleRoot, "vers ions", hash)); err != nil {
362 glog.Errorf("Failed to remove directory for %s: %s", hash, err) 356 glog.Errorf("Failed to remove directory for %s: %s", hash, err)
363 continue 357 continue
364 } 358 }
365 glog.Infof("Decimate: Finished %s", hash) 359 glog.Infof("Decimate: Finished %s", hash)
366 } 360 }
367 if err := b.writeNewGoodBuilds(keep); err != nil { 361 if err := b.writeNewGoodBuilds(keep); err != nil {
368 continue 362 continue
369 } 363 }
370 decimateFailures.Reset() 364 decimateFailures.Reset()
371 decimateLiveness.Reset() 365 decimateLiveness.Reset()
372 } 366 }
373 } 367 }
374 368
375 // decimate returns a list of hashes to keep, the list to remove, 369 // decimate returns a list of hashes to keep, the list to remove,
376 // and an error if one occurred. 370 // and an error if one occurred.
377 // 371 //
378 // The algorithm is: 372 // The algorithm is:
379 // Preserve all hashes that are spaced one month apart. 373 // Preserve all hashes that are spaced one month apart.
380 // Then if there are more than 'limit' remaining hashes 374 // Then if there are more than 'limit' remaining hashes
381 // remove every other one to bring the count down to 'limit'/2. 375 // remove every other one to bring the count down to 'limit'/2.
382 // 376 //
383 func decimate(hashes []string, vcs vcsinfo.VCS, limit int) ([]string, []string, error) { 377 func decimate(hashes []string, vcs vcsinfo.VCS, limit int) ([]string, []string, error) {
384 keep := []string{} 378 keep := []string{}
385 remove := []string{} 379 remove := []string{}
386 380
387 » // The hashes are in reverse chronological order, so we start at the end 381 » // The hashes are stored with the oldest first, newest last.
388 » // and work back until we start to find hashes that are less than 382 » // So we start at the front and work forward until we start to find hash es that are less than
389 » // PRESERVE_DURATION apart. Once we find that spot set oldiesBegin 383 » // PRESERVE_DURATION apart. Once we find that spot set oldiesEnd
390 // to that index. 384 // to that index.
391 » oldiesBegin := len(hashes) 385 » oldiesEnd := 0
392 » c, err := vcs.Details(hashes[len(hashes)-1], true) 386 » c, err := vcs.Details(hashes[0], true)
393 if err != nil { 387 if err != nil {
394 return nil, nil, fmt.Errorf("Failed to get hash details: %s", er r) 388 return nil, nil, fmt.Errorf("Failed to get hash details: %s", er r)
395 } 389 }
396 » lastTS := c.Timestamp 390 » lastTS := time.Time{}
397 » for i := len(hashes) - 2; i > 0; i-- { 391 » for i, h := range hashes {
398 » » c, err := vcs.Details(hashes[i], true) 392 » » c, err = vcs.Details(h, true)
399 if err != nil { 393 if err != nil {
400 return nil, nil, fmt.Errorf("Failed to get hash details: %s", err) 394 return nil, nil, fmt.Errorf("Failed to get hash details: %s", err)
401 } 395 }
396 fmt.Printf("%v", c.Timestamp.Sub(lastTS))
402 if c.Timestamp.Sub(lastTS) < PRESERVE_DURATION { 397 if c.Timestamp.Sub(lastTS) < PRESERVE_DURATION {
403 glog.Infof("Decimation: Time %v between %q and %q", c.Ti mestamp.Sub(lastTS), hashes[i], hashes[i+1])
404 break 398 break
405 } 399 }
406 lastTS = c.Timestamp 400 lastTS = c.Timestamp
407 » » oldiesBegin = i 401 » » oldiesEnd = i
408 } 402 }
409 403
410 // Now that we know where the old hashes that we want to preserve are, w e 404 // Now that we know where the old hashes that we want to preserve are, w e
411 // will chop them off and ignore them for the rest of the decimation pro cess. 405 // will chop them off and ignore them for the rest of the decimation pro cess.
412 » oldies := hashes[oldiesBegin:] 406 » oldies := hashes[:oldiesEnd]
413 » hashes = hashes[:oldiesBegin] 407 » hashes = hashes[oldiesEnd:]
408 » fmt.Println(oldies, hashes)
414 409
415 // Only do decimation if we have enough fresh hashes. 410 // Only do decimation if we have enough fresh hashes.
416 if len(hashes) < limit { 411 if len(hashes) < limit {
417 » » return append(hashes, oldies...), remove, nil 412 » » return append(oldies, hashes...), remove, nil
418 } 413 }
419 » for i, h := range hashes { 414 » last := hashes[len(hashes)-1]
415 » for i, h := range hashes[:len(hashes)-1] {
420 if i%2 == 0 { 416 if i%2 == 0 {
421 keep = append(keep, h) 417 keep = append(keep, h)
422 } else { 418 } else {
423 remove = append(remove, h) 419 remove = append(remove, h)
424 } 420 }
425 } 421 }
422 keep = append(keep, last)
426 // Once done with decimation add the oldies back into the list of hashes to keep. 423 // Once done with decimation add the oldies back into the list of hashes to keep.
427 » return append(keep, oldies...), remove, nil 424 » return append(oldies, keep...), remove, nil
428 } 425 }
OLDNEW
« no previous file with comments | « no previous file | fiddle/go/builder/builder_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698