@@ -560,7 +560,7 @@ func handleLogs(w http.ResponseWriter, r *http.Request) {
560
560
return
561
561
}
562
562
563
- if ! st .hasEvent ("make_and_test" ) {
563
+ if ! st .hasEvent ("make_and_test" ) && ! st . hasEvent ( "make_cross_compile_kube" ) {
564
564
fmt .Fprintf (w , "\n \n (buildlet still starting; no live streaming. reload manually to see status)\n " )
565
565
return
566
566
}
@@ -633,7 +633,7 @@ func findWorkLoop(work chan<- builderRev) {
633
633
//work <- builderRev{name: "linux-arm", rev: "c9778ec302b2e0e0d6027e1e0fca892e428d9657", subName: "tools", subRev: "ac303766f5f240c1796eeea3dc9bf34f1261aa35"}
634
634
const debugArm = false
635
635
if debugArm {
636
- for ! reversePool .CanBuild ("buildlet -linux-arm" ) {
636
+ for ! reversePool .CanBuild ("host -linux-arm" ) {
637
637
log .Printf ("waiting for ARM to register." )
638
638
time .Sleep (time .Second )
639
639
}
@@ -1392,10 +1392,43 @@ func (st *buildStatus) useSnapshot() bool {
1392
1392
return b
1393
1393
}
1394
1394
1395
+ func (st * buildStatus ) forceSnapshotUsage () {
1396
+ st .mu .Lock ()
1397
+ defer st .mu .Unlock ()
1398
+ truth := true
1399
+ st .useSnapshotMemo = & truth
1400
+ }
1401
+
1402
+ func (st * buildStatus ) shouldCrossCompileMake () bool {
1403
+ if inStaging {
1404
+ return st .name == "linux-arm" && kubeErr == nil
1405
+ }
1406
+ return st .isTry () && st .name == "linux-arm" && kubeErr == nil
1407
+ }
1408
+
1395
1409
func (st * buildStatus ) build () error {
1396
1410
st .buildRecord ().put ()
1411
+
1412
+ sp := st .createSpan ("checking_for_snapshot" )
1413
+ if inStaging {
1414
+ err := storageClient .Bucket (buildEnv .SnapBucket ).Object (st .snapshotObjectName ()).Delete (context .Background ())
1415
+ st .logEventTime ("deleted_snapshot" , fmt .Sprint (err ))
1416
+ }
1417
+ snapshotExists := st .useSnapshot ()
1418
+ if inStaging {
1419
+ st .logEventTime ("use_snapshot" , fmt .Sprint (snapshotExists ))
1420
+ }
1421
+ sp .done (nil )
1422
+
1423
+ if ! snapshotExists && st .shouldCrossCompileMake () {
1424
+ if err := st .crossCompileMakeAndSnapshot (); err != nil {
1425
+ return err
1426
+ }
1427
+ st .forceSnapshotUsage ()
1428
+ }
1429
+
1430
+ sp = st .createSpan ("get_buildlet" )
1397
1431
pool := st .buildletPool ()
1398
- sp := st .createSpan ("get_buildlet" )
1399
1432
bc , err := pool .GetBuildlet (st .ctx , st .conf .HostType , st )
1400
1433
sp .done (err )
1401
1434
if err != nil {
@@ -1542,7 +1575,7 @@ func (st *buildStatus) runAllSharded() (remoteErr, err error) {
1542
1575
return nil , nil
1543
1576
}
1544
1577
1545
- if err := st .doSnapshot (); err != nil {
1578
+ if err := st .doSnapshot (st . bc ); err != nil {
1546
1579
return nil , err
1547
1580
}
1548
1581
@@ -1560,6 +1593,68 @@ func (st *buildStatus) runAllSharded() (remoteErr, err error) {
1560
1593
return nil , nil
1561
1594
}
1562
1595
1596
+ func (st * buildStatus ) crossCompileMakeAndSnapshot () (err error ) {
1597
+ // TODO: currently we ditch this buildlet when we're done with
1598
+ // the make.bash & snapshot. For extra speed later, we could
1599
+ // keep it around and use it to "go test -c" each stdlib
1600
+ // package's tests, and push the binary to each ARM helper
1601
+ // machine. That might be too little gain for the complexity,
1602
+ // though, or slower once we ship everything around.
1603
+ ctx , cancel := context .WithCancel (st .ctx )
1604
+ defer cancel ()
1605
+ sp := st .createSpan ("get_buildlet_cross" )
1606
+ kubeBC , err := kubePool .GetBuildlet (ctx , "host-linux-armhf-cross" , st )
1607
+ sp .done (err )
1608
+ if err != nil {
1609
+ return err
1610
+ }
1611
+ defer kubeBC .Close ()
1612
+
1613
+ if err := st .writeGoSourceTo (kubeBC ); err != nil {
1614
+ return err
1615
+ }
1616
+
1617
+ makeSpan := st .createSpan ("make_cross_compile_kube" )
1618
+ defer func () { makeSpan .done (err ) }()
1619
+
1620
+ goos , goarch := st .conf .GOOS (), st .conf .GOARCH ()
1621
+
1622
+ remoteErr , err := kubeBC .Exec ("/bin/bash" , buildlet.ExecOpts {
1623
+ SystemLevel : true ,
1624
+ Args : []string {
1625
+ "-c" ,
1626
+ "cd $WORKDIR/go/src && " +
1627
+ "./make.bash && " +
1628
+ "cd .. && " +
1629
+ "mv bin/*_*/* bin && " +
1630
+ "rmdir bin/*_* && " +
1631
+ "rm -rf pkg/linux_amd64 pkg/tool/linux_amd64 pkg/bootstrap pkg/obj" ,
1632
+ },
1633
+ Output : st ,
1634
+ ExtraEnv : []string {
1635
+ "GOROOT_BOOTSTRAP=/go1.4" ,
1636
+ "CGO_ENABLED=1" ,
1637
+ "CC_FOR_TARGET=arm-linux-gnueabihf-gcc" ,
1638
+ "GOOS=" + goos ,
1639
+ "GOARCH=" + goarch ,
1640
+ "GOARM=7" , // harmless if GOARCH != "arm"
1641
+ },
1642
+ Debug : true ,
1643
+ })
1644
+ if err != nil {
1645
+ return err
1646
+ }
1647
+ if remoteErr != nil {
1648
+ return fmt .Errorf ("remote error: %v" , remoteErr )
1649
+ }
1650
+
1651
+ if err := st .doSnapshot (kubeBC ); err != nil {
1652
+ return err
1653
+ }
1654
+
1655
+ return nil
1656
+ }
1657
+
1563
1658
// runMake builds the tool chain.
1564
1659
// remoteErr and err are as described at the top of this file.
1565
1660
func (st * buildStatus ) runMake () (remoteErr , err error ) {
@@ -1635,16 +1730,16 @@ func (st *buildStatus) runAllLegacy() (remoteErr, err error) {
1635
1730
return nil , nil
1636
1731
}
1637
1732
1638
- func (st * buildStatus ) doSnapshot () error {
1733
+ func (st * buildStatus ) doSnapshot (bc * buildlet. Client ) error {
1639
1734
// If we're using a pre-built snapshot, don't make another.
1640
1735
if st .useSnapshot () {
1641
1736
return nil
1642
1737
}
1643
1738
1644
- if err := st .cleanForSnapshot (); err != nil {
1739
+ if err := st .cleanForSnapshot (bc ); err != nil {
1645
1740
return fmt .Errorf ("cleanForSnapshot: %v" , err )
1646
1741
}
1647
- if err := st .writeSnapshot (); err != nil {
1742
+ if err := st .writeSnapshot (bc ); err != nil {
1648
1743
return fmt .Errorf ("writeSnapshot: %v" , err )
1649
1744
}
1650
1745
return nil
@@ -1655,7 +1750,7 @@ var timeSnapshotCorruptionFixed = time.Date(2015, time.November, 1, 0, 0, 0, 0,
1655
1750
// TODO(adg): prune this map over time (might never be necessary, though)
1656
1751
var snapshotExistsCache = struct {
1657
1752
sync.Mutex
1658
- m map [builderRev ]bool
1753
+ m map [builderRev ]bool // set; only true values
1659
1754
}{m : map [builderRev ]bool {}}
1660
1755
1661
1756
// snapshotExists reports whether the snapshot exists and isn't corrupt.
@@ -1729,18 +1824,22 @@ func (br *builderRev) snapshotExists() (ok bool) {
1729
1824
}
1730
1825
1731
1826
func (st * buildStatus ) writeGoSource () error {
1827
+ return st .writeGoSourceTo (st .bc )
1828
+ }
1829
+
1830
+ func (st * buildStatus ) writeGoSourceTo (bc * buildlet.Client ) error {
1732
1831
// Write the VERSION file.
1733
1832
sp := st .createSpan ("write_version_tar" )
1734
- if err := st . bc .PutTar (versionTgz (st .rev ), "go" ); err != nil {
1833
+ if err := bc .PutTar (versionTgz (st .rev ), "go" ); err != nil {
1735
1834
return sp .done (fmt .Errorf ("writing VERSION tgz: %v" , err ))
1736
1835
}
1737
1836
1738
- srcTar , err := getSourceTgz (st , "go" , st .rev , st .trySet != nil )
1837
+ srcTar , err := getSourceTgz (st , "go" , st .rev , st .isTry () )
1739
1838
if err != nil {
1740
1839
return err
1741
1840
}
1742
1841
sp = st .createSpan ("write_go_src_tar" )
1743
- if err := st . bc .PutTar (srcTar , "go" ); err != nil {
1842
+ if err := bc .PutTar (srcTar , "go" ); err != nil {
1744
1843
return sp .done (fmt .Errorf ("writing tarball from Gerrit: %v" , err ))
1745
1844
}
1746
1845
return sp .done (nil )
@@ -1756,14 +1855,12 @@ func (st *buildStatus) writeBootstrapToolchain() error {
1756
1855
return sp .done (st .bc .PutTarFromURL (u , bootstrapDir ))
1757
1856
}
1758
1857
1759
- var cleanForSnapshotFiles = []string {
1760
- "go/doc/gopher" ,
1761
- "go/pkg/bootstrap" ,
1762
- }
1763
-
1764
- func (st * buildStatus ) cleanForSnapshot () error {
1858
+ func (st * buildStatus ) cleanForSnapshot (bc * buildlet.Client ) error {
1765
1859
sp := st .createSpan ("clean_for_snapshot" )
1766
- return sp .done (st .bc .RemoveAll (cleanForSnapshotFiles ... ))
1860
+ return sp .done (bc .RemoveAll (
1861
+ "go/doc/gopher" ,
1862
+ "go/pkg/bootstrap" ,
1863
+ ))
1767
1864
}
1768
1865
1769
1866
// snapshotObjectName is the cloud storage object name of the
@@ -1778,12 +1875,12 @@ func (br *builderRev) snapshotURL() string {
1778
1875
return buildEnv .SnapshotURL (br .name , br .rev )
1779
1876
}
1780
1877
1781
- func (st * buildStatus ) writeSnapshot () (err error ) {
1878
+ func (st * buildStatus ) writeSnapshot (bc * buildlet. Client ) (err error ) {
1782
1879
sp := st .createSpan ("write_snapshot_to_gcs" )
1783
1880
defer func () { sp .done (err ) }()
1784
1881
1785
1882
tsp := st .createSpan ("fetch_snapshot_reader_from_buildlet" )
1786
- tgz , err := st . bc .GetTar ("go" )
1883
+ tgz , err := bc .GetTar ("go" )
1787
1884
tsp .done (err )
1788
1885
if err != nil {
1789
1886
return err
@@ -1847,6 +1944,11 @@ func (st *buildStatus) distTestList() (names []string, remoteErr, err error) {
1847
1944
// only do this for slow builders running redundant tests. (That is,
1848
1945
// tests which have identical behavior across different ports)
1849
1946
func (st * buildStatus ) shouldSkipTest (testName string ) bool {
1947
+ if inStaging && st .name == "linux-arm" && false {
1948
+ if strings .HasPrefix (testName , "go_test:" ) && testName < "go_test:runtime" {
1949
+ return true
1950
+ }
1951
+ }
1850
1952
switch testName {
1851
1953
case "api" :
1852
1954
return st .isTry () && st .name != "linux-amd64"
@@ -2714,6 +2816,7 @@ type span struct {
2714
2816
event string // event name like "get_foo" or "write_bar"
2715
2817
optText string // optional details for event
2716
2818
start time.Time
2819
+ end time.Time
2717
2820
el eventTimeLogger // where we log to at the end; TODO: this will change
2718
2821
}
2719
2822
@@ -2735,8 +2838,16 @@ func createSpan(el eventTimeLogger, event string, optText ...string) *span {
2735
2838
}
2736
2839
}
2737
2840
2841
+ // done ends a span.
2842
+ // It is legal to call done multiple times. Only the first call
2843
+ // logs.
2844
+ // done always returns its input argument.
2738
2845
func (s * span ) done (err error ) error {
2846
+ if ! s .end .IsZero () {
2847
+ return err
2848
+ }
2739
2849
t1 := time .Now ()
2850
+ s .end = t1
2740
2851
td := t1 .Sub (s .start )
2741
2852
var text bytes.Buffer
2742
2853
fmt .Fprintf (& text , "after %v" , td )
@@ -2923,6 +3034,10 @@ var sourceGroup singleflight.Group
2923
3034
var sourceCache = lru .New (40 ) // git rev -> []byte
2924
3035
2925
3036
func useWatcher () bool {
3037
+ if inStaging {
3038
+ // Adjust as needed, depending on what you're testing.
3039
+ return false
3040
+ }
2926
3041
return * mode != "dev"
2927
3042
}
2928
3043
0 commit comments