Procházet zdrojové kódy

cmd/dist,release/dist: expose RPM signing hook (#8789)

Plumb a signing callback function to `unixpkgs.rpmTarget` to allow
signing RPMs. This callback is optional and RPMs will build unsigned if
not set, just as before.

Updates https://github.com/tailscale/tailscale/issues/1882

Signed-off-by: Andrew Lytvynov <[email protected]>
Andrew Lytvynov před 2 roky
rodič
revize
371e1ebf07

+ 2 - 3
cmd/dist/dist.go

@@ -6,7 +6,6 @@ package main
 
 import (
 	"context"
-	"crypto"
 	"errors"
 	"flag"
 	"log"
@@ -20,10 +19,10 @@ import (
 
 var synologyPackageCenter bool
 
-func getTargets(tgzSigner crypto.Signer) ([]dist.Target, error) {
+func getTargets(signers unixpkgs.Signers) ([]dist.Target, error) {
 	var ret []dist.Target
 
-	ret = append(ret, unixpkgs.Targets(tgzSigner)...)
+	ret = append(ret, unixpkgs.Targets(signers)...)
 	// Synology packages can be built either for sideloading, or for
 	// distribution by Synology in their package center. When
 	// distributed through the package center, apps can request

+ 4 - 3
release/dist/cli/cli.go

@@ -19,6 +19,7 @@ import (
 
 	"github.com/peterbourgon/ff/v3/ffcli"
 	"tailscale.com/release/dist"
+	"tailscale.com/release/dist/unixpkgs"
 )
 
 // CLI returns a CLI root command to build release packages.
@@ -26,7 +27,7 @@ import (
 // getTargets is a function that gets run in the Exec function of commands that
 // need to know the target list. Its execution is deferred in this way to allow
 // customization of command FlagSets with flags that influence the target list.
-func CLI(getTargets func(tgzSigner crypto.Signer) ([]dist.Target, error)) *ffcli.Command {
+func CLI(getTargets func(unixpkgs.Signers) ([]dist.Target, error)) *ffcli.Command {
 	return &ffcli.Command{
 		Name:       "dist",
 		ShortUsage: "dist [flags] <command> [command flags]",
@@ -36,7 +37,7 @@ func CLI(getTargets func(tgzSigner crypto.Signer) ([]dist.Target, error)) *ffcli
 			{
 				Name: "list",
 				Exec: func(ctx context.Context, args []string) error {
-					targets, err := getTargets(nil)
+					targets, err := getTargets(unixpkgs.Signers{})
 					if err != nil {
 						return err
 					}
@@ -56,7 +57,7 @@ func CLI(getTargets func(tgzSigner crypto.Signer) ([]dist.Target, error)) *ffcli
 					if err != nil {
 						return err
 					}
-					targets, err := getTargets(tgzSigner)
+					targets, err := getTargets(unixpkgs.Signers{Tarball: tgzSigner})
 					if err != nil {
 						return err
 					}

+ 24 - 18
release/dist/unixpkgs/pkgs.go

@@ -24,8 +24,8 @@ import (
 )
 
 type tgzTarget struct {
-	filenameArch string // arch to use in filename instead of deriving from goenv["GOARCH"]
-	goenv        map[string]string
+	filenameArch string // arch to use in filename instead of deriving from goEnv["GOARCH"]
+	goEnv        map[string]string
 	signer       crypto.Signer
 }
 
@@ -33,11 +33,11 @@ func (t *tgzTarget) arch() string {
 	if t.filenameArch != "" {
 		return t.filenameArch
 	}
-	return t.goenv["GOARCH"]
+	return t.goEnv["GOARCH"]
 }
 
 func (t *tgzTarget) os() string {
-	return t.goenv["GOOS"]
+	return t.goEnv["GOOS"]
 }
 
 func (t *tgzTarget) String() string {
@@ -46,18 +46,18 @@ func (t *tgzTarget) String() string {
 
 func (t *tgzTarget) Build(b *dist.Build) ([]string, error) {
 	var filename string
-	if t.goenv["GOOS"] == "linux" {
+	if t.goEnv["GOOS"] == "linux" {
 		// Linux used to be the only tgz architecture, so we didn't put the OS
 		// name in the filename.
 		filename = fmt.Sprintf("tailscale_%s_%s.tgz", b.Version.Short, t.arch())
 	} else {
 		filename = fmt.Sprintf("tailscale_%s_%s_%s.tgz", b.Version.Short, t.os(), t.arch())
 	}
-	ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goenv)
+	ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goEnv)
 	if err != nil {
 		return nil, err
 	}
-	tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goenv)
+	tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goEnv)
 	if err != nil {
 		return nil, err
 	}
@@ -173,19 +173,19 @@ func (t *tgzTarget) Build(b *dist.Build) ([]string, error) {
 }
 
 type debTarget struct {
-	goenv map[string]string
+	goEnv map[string]string
 }
 
 func (t *debTarget) os() string {
-	return t.goenv["GOOS"]
+	return t.goEnv["GOOS"]
 }
 
 func (t *debTarget) arch() string {
-	return t.goenv["GOARCH"]
+	return t.goEnv["GOARCH"]
 }
 
 func (t *debTarget) String() string {
-	return fmt.Sprintf("linux/%s/deb", t.goenv["GOARCH"])
+	return fmt.Sprintf("linux/%s/deb", t.goEnv["GOARCH"])
 }
 
 func (t *debTarget) Build(b *dist.Build) ([]string, error) {
@@ -193,11 +193,11 @@ func (t *debTarget) Build(b *dist.Build) ([]string, error) {
 		return nil, errors.New("deb only supported on linux")
 	}
 
-	ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goenv)
+	ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goEnv)
 	if err != nil {
 		return nil, err
 	}
-	tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goenv)
+	tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goEnv)
 	if err != nil {
 		return nil, err
 	}
@@ -284,15 +284,16 @@ func (t *debTarget) Build(b *dist.Build) ([]string, error) {
 }
 
 type rpmTarget struct {
-	goenv map[string]string
+	goEnv  map[string]string
+	signFn func(io.Reader) ([]byte, error)
 }
 
 func (t *rpmTarget) os() string {
-	return t.goenv["GOOS"]
+	return t.goEnv["GOOS"]
 }
 
 func (t *rpmTarget) arch() string {
-	return t.goenv["GOARCH"]
+	return t.goEnv["GOARCH"]
 }
 
 func (t *rpmTarget) String() string {
@@ -304,11 +305,11 @@ func (t *rpmTarget) Build(b *dist.Build) ([]string, error) {
 		return nil, errors.New("rpm only supported on linux")
 	}
 
-	ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goenv)
+	ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goEnv)
 	if err != nil {
 		return nil, err
 	}
-	tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goenv)
+	tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goEnv)
 	if err != nil {
 		return nil, err
 	}
@@ -375,6 +376,11 @@ func (t *rpmTarget) Build(b *dist.Build) ([]string, error) {
 			Conflicts: []string{"tailscale-relay"},
 			RPM: nfpm.RPM{
 				Group: "Network",
+				Signature: nfpm.RPMSignature{
+					PackageSignature: nfpm.PackageSignature{
+						SignFn: t.signFn,
+					},
+				},
 			},
 		},
 	})

+ 14 - 7
release/dist/unixpkgs/targets.go

@@ -6,6 +6,7 @@ package unixpkgs
 import (
 	"crypto"
 	"fmt"
+	"io"
 	"sort"
 	"strings"
 
@@ -15,22 +16,27 @@ import (
 	_ "github.com/goreleaser/nfpm/v2/rpm"
 )
 
-func Targets(signer crypto.Signer) []dist.Target {
+type Signers struct {
+	Tarball crypto.Signer
+	RPM     func(io.Reader) ([]byte, error)
+}
+
+func Targets(signers Signers) []dist.Target {
 	var ret []dist.Target
 	for goosgoarch := range tarballs {
 		goos, goarch := splitGoosGoarch(goosgoarch)
 		ret = append(ret, &tgzTarget{
-			goenv: map[string]string{
+			goEnv: map[string]string{
 				"GOOS":   goos,
 				"GOARCH": goarch,
 			},
-			signer: signer,
+			signer: signers.Tarball,
 		})
 	}
 	for goosgoarch := range debs {
 		goos, goarch := splitGoosGoarch(goosgoarch)
 		ret = append(ret, &debTarget{
-			goenv: map[string]string{
+			goEnv: map[string]string{
 				"GOOS":   goos,
 				"GOARCH": goarch,
 			},
@@ -39,10 +45,11 @@ func Targets(signer crypto.Signer) []dist.Target {
 	for goosgoarch := range rpms {
 		goos, goarch := splitGoosGoarch(goosgoarch)
 		ret = append(ret, &rpmTarget{
-			goenv: map[string]string{
+			goEnv: map[string]string{
 				"GOOS":   goos,
 				"GOARCH": goarch,
 			},
+			signFn: signers.RPM,
 		})
 	}
 
@@ -50,12 +57,12 @@ func Targets(signer crypto.Signer) []dist.Target {
 	// an ancient architecture.
 	ret = append(ret, &tgzTarget{
 		filenameArch: "geode",
-		goenv: map[string]string{
+		goEnv: map[string]string{
 			"GOOS":   "linux",
 			"GOARCH": "386",
 			"GO386":  "softfloat",
 		},
-		signer: signer,
+		signer: signers.Tarball,
 	})
 
 	sort.Slice(ret, func(i, j int) bool {