mirror of
https://github.com/grafana/grafana.git
synced 2025-01-28 17:24:59 -06:00
Remove code to publish to RPM and deb repos (#61786)
This was replaced here: https://github.com/grafana/grafana/pull/53553 and it's no longer used
This commit is contained in:
parent
61c2c12489
commit
a190e03133
@ -1,246 +0,0 @@
|
||||
package packaging
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/grafana/grafana/pkg/build/config"
|
||||
"github.com/grafana/grafana/pkg/build/fsutil"
|
||||
"github.com/grafana/grafana/pkg/infra/fs"
|
||||
)
|
||||
|
||||
func writeAptlyConf(dbDir, repoDir string) error {
|
||||
aptlyConf := fmt.Sprintf(`{
|
||||
"rootDir": "%s",
|
||||
"downloadConcurrency": 4,
|
||||
"downloadSpeedLimit": 0,
|
||||
"architectures": [],
|
||||
"dependencyFollowSuggests": false,
|
||||
"dependencyFollowRecommends": false,
|
||||
"dependencyFollowAllVariants": false,
|
||||
"dependencyFollowSource": false,
|
||||
"dependencyVerboseResolve": false,
|
||||
"gpgDisableSign": false,
|
||||
"gpgDisableVerify": false,
|
||||
"gpgProvider": "gpg2",
|
||||
"downloadSourcePackages": false,
|
||||
"skipLegacyPool": true,
|
||||
"ppaDistributorID": "ubuntu",
|
||||
"ppaCodename": "",
|
||||
"skipContentsPublishing": false,
|
||||
"FileSystemPublishEndpoints": {
|
||||
"repo": {
|
||||
"rootDir": "%s",
|
||||
"linkMethod": "copy"
|
||||
}
|
||||
},
|
||||
"S3PublishEndpoints": {},
|
||||
"SwiftPublishEndpoints": {}
|
||||
}
|
||||
`, dbDir, repoDir)
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(filepath.Join(home, ".aptly.conf"), []byte(aptlyConf), 0600)
|
||||
}
|
||||
|
||||
// downloadDebs downloads Deb packages.
|
||||
func downloadDebs(cfg PublishConfig, workDir string) error {
|
||||
if cfg.Bucket == "" {
|
||||
panic("cfg.Bucket has to be set")
|
||||
}
|
||||
if !strings.HasSuffix(workDir, string(filepath.Separator)) {
|
||||
workDir += string(filepath.Separator)
|
||||
}
|
||||
|
||||
var version string
|
||||
if cfg.ReleaseMode.Mode == config.TagMode {
|
||||
if cfg.ReleaseMode.IsBeta {
|
||||
version = strings.ReplaceAll(cfg.Version, "-", "~")
|
||||
} else {
|
||||
version = cfg.Version
|
||||
}
|
||||
}
|
||||
if version == "" {
|
||||
panic(fmt.Sprintf("Unrecognized version mode %s", cfg.ReleaseMode.Mode))
|
||||
}
|
||||
|
||||
var sfx string
|
||||
switch cfg.Edition {
|
||||
case config.EditionOSS:
|
||||
case config.EditionEnterprise:
|
||||
sfx = EnterpriseSfx
|
||||
default:
|
||||
return fmt.Errorf("unrecognized edition %q", cfg.Edition)
|
||||
}
|
||||
|
||||
u := fmt.Sprintf("gs://%s/%s/%s/grafana%s_%s_*.deb*", cfg.Bucket,
|
||||
strings.ToLower(string(cfg.Edition)), ReleaseFolder, sfx, version)
|
||||
log.Printf("Downloading Deb packages %q...\n", u)
|
||||
args := []string{
|
||||
"-m",
|
||||
"cp",
|
||||
u,
|
||||
workDir,
|
||||
}
|
||||
//nolint:gosec
|
||||
cmd := exec.Command("gsutil", args...)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to download Deb packages %q: %w\n%s", u, err, output)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateDebRepo updates the Debian repository with the new release.
|
||||
func UpdateDebRepo(cfg PublishConfig, workDir string) error {
|
||||
if cfg.ReleaseMode.Mode != config.TagMode {
|
||||
panic(fmt.Sprintf("Unsupported version mode: %s", cfg.ReleaseMode.Mode))
|
||||
}
|
||||
|
||||
if cfg.ReleaseMode.IsTest {
|
||||
if cfg.Config.DebDBBucket == DefaultDebDBBucket {
|
||||
return fmt.Errorf("in test-release mode, the default Deb DB bucket shouldn't be used")
|
||||
}
|
||||
if cfg.Config.DebRepoBucket == DefaultDebRepoBucket {
|
||||
return fmt.Errorf("in test-release mode, the default Deb repo bucket shouldn't be used")
|
||||
}
|
||||
}
|
||||
|
||||
if err := downloadDebs(cfg, workDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repoName := "grafana"
|
||||
if cfg.ReleaseMode.IsBeta {
|
||||
repoName = "beta"
|
||||
}
|
||||
|
||||
repoRoot, err := fsutil.CreateTempDir("deb-repo")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := os.RemoveAll(repoRoot); err != nil {
|
||||
log.Printf("Failed to remove temporary directory %q: %s\n", repoRoot, err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
dbDir := filepath.Join(repoRoot, "db")
|
||||
repoDir := filepath.Join(repoRoot, "repo")
|
||||
tmpDir := filepath.Join(repoRoot, "tmp")
|
||||
for _, dpath := range []string{dbDir, repoDir, tmpDir} {
|
||||
if err := os.MkdirAll(dpath, 0750); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := writeAptlyConf(dbDir, repoDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Download the Debian repo database
|
||||
u := fmt.Sprintf("gs://%s/%s", cfg.DebDBBucket, strings.ToLower(string(cfg.Edition)))
|
||||
log.Printf("Downloading Debian repo database from %s...\n", u)
|
||||
//nolint:gosec
|
||||
cmd := exec.Command("gsutil", "-m", "rsync", "-r", "-d", u, dbDir)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to download Debian repo database: %w\n%s", err, output)
|
||||
}
|
||||
|
||||
if err := addPkgsToRepo(cfg, workDir, tmpDir, repoName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Println("Updating local Debian package repository...")
|
||||
// Update published local repository. This assumes that there exists already a local, published repo.
|
||||
for _, tp := range []string{"stable", "beta"} {
|
||||
passArg := fmt.Sprintf("-passphrase-file=%s", cfg.GPGPassPath)
|
||||
//nolint:gosec
|
||||
cmd := exec.Command("aptly", "publish", "update", "-batch", passArg, "-force-overwrite", tp,
|
||||
"filesystem:repo:grafana")
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return cli.Exit(fmt.Sprintf("failed to update Debian %q repository: %s", tp, output), 1)
|
||||
}
|
||||
}
|
||||
|
||||
// Update database in GCS
|
||||
u = fmt.Sprintf("gs://%s/%s", cfg.DebDBBucket, strings.ToLower(string(cfg.Edition)))
|
||||
if cfg.DryRun {
|
||||
log.Printf("Simulating upload of Debian repo database to GCS (%s)\n", u)
|
||||
} else {
|
||||
log.Printf("Uploading Debian repo database to GCS (%s)...\n", u)
|
||||
//nolint:gosec
|
||||
cmd = exec.Command("gsutil", "-m", "rsync", "-r", "-d", dbDir, u)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return cli.Exit(fmt.Sprintf("failed to upload Debian repo database to GCS: %s", output), 1)
|
||||
}
|
||||
}
|
||||
|
||||
// Update metadata and binaries in repository bucket
|
||||
u = fmt.Sprintf("gs://%s/%s/deb", cfg.DebRepoBucket, strings.ToLower(string(cfg.Edition)))
|
||||
grafDir := filepath.Join(repoDir, "grafana")
|
||||
if cfg.DryRun {
|
||||
log.Printf("Simulating upload of Debian repo resources to GCS (%s)\n", u)
|
||||
} else {
|
||||
log.Printf("Uploading Debian repo resources to GCS (%s)...\n", u)
|
||||
//nolint:gosec
|
||||
cmd = exec.Command("gsutil", "-m", "rsync", "-r", "-d", grafDir, u)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return cli.Exit(fmt.Sprintf("failed to upload Debian repo resources to GCS: %s", output), 1)
|
||||
}
|
||||
allRepoResources := fmt.Sprintf("%s/**/*", u)
|
||||
log.Printf("Setting cache ttl for Debian repo resources on GCS (%s)...\n", allRepoResources)
|
||||
//nolint:gosec
|
||||
cmd = exec.Command("gsutil", "-m", "setmeta", "-h", CacheSettings+cfg.TTL, allRepoResources)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return cli.Exit(fmt.Sprintf("failed to set cache ttl for Debian repo resources on GCS: %s", output), 1)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func addPkgsToRepo(cfg PublishConfig, workDir, tmpDir, repoName string) error {
|
||||
var sfx string
|
||||
switch cfg.Edition {
|
||||
case config.EditionOSS:
|
||||
case config.EditionEnterprise:
|
||||
sfx = EnterpriseSfx
|
||||
default:
|
||||
return fmt.Errorf("unsupported edition %q", cfg.Edition)
|
||||
}
|
||||
|
||||
log.Printf("Adding packages to Debian %q repo...\n", repoName)
|
||||
// TODO: Be more specific about filename pattern
|
||||
debs, err := filepath.Glob(filepath.Join(workDir, fmt.Sprintf("grafana%s*.deb", sfx)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, deb := range debs {
|
||||
basename := filepath.Base(deb)
|
||||
if strings.Contains(basename, "latest") {
|
||||
continue
|
||||
}
|
||||
|
||||
tgt := filepath.Join(tmpDir, basename)
|
||||
if err := fs.CopyFile(deb, tgt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// XXX: Adds too many packages in enterprise (Arve: What does this mean exactly?)
|
||||
//nolint:gosec
|
||||
cmd := exec.Command("aptly", "repo", "add", "-force-replace", repoName, tmpDir)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return cli.Exit(fmt.Sprintf("failed to add packages to local Debian repository: %s", output), 1)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -1,370 +0,0 @@
|
||||
package packaging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
// Consider switching this over to a community fork unless there is
|
||||
// an option to move us away from OpenPGP.
|
||||
"golang.org/x/crypto/openpgp" //nolint:staticcheck
|
||||
"golang.org/x/crypto/openpgp/armor" //nolint:staticcheck
|
||||
"golang.org/x/crypto/openpgp/packet" //nolint:staticcheck
|
||||
|
||||
"github.com/grafana/grafana/pkg/build/config"
|
||||
"github.com/grafana/grafana/pkg/build/fsutil"
|
||||
"github.com/grafana/grafana/pkg/infra/fs"
|
||||
)
|
||||
|
||||
// UpdateRPMRepo updates the RPM repository with the new release.
|
||||
func UpdateRPMRepo(cfg PublishConfig, workDir string) error {
|
||||
if cfg.ReleaseMode.Mode != config.TagMode {
|
||||
panic(fmt.Sprintf("Unsupported version mode %s", cfg.ReleaseMode.Mode))
|
||||
}
|
||||
|
||||
if cfg.ReleaseMode.IsTest && cfg.Config.RPMRepoBucket == DefaultRPMRepoBucket {
|
||||
return fmt.Errorf("in test-release mode, the default RPM repo bucket shouldn't be used")
|
||||
}
|
||||
|
||||
if err := downloadRPMs(cfg, workDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repoRoot, err := fsutil.CreateTempDir("rpm-repo")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := os.RemoveAll(repoRoot); err != nil {
|
||||
log.Printf("Failed to remove %q: %s\n", repoRoot, err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
repoName := "rpm"
|
||||
if cfg.ReleaseMode.IsBeta {
|
||||
repoName = "rpm-beta"
|
||||
}
|
||||
folderURI := fmt.Sprintf("gs://%s/%s/%s", cfg.RPMRepoBucket, strings.ToLower(string(cfg.Edition)), repoName)
|
||||
|
||||
// Download the RPM database
|
||||
log.Printf("Downloading RPM database from GCS (%s)...\n", folderURI)
|
||||
//nolint:gosec
|
||||
cmd := exec.Command("gsutil", "-m", "rsync", "-r", "-d", folderURI, repoRoot)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to download RPM database from GCS: %w\n%s", err, output)
|
||||
}
|
||||
|
||||
// Add the new release to the repo
|
||||
var sfx string
|
||||
switch cfg.Edition {
|
||||
case config.EditionOSS:
|
||||
case config.EditionEnterprise:
|
||||
sfx = EnterpriseSfx
|
||||
default:
|
||||
return fmt.Errorf("unsupported edition %q", cfg.Edition)
|
||||
}
|
||||
allRPMs, err := filepath.Glob(filepath.Join(workDir, fmt.Sprintf("grafana%s-*.rpm", sfx)))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list RPMs in %q: %w", workDir, err)
|
||||
}
|
||||
rpms := []string{}
|
||||
for _, rpm := range allRPMs {
|
||||
if strings.Contains(rpm, "-latest") {
|
||||
continue
|
||||
}
|
||||
|
||||
rpms = append(rpms, rpm)
|
||||
}
|
||||
// XXX: What does the following comment mean?
|
||||
// adds to many files for enterprise
|
||||
for _, rpm := range rpms {
|
||||
if err := fs.CopyFile(rpm, filepath.Join(repoRoot, filepath.Base(rpm))); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:gosec
|
||||
cmd = exec.Command("createrepo", repoRoot)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to create repo at %q: %w\n%s", repoRoot, err, output)
|
||||
}
|
||||
|
||||
if err := signRPMRepo(repoRoot, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Update the repo in GCS
|
||||
|
||||
// Sync packages first to avoid cache misses
|
||||
if cfg.DryRun {
|
||||
log.Printf("Simulating upload of RPMs to GCS (%s)\n", folderURI)
|
||||
} else {
|
||||
log.Printf("Uploading RPMs to GCS (%s)...\n", folderURI)
|
||||
args := []string{"-m", "cp"}
|
||||
args = append(args, rpms...)
|
||||
args = append(args, folderURI)
|
||||
//nolint:gosec
|
||||
cmd = exec.Command("gsutil", args...)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to upload RPMs to GCS: %w\n%s", err, output)
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.DryRun {
|
||||
log.Printf("Simulating upload of RPM repo metadata to GCS (%s)\n", folderURI)
|
||||
} else {
|
||||
log.Printf("Uploading RPM repo metadata to GCS (%s)...\n", folderURI)
|
||||
//nolint:gosec
|
||||
cmd = exec.Command("gsutil", "-m", "rsync", "-r", "-d", repoRoot, folderURI)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to upload RPM repo metadata to GCS: %w\n%s", err, output)
|
||||
}
|
||||
allRepoResources := fmt.Sprintf("%s/**/*", folderURI)
|
||||
log.Printf("Setting cache ttl for RPM repo resources on GCS (%s)...\n", allRepoResources)
|
||||
//nolint:gosec
|
||||
cmd = exec.Command("gsutil", "-m", "setmeta", "-h", CacheSettings+cfg.TTL, allRepoResources)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to set cache ttl for RPM repo resources on GCS: %w\n%s", err, output)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// downloadRPMs downloads RPM packages.
|
||||
func downloadRPMs(cfg PublishConfig, workDir string) error {
|
||||
if !strings.HasSuffix(workDir, string(filepath.Separator)) {
|
||||
workDir += string(filepath.Separator)
|
||||
}
|
||||
var version string
|
||||
if cfg.ReleaseMode.Mode == config.TagMode {
|
||||
if cfg.ReleaseMode.IsBeta {
|
||||
version = strings.ReplaceAll(cfg.Version, "-", "~")
|
||||
} else {
|
||||
version = cfg.Version
|
||||
}
|
||||
}
|
||||
if version == "" {
|
||||
panic(fmt.Sprintf("Unrecognized version mode %s", cfg.ReleaseMode.Mode))
|
||||
}
|
||||
|
||||
var sfx string
|
||||
switch cfg.Edition {
|
||||
case config.EditionOSS:
|
||||
case config.EditionEnterprise:
|
||||
sfx = EnterpriseSfx
|
||||
default:
|
||||
return fmt.Errorf("unrecognized edition %q", cfg.Edition)
|
||||
}
|
||||
|
||||
u := fmt.Sprintf("gs://%s/%s/%s/grafana%s-%s-*.*.rpm*", cfg.Bucket,
|
||||
strings.ToLower(string(cfg.Edition)), ReleaseFolder, sfx, version)
|
||||
log.Printf("Downloading RPM packages %q...\n", u)
|
||||
args := []string{
|
||||
"-m",
|
||||
"cp",
|
||||
u,
|
||||
workDir,
|
||||
}
|
||||
//nolint:gosec
|
||||
cmd := exec.Command("gsutil", args...)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to download RPM packages %q: %w\n%s", u, err, output)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPublicKey(cfg PublishConfig) (*packet.PublicKey, error) {
|
||||
f, err := os.Open(cfg.GPGPublicKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open %q: %w", cfg.GPGPublicKey, err)
|
||||
}
|
||||
defer func(f *os.File) {
|
||||
err := f.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}(f)
|
||||
|
||||
block, err := armor.Decode(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if block.Type != openpgp.PublicKeyType {
|
||||
return nil, fmt.Errorf("invalid public key block type: %q", block.Type)
|
||||
}
|
||||
|
||||
packetReader := packet.NewReader(block.Body)
|
||||
pkt, err := packetReader.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
key, ok := pkt.(*packet.PublicKey)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("got non-public key from packet reader: %T", pkt)
|
||||
}
|
||||
|
||||
return key, nil
|
||||
}
|
||||
|
||||
func getPrivateKey(cfg PublishConfig) (*packet.PrivateKey, error) {
|
||||
f, err := os.Open(cfg.GPGPrivateKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open %q: %w", cfg.GPGPrivateKey, err)
|
||||
}
|
||||
defer func(f *os.File) {
|
||||
err := f.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}(f)
|
||||
|
||||
passphraseB, err := os.ReadFile(cfg.GPGPassPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read %q: %w", cfg.GPGPrivateKey, err)
|
||||
}
|
||||
passphraseB = bytes.TrimSuffix(passphraseB, []byte("\n"))
|
||||
|
||||
block, err := armor.Decode(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if block.Type != openpgp.PrivateKeyType {
|
||||
return nil, fmt.Errorf("invalid private key block type: %q", block.Type)
|
||||
}
|
||||
|
||||
packetReader := packet.NewReader(block.Body)
|
||||
pkt, err := packetReader.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
key, ok := pkt.(*packet.PrivateKey)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("got non-private key from packet reader: %T", pkt)
|
||||
}
|
||||
|
||||
if err := key.Decrypt(passphraseB); err != nil {
|
||||
return nil, fmt.Errorf("failed to decrypt private key: %w", err)
|
||||
}
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// signRPMRepo signs an RPM repository using PGP.
|
||||
// The signature gets written to the file repodata/repomd.xml.asc.
|
||||
func signRPMRepo(repoRoot string, cfg PublishConfig) error {
|
||||
if cfg.GPGPublicKey == "" || cfg.GPGPrivateKey == "" {
|
||||
return fmt.Errorf("private or public key is empty")
|
||||
}
|
||||
|
||||
log.Printf("Signing RPM repo")
|
||||
|
||||
pubKey, err := getPublicKey(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
privKey, err := getPrivateKey(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pcfg := packet.Config{
|
||||
DefaultHash: crypto.SHA256,
|
||||
DefaultCipher: packet.CipherAES256,
|
||||
DefaultCompressionAlgo: packet.CompressionZLIB,
|
||||
CompressionConfig: &packet.CompressionConfig{
|
||||
Level: 9,
|
||||
},
|
||||
RSABits: 4096,
|
||||
}
|
||||
currentTime := pcfg.Now()
|
||||
uid := packet.NewUserId("", "", "")
|
||||
|
||||
isPrimaryID := false
|
||||
keyLifetimeSecs := uint32(86400 * 365)
|
||||
signer := openpgp.Entity{
|
||||
PrimaryKey: pubKey,
|
||||
PrivateKey: privKey,
|
||||
Identities: map[string]*openpgp.Identity{
|
||||
uid.Id: {
|
||||
Name: uid.Name,
|
||||
UserId: uid,
|
||||
SelfSignature: &packet.Signature{
|
||||
CreationTime: currentTime,
|
||||
SigType: packet.SigTypePositiveCert,
|
||||
PubKeyAlgo: packet.PubKeyAlgoRSA,
|
||||
Hash: pcfg.Hash(),
|
||||
IsPrimaryId: &isPrimaryID,
|
||||
FlagsValid: true,
|
||||
FlagSign: true,
|
||||
FlagCertify: true,
|
||||
IssuerKeyId: &pubKey.KeyId,
|
||||
},
|
||||
},
|
||||
},
|
||||
Subkeys: []openpgp.Subkey{
|
||||
{
|
||||
PublicKey: pubKey,
|
||||
PrivateKey: privKey,
|
||||
Sig: &packet.Signature{
|
||||
CreationTime: currentTime,
|
||||
SigType: packet.SigTypeSubkeyBinding,
|
||||
PubKeyAlgo: packet.PubKeyAlgoRSA,
|
||||
Hash: pcfg.Hash(),
|
||||
PreferredHash: []uint8{8}, // SHA-256
|
||||
FlagsValid: true,
|
||||
FlagEncryptStorage: true,
|
||||
FlagEncryptCommunications: true,
|
||||
IssuerKeyId: &pubKey.KeyId,
|
||||
KeyLifetimeSecs: &keyLifetimeSecs,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Ignore gosec G304 as this function is only used in the build process.
|
||||
//nolint:gosec
|
||||
freader, err := os.Open(filepath.Join(repoRoot, "repodata", "repomd.xml"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(freader *os.File) {
|
||||
err := freader.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}(freader)
|
||||
|
||||
// Ignore gosec G304 as this function is only used in the build process.
|
||||
//nolint:gosec
|
||||
sigwriter, err := os.Create(filepath.Join(repoRoot, "repodata", "repomd.xml.asc"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(sigwriter *os.File) {
|
||||
err := sigwriter.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}(sigwriter)
|
||||
|
||||
if err := openpgp.ArmoredDetachSignText(sigwriter, &signer, freader, nil); err != nil {
|
||||
return fmt.Errorf("failed to write PGP signature: %w", err)
|
||||
}
|
||||
|
||||
if err := sigwriter.Close(); err != nil {
|
||||
return fmt.Errorf("failed to write PGP signature: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
package packaging
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/build/config"
|
||||
)
|
||||
|
||||
const pubKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: OpenPGP.js v4.10.10
|
||||
Comment: https://openpgpjs.org
|
||||
|
||||
xsBNBGM1b9wBCADZM49X7vwOS93KbgA6yhpwrYf8ZlzksGcDaYgp1IzvqHbs
|
||||
xeU1mmBYVH/bSKRDG0tt3Qdky4Nvl4Oqd+g0e2ZGjmlEy9zUiPTTK/BtXT+5
|
||||
s8oqih2NIAkyF91BNZABAgvh/vJdYImhYeUQBDqMJgqZ/Y/Ha31N7rSW+jUt
|
||||
LHspbN0ztJYjuEd/bg2NKH7Gs/AyNvX9IQTC4k7iRRafx7q/PBCVtsk+NCwz
|
||||
BEkL93xpAdcdYiMNrRP2eIHQjBmNZ/oUCkcDsLCBvcSq6P2lGpNnpPzVoTJf
|
||||
v2qrWkVn5txJJsOkmBGpEDbECPunVilrWO6RPomP0yYkr6NE4XeCJ3QhABEB
|
||||
AAHNGWR1bW15IDxkdW1teUBob3RtYWlsLmNvbT7CwI0EEAEIACAFAmM1b9wG
|
||||
CwkHCAMCBBUICgIEFgIBAAIZAQIbAwIeAQAhCRAoJ1i5w6kkAxYhBCQv+iwt
|
||||
IFn7vj9PLygnWLnDqSQDPxkH/0Ju2Cah+bOxl09uv2Ft2BVlQh0u+wJyRVgs
|
||||
KxTxldAXFZwMrN4wK/GUoGWDiy2tzNtoVE6GpxWUj+LvSGFaVLNVjW+Le77I
|
||||
BP/sl1wKHJbQhseKc7Mz5Zj3i0F1FPM+rLik7tNk6kiEBqYVyyXahyT98Hu1
|
||||
1OKEV+8NiRG47iNgd/dpgEdVSS4DN/dL6m5q+CVy9YnlR+wXxF/2xcMmWBzR
|
||||
V2cPVw0JzunpUV8lDDQ/n1sPw61D3oL1aH0bkn8aA8pEceKOVIYOaja7LkLX
|
||||
uSlROlALA/M2fuubradW9I3FcrJNn+/xA52el2l/Hn/Syf9GQV/Ll/R+qKIo
|
||||
Z57xWd7OwE0EYzVv3AEIAJl/PNYOF2prNKY58BfZ74XurDb9mNlZ1wsIqrOu
|
||||
J/euzHEnzkCAjMUuXV7wcugjQlmpcZn6Y0QmQ2uX7SwPCMovDvngbXeAfbdd
|
||||
6FUKecQ0sG54Plm8HSMNdjetdUVl7ACxjJO8Rdc/Asx7ua7gMm42CVfqMj4L
|
||||
qN5foUBlaKJ1iGKUpQ+673UQWMYeOBuu9G8awbSzGaphN97CIX7xEMGzGeff
|
||||
yHLHK+MsfX935uDgDwJQzxJKEugIJDMKgWOLgVz1jRCsJKHlywHTWpVuMiKY
|
||||
Wnuq4tDNLBUQtaRL7uclG7Wejw/XNN0uD/zNHPgF5rmlYHVhrtDbBCP2XqTn
|
||||
WU8AEQEAAcLAdgQYAQgACQUCYzVv3AIbDAAhCRAoJ1i5w6kkAxYhBCQv+iwt
|
||||
IFn7vj9PLygnWLnDqSQDFqYH/AkdNaPUQlE7RQBigNRGOFBuqjhbLsV/rZf+
|
||||
/4K6wDHojM606lgLm57T4NUXnk53VIF3KO8+v8N11mCtPb+zBngfvVU14COC
|
||||
HEDNdOK19TlR+tH25cftfUiF+OJsgMQysErGuFEtwLE6TNzpQIcnw7SbjxMr
|
||||
EGacF9xCBKexB6MlR3GwJ2LBUJm3Lq/fvqImztoTlKDsrpk4JOH5FfYG+G2f
|
||||
1zU73fVsCCElX4qA/49rRQf0RNfhjRjmHULP8hSvCXUEhfiBggEgxof/vKlC
|
||||
qauHC55luuIeabju8HaXTjpz019cq+3IUgewX/ky0PhQXEW9SoODKabPY2yS
|
||||
yUbHFm4=
|
||||
=OCSx
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
`
|
||||
|
||||
const privKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: OpenPGP.js v4.10.10
|
||||
Comment: https://openpgpjs.org
|
||||
|
||||
xcMGBGM1b9wBCADZM49X7vwOS93KbgA6yhpwrYf8ZlzksGcDaYgp1IzvqHbs
|
||||
xeU1mmBYVH/bSKRDG0tt3Qdky4Nvl4Oqd+g0e2ZGjmlEy9zUiPTTK/BtXT+5
|
||||
s8oqih2NIAkyF91BNZABAgvh/vJdYImhYeUQBDqMJgqZ/Y/Ha31N7rSW+jUt
|
||||
LHspbN0ztJYjuEd/bg2NKH7Gs/AyNvX9IQTC4k7iRRafx7q/PBCVtsk+NCwz
|
||||
BEkL93xpAdcdYiMNrRP2eIHQjBmNZ/oUCkcDsLCBvcSq6P2lGpNnpPzVoTJf
|
||||
v2qrWkVn5txJJsOkmBGpEDbECPunVilrWO6RPomP0yYkr6NE4XeCJ3QhABEB
|
||||
AAH+CQMIuDEg1p2Y6zbg0EQ3JvsP7VQBGsuXg9khTjktoxhwici/d+rcIW7Q
|
||||
SuKWJGqs83LTeeGmS+9etNtf3LqRdPnI7f0qbT47mAqvp2gn7Rvbrabk+5Jj
|
||||
AQS/DDLlWNiWsPrMBMZ7TZpiQ+g7gnIZaV10taFupYJr69AjtED+NPu8LOvZ
|
||||
2ItK9xBqOwl5mkNe7ps/uTT6jwYSWxeObp4ymnLDLONY3eHuaYP9QB/NSlw0
|
||||
80Wo5qBPljlU8JdbEoLFU4gY6wkEbLa/DVbEVXSHfWVtr8jZbzHW39TBxpG2
|
||||
Dxk52EVyu8Gf9XIQN2ZjDP3CzBGmlxJjLxLUD4GmRSPaDGK7LCN9ZztaXy3Y
|
||||
WtF6RJfNzEoDdCaV0kkM3AskQDsQ+CWsDVsbbQyDtfncVG6cDzqmoDrBCSq1
|
||||
Bsoz07k2hj9VP0aP2xU78qcpJWO2rmhAHy9W2NqjXSBJriy1JXrK5o2/lUUr
|
||||
94R8NLvqeVbInUw/zovVctaujHIBhNKL9wn2T0LWrA2OEJUz0HWo6ZQSaNzl
|
||||
Obtz0M8gCj/4sDYjRAiDk50FzOcZp8ijYQFVypQTVzHki5T/JfvBnMpo+4Uc
|
||||
93QB1woyiZuJCIj7DpY3MkZ5fTDtgJPa+0k8r+lPnAmE6auGUaH7JRKhbBu0
|
||||
8faDwaiSv3kD3EEDffoWX/axLLYta9jTDnitTXbf1jY03pdJeiU/ZX0BQTZi
|
||||
pehZ/6yi/qXM/F8HDVEWriSLqVsMLrXXeFIojAc3fJ/QPpAZSx6E/Fe2xh8c
|
||||
yURov5krU1zNJDwqC3SjHsHQ/UlLtamDDmmuXX+xb1CwIDd6WksGsCbe/LoN
|
||||
TxViV4hOjIeh5TwRP5jQaqsVKCT8fzoDrRXy76taT+Zaaen+J6rC51HQwyEq
|
||||
Qgf1e7WodzN3r10UV6/L/wNkfdWJgf5MzRlkdW1teSA8ZHVtbXlAaG90bWFp
|
||||
bC5jb20+wsCNBBABCAAgBQJjNW/cBgsJBwgDAgQVCAoCBBYCAQACGQECGwMC
|
||||
HgEAIQkQKCdYucOpJAMWIQQkL/osLSBZ+74/Ty8oJ1i5w6kkAz8ZB/9Cbtgm
|
||||
ofmzsZdPbr9hbdgVZUIdLvsCckVYLCsU8ZXQFxWcDKzeMCvxlKBlg4strczb
|
||||
aFROhqcVlI/i70hhWlSzVY1vi3u+yAT/7JdcChyW0IbHinOzM+WY94tBdRTz
|
||||
Pqy4pO7TZOpIhAamFcsl2ock/fB7tdTihFfvDYkRuO4jYHf3aYBHVUkuAzf3
|
||||
S+puavglcvWJ5UfsF8Rf9sXDJlgc0VdnD1cNCc7p6VFfJQw0P59bD8OtQ96C
|
||||
9Wh9G5J/GgPKRHHijlSGDmo2uy5C17kpUTpQCwPzNn7rm62nVvSNxXKyTZ/v
|
||||
8QOdnpdpfx5/0sn/RkFfy5f0fqiiKGee8Vnex8MGBGM1b9wBCACZfzzWDhdq
|
||||
azSmOfAX2e+F7qw2/ZjZWdcLCKqzrif3rsxxJ85AgIzFLl1e8HLoI0JZqXGZ
|
||||
+mNEJkNrl+0sDwjKLw754G13gH23XehVCnnENLBueD5ZvB0jDXY3rXVFZewA
|
||||
sYyTvEXXPwLMe7mu4DJuNglX6jI+C6jeX6FAZWiidYhilKUPuu91EFjGHjgb
|
||||
rvRvGsG0sxmqYTfewiF+8RDBsxnn38hyxyvjLH1/d+bg4A8CUM8SShLoCCQz
|
||||
CoFji4Fc9Y0QrCSh5csB01qVbjIimFp7quLQzSwVELWkS+7nJRu1no8P1zTd
|
||||
Lg/8zRz4Bea5pWB1Ya7Q2wQj9l6k51lPABEBAAH+CQMIwr3YSD15lYrgItoy
|
||||
MDsrWqMMHJsSxusbQiK0KLgjFBuDuTolsu9zqQCHEm2dxChqT+yQ6AeeynRD
|
||||
pDMVkHEvhShvGUhB6Bu5wClHj8+xFpyprShE/KbEuppNdfIRgWVYc7UX+TYz
|
||||
6BymqhzKyIw2Q33ocrXgTRZ02HM7urKVvAhsJCEff0paByOzCspiv/TPRihi
|
||||
7GAZY0wFLDPe9qr+07ExT2ndMDX8Xb1mlg8IeaSWUaNilm7M8oW3xnUBnXeD
|
||||
XglTkObGeRVXAINim9uL4soT3lamN4QwgBus9WzFqOOCMk11fjatY8kY1zX9
|
||||
epO27igGtMwTFl11XcQLlFyvlgPBeWtFam7RiDPa3VF0XubmBYZBmqWpccWs
|
||||
xl0xHCtUK7Pd0O4kSqxsL9cB0MX9iR1yPkM8wA++Mp6pEfNcXUrGIdlie0H5
|
||||
aCq8rguYG5VuFosSUatdCbpRVGBxGnhxHes0mNTPgwAoAVNYBWXH5iq5HxKy
|
||||
i3Zy5V7ZKSyDrfg/0AajtDW5h3g+wglUI9UCdT4tNLFwYbhHqGH2xdBztYI0
|
||||
iSJ7COLmo26smkA8UXxsrlw8PWPzpbhQOG06EbMjncJimJDMI1YDC6ag7M5l
|
||||
OcG9uXZQ22ipAz5CSPtyL0/0WAp4yyn1VQRBK42n/y9ld+dMbuq6majazb15
|
||||
6sEgHUKERcwGs0Ftfj5Zamwhm7ZoIe26XEqvcshpQpv1Q9hktluVeSbiVaBe
|
||||
Nl8zUZHlo/0zUc5j7G5Up58t+ChSsyOFJGM7CGkKHHawBZYCs0EcpsdAPr3T
|
||||
1C8A0Wt9POTETYM4pZFOoLds6VTolZZcxeBN5YPoN2kbwFpOgPJN09Zz8z8S
|
||||
4psQRV4KQ92XDPZ/6q2BH5i2+F2ZwUsvCR4DwgzbVGZSRV6mM7lkjZSmnWfC
|
||||
AE7DUl7XwsB2BBgBCAAJBQJjNW/cAhsMACEJECgnWLnDqSQDFiEEJC/6LC0g
|
||||
Wfu+P08vKCdYucOpJAMWpgf8CR01o9RCUTtFAGKA1EY4UG6qOFsuxX+tl/7/
|
||||
grrAMeiMzrTqWAubntPg1ReeTndUgXco7z6/w3XWYK09v7MGeB+9VTXgI4Ic
|
||||
QM104rX1OVH60fblx+19SIX44myAxDKwSsa4US3AsTpM3OlAhyfDtJuPEysQ
|
||||
ZpwX3EIEp7EHoyVHcbAnYsFQmbcur9++oibO2hOUoOyumTgk4fkV9gb4bZ/X
|
||||
NTvd9WwIISVfioD/j2tFB/RE1+GNGOYdQs/yFK8JdQSF+IGCASDGh/+8qUKp
|
||||
q4cLnmW64h5puO7wdpdOOnPTX1yr7chSB7Bf+TLQ+FBcRb1Kg4Mpps9jbJLJ
|
||||
RscWbg==
|
||||
=KJNy
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
`
|
||||
|
||||
// Dummy GPG keys, used only for testing
|
||||
// nolint:gosec
|
||||
const passPhrase = `MkDgjkrgdGxt`
|
||||
|
||||
func TestSignRPMRepo(t *testing.T) {
|
||||
repoDir := t.TempDir()
|
||||
workDir := t.TempDir()
|
||||
pubKeyPath := filepath.Join(workDir, "pub.key")
|
||||
err := os.WriteFile(pubKeyPath, []byte(pubKey), 0600)
|
||||
require.NoError(t, err)
|
||||
privKeyPath := filepath.Join(workDir, "priv.key")
|
||||
err = os.WriteFile(privKeyPath, []byte(privKey), 0600)
|
||||
require.NoError(t, err)
|
||||
passPhrasePath := filepath.Join(workDir, "passphrase")
|
||||
err = os.WriteFile(passPhrasePath, []byte(passPhrase), 0600)
|
||||
require.NoError(t, err)
|
||||
err = os.Mkdir(filepath.Join(repoDir, "repodata"), 0700)
|
||||
require.NoError(t, err)
|
||||
err = os.WriteFile(filepath.Join(repoDir, "repodata", "repomd.xml"), []byte("<xml></xml>"), 0600)
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := PublishConfig{
|
||||
Config: config.Config{
|
||||
GPGPrivateKey: privKeyPath,
|
||||
GPGPublicKey: pubKeyPath,
|
||||
GPGPassPath: passPhrasePath,
|
||||
},
|
||||
}
|
||||
|
||||
err = signRPMRepo(repoDir, cfg)
|
||||
require.NoError(t, err)
|
||||
}
|
Loading…
Reference in New Issue
Block a user