Skip to content

Commit 5b3431a

Browse files
authored
feat(cas-backend): add configurable max blob size per backend (#2453)
Signed-off-by: Miguel Martinez <[email protected]>
1 parent 8feabbc commit 5b3431a

24 files changed

+390
-69
lines changed

CLAUDE.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,4 +255,13 @@ Code reviews are required for all submissions via GitHub pull requests.
255255
- make sure golang code is always formatted and golang-ci-lint is run
256256
- I do not want you to be in the co-author signoff
257257
- when the schema is changed, run make generate, do not create a migration explicitly
258-
- do not add generated by claude code in PR
258+
- If you are writing go code, adhere to best practices such as the ones in effective-go, or others. This could include, error handling patterns, interface design, package organization, concurrency patterns, etc.
259+
- do not change previous migrations, they are immutable
260+
- if you add any new dependency to a constructor, remember to run wire ./...
261+
- when adding new inedexes, make sure to update the generated sql migraiton files and make them CREATE INDEX CONCURRENTLY and set -- atlas:txmode none at the top
262+
- after updating protos, make sure to run `buf format -w`
263+
- Please avoid sycophantic commentary like ‘You’re absolutely correct!’ or ‘Brilliant idea!’
264+
- For each file you modify, update the license header. If it says 2024, change it to 2024-2025. If there's no license header, create one with the current year.
265+
- if you add any new dependency to a constructor, remember to run wire ./...
266+
- when creating PR message, keep it high-level, what functionality was added, don't add info about testing, no icons, no info about how the message was generated.
267+
- app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts is a special case that we don't want to upgrade, so if it upgrades, put it back to main

app/cli/cmd/casbackend.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2024 The Chainloop Authors.
2+
// Copyright 2024-2025 The Chainloop Authors.
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -18,13 +18,16 @@ package cmd
1818
import (
1919
"fmt"
2020

21+
"code.cloudfoundry.org/bytefmt"
2122
"github.com/chainloop-dev/chainloop/app/cli/pkg/action"
2223
"github.com/spf13/cobra"
2324
)
2425

2526
var (
2627
isDefaultCASBackendUpdateOption *bool
2728
descriptionCASBackendUpdateOption *string
29+
maxBytesCASBackendOption string
30+
parsedMaxBytes *int64
2831
)
2932

3033
func newCASBackendCmd() *cobra.Command {
@@ -46,6 +49,7 @@ func newCASBackendAddCmd() *cobra.Command {
4649
cmd.PersistentFlags().Bool("default", false, "set the backend as default in your organization")
4750
cmd.PersistentFlags().String("description", "", "descriptive information for this registration")
4851
cmd.PersistentFlags().String("name", "", "CAS backend name")
52+
cmd.PersistentFlags().StringVar(&maxBytesCASBackendOption, "max-bytes", "", "Maximum size for each blob stored in this backend (e.g., 100MB, 1GB)")
4953
err := cmd.MarkPersistentFlagRequired("name")
5054
cobra.CheckErr(err)
5155

@@ -56,12 +60,13 @@ func newCASBackendAddCmd() *cobra.Command {
5660
func newCASBackendUpdateCmd() *cobra.Command {
5761
cmd := &cobra.Command{
5862
Use: "update",
59-
Short: "Update a CAS backend description, credentials or default status",
63+
Short: "Update a CAS backend description, credentials, default status, or max bytes",
6064
}
6165

6266
cmd.PersistentFlags().Bool("default", false, "set the backend as default in your organization")
6367
cmd.PersistentFlags().String("description", "", "descriptive information for this registration")
6468
cmd.PersistentFlags().String("name", "", "CAS backend name")
69+
cmd.PersistentFlags().StringVar(&maxBytesCASBackendOption, "max-bytes", "", "Maximum size for each blob stored in this backend (e.g., 100MB, 1GB). Note: not supported for inline backends.")
6570

6671
cmd.AddCommand(newCASBackendUpdateOCICmd(), newCASBackendUpdateInlineCmd(), newCASBackendUpdateAzureBlobCmd(), newCASBackendUpdateAWSS3Cmd())
6772
return cmd
@@ -125,6 +130,24 @@ func confirmationPrompt(msg string) bool {
125130
return gotChallenge == "y" || gotChallenge == "Y"
126131
}
127132

133+
// parseMaxBytesOption validates and parses the --max-bytes flag value.
134+
// It stores the parsed result in parsedMaxBytes for child commands to use.
135+
func parseMaxBytesOption() error {
136+
parsedMaxBytes = nil
137+
if maxBytesCASBackendOption == "" {
138+
return nil
139+
}
140+
141+
bytes, err := bytefmt.ToBytes(maxBytesCASBackendOption)
142+
if err != nil {
143+
return fmt.Errorf("invalid max-bytes format: %w", err)
144+
}
145+
146+
bytesInt := int64(bytes)
147+
parsedMaxBytes = &bytesInt
148+
return nil
149+
}
150+
128151
// captureUpdateFlags reads the --default and --description flags only when explicitly set and
129152
// stores their values in the package-level pointer options. This avoids treating their zero
130153
// values as an intention to update.

app/cli/cmd/casbackend_add_azureblob.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2024 The Chainloop Authors.
2+
// Copyright 2024-2025 The Chainloop Authors.
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -30,6 +30,9 @@ func newCASBackendAddAzureBlobStorageCmd() *cobra.Command {
3030
cmd := &cobra.Command{
3131
Use: "azure-blob",
3232
Short: "Register a Azure Blob Storage CAS Backend",
33+
PreRunE: func(_ *cobra.Command, _ []string) error {
34+
return parseMaxBytesOption()
35+
},
3336
RunE: func(cmd *cobra.Command, args []string) error {
3437
// If we are setting the default, we list existing CAS backends
3538
// and ask the user to confirm the rewrite
@@ -61,7 +64,8 @@ func newCASBackendAddAzureBlobStorageCmd() *cobra.Command {
6164
"clientID": clientID,
6265
"clientSecret": clientSecret,
6366
},
64-
Default: isDefault,
67+
Default: isDefault,
68+
MaxBytes: parsedMaxBytes,
6569
}
6670

6771
res, err := action.NewCASBackendAdd(ActionOpts).Run(opts)
@@ -92,5 +96,6 @@ func newCASBackendAddAzureBlobStorageCmd() *cobra.Command {
9296
cobra.CheckErr(err)
9397

9498
cmd.Flags().StringVar(&container, "container", "chainloop", "Storage Container Name")
99+
95100
return cmd
96101
}

app/cli/cmd/casbackend_add_oci.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2024 The Chainloop Authors.
2+
// Copyright 2024-2025 The Chainloop Authors.
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -27,6 +27,9 @@ func newCASBackendAddOCICmd() *cobra.Command {
2727
cmd := &cobra.Command{
2828
Use: "oci",
2929
Short: "Register a OCI CAS Backend",
30+
PreRunE: func(_ *cobra.Command, _ []string) error {
31+
return parseMaxBytesOption()
32+
},
3033
RunE: func(cmd *cobra.Command, args []string) error {
3134
// If we are setting the default, we list existing CAS backends
3235
// and ask the user to confirm the rewrite
@@ -56,7 +59,8 @@ func newCASBackendAddOCICmd() *cobra.Command {
5659
"username": username,
5760
"password": password,
5861
},
59-
Default: isDefault,
62+
Default: isDefault,
63+
MaxBytes: parsedMaxBytes,
6064
}
6165

6266
res, err := action.NewCASBackendAdd(ActionOpts).Run(opts)
@@ -81,5 +85,6 @@ func newCASBackendAddOCICmd() *cobra.Command {
8185
cmd.Flags().StringVarP(&password, "password", "p", "", "registry password")
8286
err = cmd.MarkFlagRequired("password")
8387
cobra.CheckErr(err)
88+
8489
return cmd
8590
}

app/cli/cmd/casbackend_add_s3.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2024 The Chainloop Authors.
2+
// Copyright 2024-2025 The Chainloop Authors.
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -30,6 +30,9 @@ func newCASBackendAddAWSS3Cmd() *cobra.Command {
3030
cmd := &cobra.Command{
3131
Use: "aws-s3",
3232
Short: "Register a AWS S3 storage bucket",
33+
PreRunE: func(_ *cobra.Command, _ []string) error {
34+
return parseMaxBytesOption()
35+
},
3336
RunE: func(cmd *cobra.Command, args []string) error {
3437
isDefault, err := cmd.Flags().GetBool("default")
3538
cobra.CheckErr(err)
@@ -65,7 +68,8 @@ func newCASBackendAddAWSS3Cmd() *cobra.Command {
6568
"secretAccessKey": secretAccessKey,
6669
"region": region,
6770
},
68-
Default: isDefault,
71+
Default: isDefault,
72+
MaxBytes: parsedMaxBytes,
6973
}
7074

7175
res, err := action.NewCASBackendAdd(ActionOpts).Run(opts)

app/cli/cmd/casbackend_update_azureblob.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2024 The Chainloop Authors.
2+
// Copyright 2024-2025 The Chainloop Authors.
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -26,7 +26,10 @@ func newCASBackendUpdateAzureBlobCmd() *cobra.Command {
2626
var backendName, tenantID, clientID, clientSecret string
2727
cmd := &cobra.Command{
2828
Use: "azure-blob",
29-
Short: "Update a AzureBlob CAS Backend description, credentials or default status",
29+
Short: "Update a AzureBlob CAS Backend description, credentials, default status, or max bytes",
30+
PreRunE: func(_ *cobra.Command, _ []string) error {
31+
return parseMaxBytesOption()
32+
},
3033
RunE: func(cmd *cobra.Command, args []string) error {
3134
// capture flags only when explicitly set
3235
if err := captureUpdateFlags(cmd); err != nil {
@@ -49,7 +52,8 @@ func newCASBackendUpdateAzureBlobCmd() *cobra.Command {
4952
"clientID": clientID,
5053
"clientSecret": clientSecret,
5154
},
52-
Default: isDefaultCASBackendUpdateOption,
55+
Default: isDefaultCASBackendUpdateOption,
56+
MaxBytes: parsedMaxBytes,
5357
}
5458

5559
// this means that we are not updating credentials

app/cli/cmd/casbackend_update_oci.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2024 The Chainloop Authors.
2+
// Copyright 2024-2025 The Chainloop Authors.
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -26,7 +26,10 @@ func newCASBackendUpdateOCICmd() *cobra.Command {
2626
var backendName, username, password string
2727
cmd := &cobra.Command{
2828
Use: "oci",
29-
Short: "Update a OCI CAS Backend description, credentials or default status",
29+
Short: "Update a OCI CAS Backend description, credentials, default status, or max bytes",
30+
PreRunE: func(_ *cobra.Command, _ []string) error {
31+
return parseMaxBytesOption()
32+
},
3033
RunE: func(cmd *cobra.Command, args []string) error {
3134
// capture flags only when explicitly set
3235
if err := captureUpdateFlags(cmd); err != nil {
@@ -48,7 +51,8 @@ func newCASBackendUpdateOCICmd() *cobra.Command {
4851
"username": username,
4952
"password": password,
5053
},
51-
Default: isDefaultCASBackendUpdateOption,
54+
Default: isDefaultCASBackendUpdateOption,
55+
MaxBytes: parsedMaxBytes,
5256
}
5357

5458
if username == "" && password == "" {
@@ -73,5 +77,6 @@ func newCASBackendUpdateOCICmd() *cobra.Command {
7377
cmd.Flags().StringVarP(&username, "username", "u", "", "registry username")
7478

7579
cmd.Flags().StringVarP(&password, "password", "p", "", "registry password")
80+
7681
return cmd
7782
}

app/cli/cmd/casbackend_update_s3.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2024 The Chainloop Authors.
2+
// Copyright 2024-2025 The Chainloop Authors.
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -26,7 +26,10 @@ func newCASBackendUpdateAWSS3Cmd() *cobra.Command {
2626
var backendName, accessKeyID, secretAccessKey, region string
2727
cmd := &cobra.Command{
2828
Use: "aws-s3",
29-
Short: "Update a AWS S3 CAS Backend description, credentials or default status",
29+
Short: "Update a AWS S3 CAS Backend description, credentials, default status, or max bytes",
30+
PreRunE: func(_ *cobra.Command, _ []string) error {
31+
return parseMaxBytesOption()
32+
},
3033
RunE: func(cmd *cobra.Command, args []string) error {
3134
// capture flags only when explicitly set
3235
if err := captureUpdateFlags(cmd); err != nil {
@@ -49,7 +52,8 @@ func newCASBackendUpdateAWSS3Cmd() *cobra.Command {
4952
"secretAccessKey": secretAccessKey,
5053
"region": region,
5154
},
52-
Default: isDefaultCASBackendUpdateOption,
55+
Default: isDefaultCASBackendUpdateOption,
56+
MaxBytes: parsedMaxBytes,
5357
}
5458

5559
// this means that we are not updating credentials

0 commit comments

Comments
 (0)