Skip to content

Commit 1df5673

Browse files
heschigopherbot
authored andcommitted
internal/relui: improve reproducibility of signed tarballs, take 2
Trying to predict the format of the distpack archives was probably not a good idea. Use the same approach we use for the module zips: tweak the contents of the files, and leave the metadata untouched. For golang/go#61513 Change-Id: I6e498b573eade71ec907590af05e7d3c0f25eb57 Reviewed-on: https://go-review.googlesource.com/c/build/+/512437 Auto-Submit: Heschi Kreinick <[email protected]> Run-TryBot: Heschi Kreinick <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
1 parent 53f51af commit 1df5673

File tree

2 files changed

+92
-19
lines changed

2 files changed

+92
-19
lines changed

internal/relui/buildrelease_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,14 @@ func testRelease(t *testing.T, prevTag string, major int, wantVersion string, ki
368368
"go/VERSION": versionFile,
369369
"go/tool/something_orother/compile": "",
370370
})
371+
checkTGZ(t, dlURL, files, "darwin-amd64.tar.gz", task.WebsiteFile{
372+
OS: "darwin",
373+
Arch: "amd64",
374+
Kind: "archive",
375+
}, map[string]string{
376+
"go/VERSION": versionFile,
377+
"go/bin/go": "-signed <macOS>",
378+
})
371379
checkContents(t, dlURL, files, "darwin-amd64.pkg", task.WebsiteFile{
372380
OS: "darwin",
373381
Arch: "amd64",

internal/relui/workflows.go

Lines changed: 84 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ func (tasks *BuildReleaseTasks) addBuildTasks(wd *wf.Definition, major int, vers
504504
blockers = append(blockers, match)
505505
if target.GOOS == "windows" {
506506
zip = wf.Task1(wd, "Get binary from distpack", tasks.binaryArchiveFromDistpack, distpack)
507-
tar = wf.Task1(wd, "Convert to .tgz", tasks.convertZipToTGZ, zip)
507+
tar = wf.Task1(wd, "Convert zip to .tgz", tasks.convertZipToTGZ, zip)
508508
} else {
509509
tar = wf.Task1(wd, "Get binary from distpack", tasks.binaryArchiveFromDistpack, distpack)
510510
}
@@ -524,9 +524,10 @@ func (tasks *BuildReleaseTasks) addBuildTasks(wd *wf.Definition, major int, vers
524524
case "darwin":
525525
pkg := wf.Task2(wd, "Build PKG installer", tasks.buildDarwinPKG, version, tar)
526526
signedPKG := wf.Task2(wd, "Sign PKG installer", tasks.signArtifact, pkg, wf.Const(sign.BuildMacOS))
527-
signedTGZ := wf.Task1(wd, "Convert to .tgz", tasks.convertPKGToTGZ, signedPKG)
527+
signedTGZ := wf.Task1(wd, "Convert PKG to .tgz", tasks.convertPKGToTGZ, signedPKG)
528+
mergedTGZ := wf.Task2(wd, "Merge signed files into .tgz", tasks.mergeSignedToTGZ, tar, signedTGZ)
528529
mod = wf.Task4(wd, "Merge signed files into module zip", tasks.mergeSignedToModule, version, timestamp, mod, signedTGZ)
529-
artifacts = append(artifacts, signedPKG, signedTGZ)
530+
artifacts = append(artifacts, signedPKG, mergedTGZ)
530531
case "windows":
531532
msi := wf.Task1(wd, "Build MSI installer", tasks.buildWindowsMSI, tar)
532533
signedMSI := wf.Task2(wd, "Sign MSI installer", tasks.signArtifact, msi, wf.Const(sign.BuildWindows))
@@ -788,37 +789,68 @@ func (b *BuildReleaseTasks) modFilesFromBinary(ctx *wf.TaskContext, version stri
788789
return result, nil
789790
}
790791

791-
func (b *BuildReleaseTasks) mergeSignedToModule(ctx *wf.TaskContext, version string, timestamp time.Time, mod moduleArtifact, signed artifact) (moduleArtifact, error) {
792-
a, err := b.runBuildStep(ctx, nil, nil, signed, "signedmod.zip", func(_ *task.BuildletStep, signed io.Reader, w io.Writer) error {
793-
// Load binaries from the signed tar file.
794-
szr, err := gzip.NewReader(signed)
792+
func (b *BuildReleaseTasks) mergeSignedToTGZ(ctx *wf.TaskContext, unsigned, signed artifact) (artifact, error) {
793+
return b.runBuildStep(ctx, unsigned.Target, nil, signed, "tar.gz", func(_ *task.BuildletStep, signed io.Reader, w io.Writer) error {
794+
signedBinaries, err := loadBinaries(ctx, signed)
795+
796+
// Copy files from the tgz, overwriting with binaries from the signed tar.
797+
scratchFS, err := gcsfs.FromURL(ctx, b.GCSClient, b.ScratchURL)
798+
if err != nil {
799+
return err
800+
}
801+
ur, err := scratchFS.Open(unsigned.ScratchPath)
795802
if err != nil {
796803
return err
797804
}
798-
defer szr.Close()
799-
str := tar.NewReader(szr)
805+
defer ur.Close()
806+
uzr, err := gzip.NewReader(ur)
807+
if err != nil {
808+
return err
809+
}
810+
defer uzr.Close()
811+
812+
utr := tar.NewReader(uzr)
813+
814+
zw, err := gzip.NewWriterLevel(w, gzip.BestCompression)
815+
if err != nil {
816+
return err
817+
}
818+
tw := tar.NewWriter(zw)
800819

801-
binaries := map[string][]byte{}
802820
for {
803-
th, err := str.Next()
821+
th, err := utr.Next()
804822
if err == io.EOF {
805823
break
806824
} else if err != nil {
807825
return err
808826
}
809-
if !strings.HasPrefix(th.Name, "go/bin/") && !strings.HasPrefix(th.Name, "go/pkg/tool/") {
810-
continue
827+
828+
hdr := *th
829+
src := io.NopCloser(utr)
830+
if signed, ok := signedBinaries[th.Name]; ok {
831+
src = io.NopCloser(bytes.NewReader(signed))
832+
hdr.Size = int64(len(signed))
811833
}
812-
if th.Typeflag != tar.TypeReg || th.Mode&0100 == 0 {
813-
continue
834+
835+
if err := tw.WriteHeader(&hdr); err != nil {
836+
return err
814837
}
815-
contents, err := io.ReadAll(str)
816-
if err != nil {
838+
if _, err := io.Copy(tw, src); err != nil {
817839
return err
818840
}
819-
binaries[th.Name] = contents
820841
}
821842

843+
if err := tw.Close(); err != nil {
844+
return err
845+
}
846+
return zw.Close()
847+
})
848+
}
849+
850+
func (b *BuildReleaseTasks) mergeSignedToModule(ctx *wf.TaskContext, version string, timestamp time.Time, mod moduleArtifact, signed artifact) (moduleArtifact, error) {
851+
a, err := b.runBuildStep(ctx, nil, nil, signed, "signedmod.zip", func(_ *task.BuildletStep, signed io.Reader, w io.Writer) error {
852+
signedBinaries, err := loadBinaries(ctx, signed)
853+
822854
// Copy files from the module zip, overwriting with binaries from the signed tar.
823855
scratchFS, err := gcsfs.FromURL(ctx, b.GCSClient, b.ScratchURL)
824856
if err != nil {
@@ -849,7 +881,7 @@ func (b *BuildReleaseTasks) mergeSignedToModule(ctx *wf.TaskContext, version str
849881
if !ok {
850882
continue
851883
}
852-
if contents, ok := binaries["go/"+suffix]; ok {
884+
if contents, ok := signedBinaries["go/"+suffix]; ok {
853885
in = io.NopCloser(bytes.NewReader(contents))
854886
} else {
855887
in, err = f.Open()
@@ -876,6 +908,39 @@ func (b *BuildReleaseTasks) mergeSignedToModule(ctx *wf.TaskContext, version str
876908
return mod, nil
877909
}
878910

911+
// loadBinaries reads binaries that we expect to have been signed by the
912+
// macOS signing process from tgz.
913+
func loadBinaries(ctx *wf.TaskContext, tgz io.Reader) (map[string][]byte, error) {
914+
zr, err := gzip.NewReader(tgz)
915+
if err != nil {
916+
return nil, err
917+
}
918+
defer zr.Close()
919+
tr := tar.NewReader(zr)
920+
921+
binaries := map[string][]byte{}
922+
for {
923+
th, err := tr.Next()
924+
if err == io.EOF {
925+
break
926+
} else if err != nil {
927+
return nil, err
928+
}
929+
if !strings.HasPrefix(th.Name, "go/bin/") && !strings.HasPrefix(th.Name, "go/pkg/tool/") {
930+
continue
931+
}
932+
if th.Typeflag != tar.TypeReg || th.Mode&0100 == 0 {
933+
continue
934+
}
935+
contents, err := io.ReadAll(tr)
936+
if err != nil {
937+
return nil, err
938+
}
939+
binaries[th.Name] = contents
940+
}
941+
return binaries, nil
942+
}
943+
879944
func (b *BuildReleaseTasks) buildBinary(ctx *wf.TaskContext, target *releasetargets.Target, source artifact) (artifact, error) {
880945
bc := dashboard.Builders[target.Builder]
881946
return b.runBuildStep(ctx, target, bc, source, "tar.gz", func(bs *task.BuildletStep, r io.Reader, w io.Writer) error {

0 commit comments

Comments
 (0)