Skip to content

Commit bd4ecf8

Browse files
committed
plume/release: support running update-release-index locally
Currently, that function operates directly on an S3 bucket. This makes it harder to test locally. Add a new `--local-mode` option in which we expect to be in a cosa workdir with release metadata present and a release index. This is mostly peppering conditionals in the code. Patch best viewed with whitespace ignored.
1 parent ef55754 commit bd4ecf8

File tree

1 file changed

+79
-25
lines changed

1 file changed

+79
-25
lines changed

mantle/cmd/plume/release.go

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/aws/aws-sdk-go/aws/awserr"
2929
"github.com/coreos/coreos-assembler/mantle/platform/api/aws"
3030
"github.com/coreos/stream-metadata-go/release"
31+
"github.com/pkg/errors"
3132
"github.com/spf13/cobra"
3233
)
3334

@@ -41,6 +42,27 @@ var (
4142

4243
specBucketPrefix string
4344

45+
// This is useful for testing `update-release-index` locally. The command is then expected to be run in a cosa workdir with the release metadata and release index available, hosted at the same levels they would be in S3. For reference:
46+
// ```
47+
// $ tree -L 3
48+
// .
49+
// ├── builds
50+
// │   ├── 40.20241019.3.0
51+
// │   │   ├── aarch64
52+
// │   │   ├── ppc64le
53+
// │   │   ├── release.json
54+
// │   │   ├── s390x
55+
// │   │   └── x86_64
56+
// │   ├── builds.json
57+
// │   └── latest -> 40.20241019.3.0
58+
// ...
59+
// ├── releases.json
60+
// ├── src
61+
// ...
62+
// └── tmp
63+
// ```
64+
releaseIndexLocal bool
65+
4466
cmdMakeAmisPublic = &cobra.Command{
4567
Use: "make-amis-public [options]",
4668
Short: "Make the AMIs of a CoreOS release public.",
@@ -71,6 +93,7 @@ func init() {
7193
cmdUpdateReleaseIndex.Flags().StringVar(&specRegion, "region", "us-east-1", "S3 bucket region")
7294
cmdUpdateReleaseIndex.Flags().StringVarP(&specStream, "stream", "", "", "target stream")
7395
cmdUpdateReleaseIndex.Flags().StringVarP(&specVersion, "version", "", "", "release version")
96+
cmdUpdateReleaseIndex.Flags().BoolVarP(&releaseIndexLocal, "local-mode", "", false, "operate on local files")
7497
root.AddCommand(cmdUpdateReleaseIndex)
7598

7699
}
@@ -85,10 +108,10 @@ func validateArgs(args []string) {
85108
if specStream == "" {
86109
plog.Fatal("--stream is required")
87110
}
88-
if specBucketPrefix == "" {
111+
if specBucketPrefix == "" && !releaseIndexLocal {
89112
plog.Fatal("--bucket-prefix is required")
90113
}
91-
if specRegion == "" {
114+
if specRegion == "" && !releaseIndexLocal {
92115
plog.Fatal("--region is required")
93116
}
94117
}
@@ -105,8 +128,20 @@ func runMakeAmisPublic(cmd *cobra.Command, args []string) {
105128

106129
func runUpdateReleaseIndex(cmd *cobra.Command, args []string) {
107130
validateArgs(args)
108-
api := getAWSApi()
109-
rel := getReleaseMetadata(api)
131+
var api *aws.API
132+
var rel release.Release
133+
if !releaseIndexLocal {
134+
api = getAWSApi()
135+
rel = getReleaseMetadata(api)
136+
} else {
137+
localRelease := fmt.Sprintf("builds/%s/release.json", specVersion)
138+
if releaseData, err := os.ReadFile(localRelease); err != nil {
139+
plog.Fatalf("reading release metadata at %s: %v", localRelease, err)
140+
} else if err := json.Unmarshal(releaseData, &rel); err != nil {
141+
plog.Fatalf("unmarshaling release metadata at %s: %v", localRelease, err)
142+
}
143+
}
144+
110145
modifyReleaseMetadataIndex(api, rel)
111146
}
112147

@@ -209,25 +244,38 @@ func modifyReleaseMetadataIndex(api *aws.API, rel release.Release) {
209244
// version. Plus we need S3 creds anyway later on to push the modified
210245
// release index back.
211246

212-
bucket, prefix := getBucketAndStreamPrefix()
213-
path := filepath.Join(prefix, "releases.json")
214-
data, err := func() ([]byte, error) {
215-
f, err := api.DownloadFile(bucket, path)
216-
if err != nil {
217-
if awsErr, ok := err.(awserr.Error); ok {
218-
if awsErr.Code() == "NoSuchKey" {
219-
return []byte("{}"), nil
247+
var bucket, prefix, path string
248+
if !releaseIndexLocal {
249+
bucket, prefix = getBucketAndStreamPrefix()
250+
path = filepath.Join(prefix, "releases.json")
251+
} else {
252+
path = "releases.json"
253+
}
254+
var data []byte
255+
var err error
256+
if !releaseIndexLocal {
257+
data, err = func() ([]byte, error) {
258+
f, err := api.DownloadFile(bucket, path)
259+
if err != nil {
260+
if awsErr, ok := err.(awserr.Error); ok {
261+
if awsErr.Code() == "NoSuchKey" {
262+
return []byte("{}"), nil
263+
}
220264
}
265+
return []byte{}, fmt.Errorf("downloading release metadata index: %v", err)
221266
}
222-
return []byte{}, fmt.Errorf("downloading release metadata index: %v", err)
223-
}
224-
defer f.Close()
225-
d, err := io.ReadAll(f)
226-
if err != nil {
227-
return []byte{}, fmt.Errorf("reading release metadata index: %v", err)
267+
defer f.Close()
268+
d, err := io.ReadAll(f)
269+
if err != nil {
270+
return []byte{}, fmt.Errorf("reading release metadata index: %v", err)
271+
}
272+
return d, nil
273+
}()
274+
} else {
275+
if data, err = os.ReadFile(path); err != nil {
276+
err = errors.Wrapf(err, "reading release metadata index from %s", path)
228277
}
229-
return d, nil
230-
}()
278+
}
231279
if err != nil {
232280
plog.Fatal(err)
233281
}
@@ -293,11 +341,17 @@ func modifyReleaseMetadataIndex(api *aws.API, rel release.Release) {
293341
plog.Fatalf("marshalling release metadata json: %v", err)
294342
}
295343

296-
// we don't want this to be cached for very long so that e.g. Cincinnati picks it up quickly
297-
var releases_max_age = 60 * 5
298-
err = api.UploadObjectExt(bytes.NewReader(out), bucket, path, true, "public-read", aws.ContentTypeJSON, releases_max_age)
299-
if err != nil {
300-
plog.Fatalf("uploading release metadata json: %v", err)
344+
if !releaseIndexLocal {
345+
// we don't want this to be cached for very long so that e.g. Cincinnati picks it up quickly
346+
var releases_max_age = 60 * 5
347+
err = api.UploadObjectExt(bytes.NewReader(out), bucket, path, true, "public-read", aws.ContentTypeJSON, releases_max_age)
348+
if err != nil {
349+
plog.Fatalf("uploading release metadata json: %v", err)
350+
}
351+
} else {
352+
if err := os.WriteFile(path, out, 0644); err != nil {
353+
plog.Fatalf("writing release metadata json to %s: %v", path, err)
354+
}
301355
}
302356
}
303357

0 commit comments

Comments
 (0)