mirror of
https://github.com/fluxcd/flux2.git
synced 2026-05-23 01:45:53 +00:00
Use single OCI layer selector flag
Signed-off-by: Dan Meier <me.daniel.meier@gmail.com> Assisted-by: Codex/gpt-5
This commit is contained in:
parent
63281daf2f
commit
57f0ac3142
3 changed files with 65 additions and 0 deletions
|
|
@ -53,6 +53,12 @@ var createSourceOCIRepositoryCmd = &cobra.Command{
|
|||
--verify-provider=cosign \
|
||||
--verify-subject="^https://github.com/stefanprodan/podinfo/.github/workflows/release.yml@refs/tags/6.6.2$" \
|
||||
--verify-issuer="^https://token.actions.githubusercontent.com$"
|
||||
|
||||
# Create an OCIRepository for a Helm chart layer
|
||||
flux create source oci valkey-cluster \
|
||||
--url=oci://example.com/charts/valkey \
|
||||
--tag=0.11.6 \
|
||||
--layer-selector=application/vnd.cncf.helm.chart.content.v1.tar+gzip:copy
|
||||
`,
|
||||
RunE: createSourceOCIRepositoryCmdRun,
|
||||
}
|
||||
|
|
@ -73,6 +79,7 @@ type sourceOCIRepositoryFlags struct {
|
|||
ignorePaths []string
|
||||
provider flags.SourceOCIProvider
|
||||
insecure bool
|
||||
layerSelector string
|
||||
}
|
||||
|
||||
var sourceOCIRepositoryArgs = newSourceOCIFlags()
|
||||
|
|
@ -99,6 +106,7 @@ func init() {
|
|||
createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.verifyOIDCIssuer, "verify-issuer", "", "regular expression to use for the OIDC issuer during signature verification")
|
||||
createSourceOCIRepositoryCmd.Flags().StringSliceVar(&sourceOCIRepositoryArgs.ignorePaths, "ignore-paths", nil, "set paths to ignore resources (can specify multiple paths with commas: path1,path2)")
|
||||
createSourceOCIRepositoryCmd.Flags().BoolVar(&sourceOCIRepositoryArgs.insecure, "insecure", false, "for when connecting to a non-TLS registries over plain HTTP")
|
||||
createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.layerSelector, "layer-selector", "", "the OCI artifact layer selector in the format '<media-type>:<operation>'")
|
||||
|
||||
createSourceCmd.AddCommand(createSourceOCIRepositoryCmd)
|
||||
}
|
||||
|
|
@ -114,6 +122,11 @@ func createSourceOCIRepositoryCmdRun(cmd *cobra.Command, args []string) error {
|
|||
return fmt.Errorf("--tag, --tag-semver or --digest is required")
|
||||
}
|
||||
|
||||
layerSelector, err := parseLayerSelector(sourceOCIRepositoryArgs.layerSelector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sourceLabels, err := parseLabels()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -152,6 +165,7 @@ func createSourceOCIRepositoryCmdRun(cmd *cobra.Command, args []string) error {
|
|||
if tag := sourceOCIRepositoryArgs.tag; tag != "" {
|
||||
repository.Spec.Reference.Tag = tag
|
||||
}
|
||||
repository.Spec.LayerSelector = layerSelector
|
||||
|
||||
if createSourceArgs.fetchTimeout > 0 {
|
||||
repository.Spec.Timeout = &metav1.Duration{Duration: createSourceArgs.fetchTimeout}
|
||||
|
|
@ -234,6 +248,28 @@ func createSourceOCIRepositoryCmdRun(cmd *cobra.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func parseLayerSelector(selector string) (*sourcev1.OCILayerSelector, error) {
|
||||
if selector == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
mediaType, operation, found := strings.Cut(selector, ":")
|
||||
if !found || mediaType == "" || operation == "" {
|
||||
return nil, fmt.Errorf("invalid --layer-selector %q: must be in the format '<media-type>:<operation>'", selector)
|
||||
}
|
||||
|
||||
switch operation {
|
||||
case sourcev1.OCILayerExtract, sourcev1.OCILayerCopy:
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid --layer-selector %q: operation must be %q or %q", selector, sourcev1.OCILayerExtract, sourcev1.OCILayerCopy)
|
||||
}
|
||||
|
||||
return &sourcev1.OCILayerSelector{
|
||||
MediaType: mediaType,
|
||||
Operation: operation,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func upsertOCIRepository(ctx context.Context, kubeClient client.Client,
|
||||
ociRepository *sourcev1.OCIRepository) (types.NamespacedName, error) {
|
||||
namespacedName := types.NamespacedName{
|
||||
|
|
|
|||
|
|
@ -81,6 +81,21 @@ func TestCreateSourceOCI(t *testing.T) {
|
|||
args: "create source oci podinfo --url=oci://ghcr.io/stefanprodan/manifests/podinfo --tag=6.3.5 --interval 10m --verify-provider=cosign --verify-secret-ref=cosign-pub --export",
|
||||
assertFunc: assertGoldenFile("./testdata/oci/export_with_verify_secret.golden"),
|
||||
},
|
||||
{
|
||||
name: "export manifest with layer selector",
|
||||
args: "create source oci podinfo --url=oci://ghcr.io/stefanprodan/manifests/podinfo --tag=6.3.5 --interval 10m --layer-selector=application/vnd.cncf.helm.chart.content.v1.tar+gzip:copy --export",
|
||||
assertFunc: assertGoldenFile("./testdata/oci/export_with_layer_selector.golden"),
|
||||
},
|
||||
{
|
||||
name: "invalid layer selector operation",
|
||||
args: "create source oci podinfo --url=oci://ghcr.io/stefanprodan/manifests/podinfo --tag=6.3.5 --layer-selector=application/vnd.cncf.helm.chart.content.v1.tar+gzip:move --export",
|
||||
assertFunc: assertError("invalid --layer-selector \"application/vnd.cncf.helm.chart.content.v1.tar+gzip:move\": operation must be \"extract\" or \"copy\""),
|
||||
},
|
||||
{
|
||||
name: "invalid layer selector format",
|
||||
args: "create source oci podinfo --url=oci://ghcr.io/stefanprodan/manifests/podinfo --tag=6.3.5 --layer-selector=application/vnd.cncf.helm.chart.content.v1.tar+gzip --export",
|
||||
assertFunc: assertError("invalid --layer-selector \"application/vnd.cncf.helm.chart.content.v1.tar+gzip\": must be in the format '<media-type>:<operation>'"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
|
|||
14
cmd/flux/testdata/oci/export_with_layer_selector.golden
vendored
Normal file
14
cmd/flux/testdata/oci/export_with_layer_selector.golden
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: OCIRepository
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 10m0s
|
||||
layerSelector:
|
||||
mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip
|
||||
operation: copy
|
||||
ref:
|
||||
tag: 6.3.5
|
||||
url: oci://ghcr.io/stefanprodan/manifests/podinfo
|
||||
Loading…
Add table
Add a link
Reference in a new issue