mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-09-27 20:10:51 -04:00
bazel: pseudo version tool freshness check (#1869)
* switch to darwin compatible shasum
* add bazel rule
* update shellscript for in-place updates
* Revert "update shellscript for in-place updates"
This reverts commit 87d39b06f7
.
* add version tool freshness check
* remove pseudo-version file
* revert to `sha256sum`
* fix workflow indentation
This commit is contained in:
parent
892752a1f8
commit
72e168e653
9 changed files with 251 additions and 40 deletions
|
@ -1,12 +1,6 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_cross_binary", "go_library")
|
||||
load("//bazel/sh:def.bzl", "sh_template")
|
||||
|
||||
platforms = [
|
||||
"darwin_amd64",
|
||||
"darwin_arm64",
|
||||
"linux_amd64",
|
||||
"linux_arm64",
|
||||
]
|
||||
load("//hack/pseudo-version:platforms.bzl", "platforms")
|
||||
|
||||
go_library(
|
||||
name = "pseudo-version_lib",
|
||||
|
@ -37,18 +31,18 @@ go_binary(
|
|||
target = ":pseudo-version",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
for platform in platforms
|
||||
for platform in platforms()
|
||||
]
|
||||
|
||||
sh_template(
|
||||
name = "pseudo_version_tool_freshness",
|
||||
data = [
|
||||
":pseudo_version_" + platform
|
||||
for platform in platforms
|
||||
for platform in platforms()
|
||||
],
|
||||
substitutions = {
|
||||
"@@PSEUDO_VERSION_%s@@" % platform: "$(rootpath :pseudo_version_%s)" % platform
|
||||
for platform in platforms
|
||||
for platform in platforms()
|
||||
},
|
||||
template = "pseudo_version_tool_freshness.sh.in",
|
||||
visibility = ["//visibility:public"],
|
||||
|
|
27
hack/pseudo-version/check/BUILD.bazel
Normal file
27
hack/pseudo-version/check/BUILD.bazel
Normal file
|
@ -0,0 +1,27 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
|
||||
load("//hack/pseudo-version:platforms.bzl", "platforms")
|
||||
|
||||
go_library(
|
||||
name = "check_lib",
|
||||
srcs = ["check.go"],
|
||||
importpath = "github.com/edgelesssys/constellation/v2/hack/pseudo-version/check",
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"@com_github_aws_aws_sdk_go//aws",
|
||||
"@com_github_aws_aws_sdk_go//aws/awserr",
|
||||
"@com_github_aws_aws_sdk_go//aws/session",
|
||||
"@com_github_aws_aws_sdk_go//service/s3",
|
||||
"@com_github_aws_aws_sdk_go//service/s3/s3manager",
|
||||
"@io_bazel_rules_go//go/runfiles:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "check",
|
||||
data = [
|
||||
"//hack/pseudo-version:pseudo_version_" + platform
|
||||
for platform in platforms()
|
||||
],
|
||||
embed = [":check_lib"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
176
hack/pseudo-version/check/check.go
Normal file
176
hack/pseudo-version/check/check.go
Normal file
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||
"github.com/bazelbuild/rules_go/go/runfiles"
|
||||
)
|
||||
|
||||
const (
|
||||
darwinArm64Filename = "pseudo_version_darwin_arm64"
|
||||
darwinAmd64Filename = "pseudo_version_darwin_amd64"
|
||||
linuxArm64Filename = "pseudo_version_linux_arm64"
|
||||
linuxAmd64Filename = "pseudo_version_linux_amd64"
|
||||
bucket = "cdn-constellation-backend"
|
||||
keyPrefix = "constellation/cas/sha256/"
|
||||
)
|
||||
|
||||
func main() {
|
||||
checker, err := newChecker()
|
||||
if err != nil {
|
||||
log.Fatalf("failed to create checker: %v", err)
|
||||
}
|
||||
|
||||
if err := checker.checkAll(); err != nil {
|
||||
log.Fatalf("failed to check pseudo-version tools: %v", err)
|
||||
}
|
||||
|
||||
log.Println("All pseudo-version tools are up-to-date")
|
||||
}
|
||||
|
||||
// a checker checks if the pseudo-version tool with the specified hash exists in S3.
|
||||
type checker struct {
|
||||
files *runfiles.Runfiles
|
||||
downloader *s3manager.Downloader
|
||||
uploader *s3manager.Uploader
|
||||
pseudoVersionToolFilenames []string
|
||||
}
|
||||
|
||||
// newChecker creates a new checker.
|
||||
func newChecker() (*checker, error) {
|
||||
files, err := runfiles.New()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to create runfiles: %v", err)
|
||||
}
|
||||
|
||||
sess := session.Must(session.NewSession(&aws.Config{
|
||||
Region: aws.String("eu-central-1"),
|
||||
}))
|
||||
|
||||
return &checker{
|
||||
files: files,
|
||||
downloader: s3manager.NewDownloader(sess),
|
||||
uploader: s3manager.NewUploader(sess),
|
||||
pseudoVersionToolFilenames: []string{
|
||||
darwinArm64Filename,
|
||||
darwinAmd64Filename,
|
||||
linuxArm64Filename,
|
||||
linuxAmd64Filename,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// checkAll checks all embedded pseudo-version tools.
|
||||
func (c *checker) checkAll() error {
|
||||
for _, filename := range c.pseudoVersionToolFilenames {
|
||||
if err := c.check(filename); err != nil {
|
||||
return fmt.Errorf("failed to check pseudo-version tool (%s): %v", filename, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// check checks if the pseudo-version tool with the specified hash exists in S3 and
|
||||
// uploads it if it doesn't.
|
||||
func (c *checker) check(filename string) error {
|
||||
log.Println("Checking pseudo-version tool:", filename)
|
||||
hash, err := c.hashPseudoVersionTool(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to hash pseudo-version tool (%s): %v", filename, err)
|
||||
}
|
||||
log.Printf("Hash: %x\n", hash)
|
||||
|
||||
exists, err := c.matchesS3Hash(filename, hash)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check if pseudo-version tool (%s) exists in S3: %v", filename, err)
|
||||
}
|
||||
log.Println("Exists in S3:", exists)
|
||||
|
||||
if !exists {
|
||||
log.Println("Uploading pseudo-version tool:", filename)
|
||||
if err := c.uploadToS3(filename, hash); err != nil {
|
||||
return fmt.Errorf("failed to upload pseudo-version tool (%s) to S3: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// uploadToS3 uploads the pseudo-version tool with the specified hash to S3.
|
||||
func (c *checker) uploadToS3(filename string, hash [32]byte) error {
|
||||
contents, err := c.files.ReadFile(fmt.Sprintf("__main__/hack/pseudo-version/%s", filename))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read pseudo-version tool (%s): %v", filename, err)
|
||||
}
|
||||
|
||||
key := keyPrefix + fmt.Sprintf("%x", hash)
|
||||
_, err = c.uploader.Upload(&s3manager.UploadInput{
|
||||
Bucket: aws.String(bucket),
|
||||
Key: aws.String(key),
|
||||
Body: bytes.NewReader(contents),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to upload %x to S3: %v", filename, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// matchesS3Hash checks the pseudo-version tool with the specified hash exists in S3.
|
||||
func (c *checker) matchesS3Hash(filename string, hash [32]byte) (bool, error) {
|
||||
tmpfileName := filename + "-tmp"
|
||||
tmpfile, err := os.Create(tmpfileName)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to create temporary file %s: %v", tmpfileName, err)
|
||||
}
|
||||
defer os.Remove(tmpfileName)
|
||||
|
||||
key := keyPrefix + fmt.Sprintf("%x", hash)
|
||||
_, err = c.downloader.Download(tmpfile, &s3.GetObjectInput{
|
||||
Bucket: aws.String(bucket),
|
||||
Key: aws.String(key),
|
||||
})
|
||||
if err != nil {
|
||||
if isNoSuchKeyErr(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("failed to download %x from S3: %v", filename, err)
|
||||
}
|
||||
|
||||
// A file with the hash exists in S3
|
||||
tmpfile.Close()
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// hashPseudoVersionTool hashes the specified embedded pseudo-version tool.
|
||||
func (c *checker) hashPseudoVersionTool(filename string) ([32]byte, error) {
|
||||
contents, err := c.files.ReadFile(fmt.Sprintf("__main__/hack/pseudo-version/%s", filename))
|
||||
if err != nil {
|
||||
return [32]byte{}, fmt.Errorf("failed to read pseudo-version tool (%s): %v", filename, err)
|
||||
}
|
||||
|
||||
return sha256.Sum256(contents), nil
|
||||
}
|
||||
|
||||
func isNoSuchKeyErr(err error) bool {
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
if aerr.Code() == s3.ErrCodeNoSuchKey {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
9
hack/pseudo-version/platforms.bzl
Normal file
9
hack/pseudo-version/platforms.bzl
Normal file
|
@ -0,0 +1,9 @@
|
|||
"""Platforms"""
|
||||
|
||||
def platforms():
|
||||
return [
|
||||
"darwin_amd64",
|
||||
"darwin_arm64",
|
||||
"linux_amd64",
|
||||
"linux_arm64",
|
||||
]
|
Loading…
Add table
Add a link
Reference in a new issue