Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: oci support (Beta) #18646

Open
wants to merge 79 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
bfcb54e
feat: oci wip
blakepettersson Mar 26, 2024
b5800bf
fix: cache by project
blakepettersson Jun 13, 2024
727a1d4
fix: propagate insecurehttponly correctly from ui
blakepettersson Jun 17, 2024
443b3f1
fix: get rid of ui errors, for now
blakepettersson Jun 21, 2024
a62410e
fix: (hard) refreshes work now
blakepettersson Jun 26, 2024
1a2899f
fix: resolverevision endpoint now works correctly for oci
blakepettersson Jun 26, 2024
2aedf6f
chore: updates from master
blakepettersson Aug 22, 2024
9c9a59b
refactor: capitalize oci where applicable
blakepettersson Aug 22, 2024
baf491b
refactor: capitalize oci where applicable
blakepettersson Aug 22, 2024
e9bd698
chore: please linters
blakepettersson Aug 22, 2024
15e2bb5
chore: please linter, again
blakepettersson Aug 22, 2024
2257eb9
chore: final linter fix
blakepettersson Aug 22, 2024
61c4d46
refactor: simpler way to get the registry host
blakepettersson Aug 22, 2024
c72b30e
refactor: extract tarball from layer directly
blakepettersson Aug 23, 2024
c87d52e
chore: address (some) cr comments
blakepettersson Aug 26, 2024
c8672e7
chore: lint and tidy
blakepettersson Aug 26, 2024
893bffb
feat: metadata + oci fixes
blakepettersson Sep 6, 2024
d5b8513
chore: make codegen
blakepettersson Sep 6, 2024
a20abab
feat: display manifest metadata in ui
blakepettersson Sep 7, 2024
a3b846f
fix: tests and lint
blakepettersson Sep 7, 2024
d83e7f8
chore: lint
blakepettersson Sep 7, 2024
874a69e
chore: comments, lint, etc.
blakepettersson Sep 9, 2024
e32ffad
chore: golangci-lint --fix
blakepettersson Sep 9, 2024
a5c52df
feat: add the ability to restrict oci layer types
blakepettersson Sep 10, 2024
4cbed18
chore: go lint
blakepettersson Sep 10, 2024
9071731
docs: add user docs on how to use oci
blakepettersson Sep 11, 2024
609731e
docs: add user docs on how to use oci
blakepettersson Sep 11, 2024
6baf732
fix: always resolve digest
blakepettersson Sep 12, 2024
9ce6fd3
test: add resolverevision unit tests
blakepettersson Sep 16, 2024
fb23fba
chore: tests and lint
blakepettersson Sep 19, 2024
7c14864
chore: go mod tidy
blakepettersson Sep 19, 2024
5cfb6cd
chore: failing test + lint
blakepettersson Sep 20, 2024
5d3cb22
chore: more linting
blakepettersson Sep 20, 2024
307a782
test: add test
blakepettersson Sep 21, 2024
ca409d3
test: add testcase
blakepettersson Sep 29, 2024
a70f036
test: another test case
blakepettersson Sep 29, 2024
6992621
chore: make mockgen
blakepettersson Sep 29, 2024
9c23980
test: moar tests
blakepettersson Oct 1, 2024
3acb1ae
chore: please the linter
blakepettersson Oct 1, 2024
3f52d33
fix/refactor: unpack tar files embedded in layer
blakepettersson Oct 2, 2024
cba5230
chore: lint and rename
blakepettersson Oct 3, 2024
3e9f29a
chore: rebase + minor cleanups
blakepettersson Oct 6, 2024
7697b18
chore: remove redundant `ingest` folder
blakepettersson Oct 27, 2024
5b41ece
chore: please the linter
blakepettersson Oct 27, 2024
4a55001
chore: check to see if json file is an oci manifest
blakepettersson Oct 27, 2024
ce68a97
chore: lint
blakepettersson Oct 27, 2024
ddd25ba
test: add simple e2e test
blakepettersson Nov 21, 2024
c28cc28
chore: lint
blakepettersson Nov 25, 2024
1cc721e
test: more tests
blakepettersson Nov 26, 2024
0ed202a
fix: add support for creating oci apps in ui
blakepettersson Nov 28, 2024
c0c6bf5
fix: ui fixes
blakepettersson Nov 29, 2024
fdc2064
chore: ui lint
blakepettersson Nov 29, 2024
bf130c0
Update docs/user-guide/oci.md
blakepettersson Dec 4, 2024
5074725
chore: cr tweaks
blakepettersson Dec 10, 2024
34b4d26
refactor: rename insecure oci field to insecureOciForceHttp
blakepettersson Dec 11, 2024
b2cfb4b
chore: add more context to errors
blakepettersson Dec 11, 2024
2401008
chore: more cr fixes
blakepettersson Dec 12, 2024
95aacbb
chore: lint
blakepettersson Dec 12, 2024
7636ede
chore: lint
blakepettersson Jan 4, 2025
38b624f
feat: oci repo-creds
blakepettersson Jan 6, 2025
8f042c0
fix: build errors
blakepettersson Jan 8, 2025
df9c23f
chore: lint, again
blakepettersson Jan 9, 2025
5f13385
fix: paths within an oci image can now be specified
blakepettersson Jan 23, 2025
cd5241c
Merge branch 'master' into feature/oci
blakepettersson Jan 23, 2025
1819eb6
chore: merge fixes
blakepettersson Jan 23, 2025
87e1ab0
chore: bump argo-ui version
blakepettersson Jan 24, 2025
7659b60
chore: lint, again
blakepettersson Jan 25, 2025
b3a0081
fix: lookup explicit tag first before semver check
blakepettersson Jan 25, 2025
c487fc2
Merge branch 'master' into feature/oci
blakepettersson Feb 11, 2025
93373fc
fix: display insecure option for oci repos
blakepettersson Feb 17, 2025
0e5fc6a
Merge branch 'master' into feature/oci
blakepettersson Feb 18, 2025
274051f
fix: helm dependencies should use oci creds if available
blakepettersson Feb 20, 2025
6dd9e35
chore: lint, again
blakepettersson Feb 20, 2025
ddd611f
Merge branch 'master' into feature/oci
blakepettersson Feb 20, 2025
f6c9dbd
fix: merge conflict error
blakepettersson Feb 20, 2025
2b765f6
docs: path is in fact not optional
blakepettersson Feb 21, 2025
b3e4b49
cli: add examples and make sure generate-spec works as well
blakepettersson Feb 21, 2025
f2d1051
Merge branch 'master' into feature/oci
blakepettersson Mar 8, 2025
13de1c4
fix: e2e test fixes
blakepettersson Mar 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ install-test-tools-local:
./hack/install.sh kustomize
./hack/install.sh helm
./hack/install.sh gotestsum
./hack/install.sh oras

# Installs all tools required for running codegen (Linux packages)
.PHONY: install-codegen-tools-local
Expand Down
113 changes: 112 additions & 1 deletion assets/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 42 additions & 24 deletions cmd/argocd-repo-server/commands/argocd_repo_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os"
"os/signal"
"runtime/debug"
"strings"
"sync"
"syscall"
"time"
Expand Down Expand Up @@ -53,30 +54,33 @@ var (

func NewCommand() *cobra.Command {
var (
parallelismLimit int64
listenPort int
listenHost string
metricsPort int
metricsHost string
otlpAddress string
otlpInsecure bool
otlpHeaders map[string]string
otlpAttrs []string
cacheSrc func() (*reposervercache.Cache, error)
tlsConfigCustomizer tls.ConfigCustomizer
tlsConfigCustomizerSrc func() (tls.ConfigCustomizer, error)
redisClient *redis.Client
disableTLS bool
maxCombinedDirectoryManifestsSize string
cmpTarExcludedGlobs []string
allowOutOfBoundsSymlinks bool
streamedManifestMaxTarSize string
streamedManifestMaxExtractedSize string
helmManifestMaxExtractedSize string
helmRegistryMaxIndexSize string
disableManifestMaxExtractedSize bool
includeHiddenDirectories bool
cmpUseManifestGeneratePaths bool
parallelismLimit int64
listenPort int
listenHost string
metricsPort int
metricsHost string
otlpAddress string
otlpInsecure bool
otlpHeaders map[string]string
otlpAttrs []string
cacheSrc func() (*reposervercache.Cache, error)
tlsConfigCustomizer tls.ConfigCustomizer
tlsConfigCustomizerSrc func() (tls.ConfigCustomizer, error)
redisClient *redis.Client
disableTLS bool
maxCombinedDirectoryManifestsSize string
cmpTarExcludedGlobs []string
allowOutOfBoundsSymlinks bool
streamedManifestMaxTarSize string
streamedManifestMaxExtractedSize string
helmManifestMaxExtractedSize string
helmRegistryMaxIndexSize string
ociManifestMaxExtractedSize string
disableOCIManifestMaxExtractedSize bool
disableManifestMaxExtractedSize bool
includeHiddenDirectories bool
cmpUseManifestGeneratePaths bool
ociLayerMediaTypes string
)
command := cobra.Command{
Use: cliName,
Expand Down Expand Up @@ -125,9 +129,17 @@ func NewCommand() *cobra.Command {
helmManifestMaxExtractedSizeQuantity, err := resource.ParseQuantity(helmManifestMaxExtractedSize)
errors.CheckError(err)

ociManifestMaxExtractedSizeQuantity, err := resource.ParseQuantity(ociManifestMaxExtractedSize)
errors.CheckError(err)

helmRegistryMaxIndexSizeQuantity, err := resource.ParseQuantity(helmRegistryMaxIndexSize)
errors.CheckError(err)

var ociMediaTypesList []string
if ociLayerMediaTypes != "" {
ociMediaTypesList = strings.Split(ociLayerMediaTypes, ";")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually I saw comma is being used instead of semicolon in such cases.
Is there a reason for choosing semicolon specifically?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No specific reason, when @alexmt initially added api-content-types he used semicolon as a separator, and for this param I decided to go with the same convention.

}

askPassServer := askpass.NewServer(askpass.SocketPath)
metricsServer := metrics.NewMetricsServer()
cacheutil.CollectMetrics(redisClient, metricsServer, nil)
Expand All @@ -144,8 +156,11 @@ func NewCommand() *cobra.Command {
StreamedManifestMaxTarSize: streamedManifestMaxTarSizeQuantity.ToDec().Value(),
HelmManifestMaxExtractedSize: helmManifestMaxExtractedSizeQuantity.ToDec().Value(),
HelmRegistryMaxIndexSize: helmRegistryMaxIndexSizeQuantity.ToDec().Value(),
OCIManifestMaxExtractedSize: ociManifestMaxExtractedSizeQuantity.ToDec().Value(),
DisableOCIManifestMaxExtractedSize: disableOCIManifestMaxExtractedSize,
IncludeHiddenDirectories: includeHiddenDirectories,
CMPUseManifestGeneratePaths: cmpUseManifestGeneratePaths,
OCIMediaTypes: ociMediaTypesList,
}, askPassServer)
errors.CheckError(err)

Expand Down Expand Up @@ -249,9 +264,12 @@ func NewCommand() *cobra.Command {
command.Flags().StringVar(&streamedManifestMaxExtractedSize, "streamed-manifest-max-extracted-size", env.StringFromEnv("ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_EXTRACTED_SIZE", "1G"), "Maximum size of streamed manifest archives when extracted")
command.Flags().StringVar(&helmManifestMaxExtractedSize, "helm-manifest-max-extracted-size", env.StringFromEnv("ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE", "1G"), "Maximum size of helm manifest archives when extracted")
command.Flags().StringVar(&helmRegistryMaxIndexSize, "helm-registry-max-index-size", env.StringFromEnv("ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_INDEX_SIZE", "1G"), "Maximum size of registry index file")
command.Flags().StringVar(&ociManifestMaxExtractedSize, "oci-manifest-max-extracted-size", env.StringFromEnv("ARGOCD_REPO_SERVER_OCI_MANIFEST_MAX_EXTRACTED_SIZE", "1G"), "Maximum size of oci manifest archives when extracted")
command.Flags().BoolVar(&disableOCIManifestMaxExtractedSize, "disable-oci-manifest-max-extracted-size", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_DISABLE_OCI_MANIFEST_MAX_EXTRACTED_SIZE", false), "Disable maximum size of oci manifest archives when extracted")
command.Flags().BoolVar(&disableManifestMaxExtractedSize, "disable-helm-manifest-max-extracted-size", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE", false), "Disable maximum size of helm manifest archives when extracted")
command.Flags().BoolVar(&includeHiddenDirectories, "include-hidden-directories", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_INCLUDE_HIDDEN_DIRECTORIES", false), "Include hidden directories from Git")
command.Flags().BoolVar(&cmpUseManifestGeneratePaths, "plugin-use-manifest-generate-paths", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS", false), "Pass the resources described in argocd.argoproj.io/manifest-generate-paths value to the cmpserver to generate the application manifests.")
command.Flags().StringVar(&ociLayerMediaTypes, "oci-layer-media-types", env.StringFromEnv("ARGOCD_REPO_SERVER_OCI_LAYER_MEDIA_TYPES", "application/vnd.oci.image.layer.v1.tar;application/vnd.oci.image.layer.v1.tar+gzip;application/vnd.cncf.helm.chart.content.v1.tar+gzip"), "Semicolon separated list of allowed media types for OCI media types. This only accounts for media types within layers.")
tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(&command)
cacheSrc = reposervercache.AddCacheFlagsToCmd(&command, cacheutil.Options{
OnClientCreated: func(client *redis.Client) {
Expand Down
10 changes: 10 additions & 0 deletions cmd/argocd/commands/admin/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ func NewGenRepoSpecCommand() *cobra.Command {

# Add a private Helm OCI-based repository named 'stable' via HTTPS
argocd admin repo generate-spec helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type helm --name stable --enable-oci --username test --password test

# Add a private HTTPS OCI repository named 'stable'
argocd repo generate-spec oci://helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type oci --name stable --username test --password test

# Add a private OCI repository named 'stable' without verifying the server's TLS certificate
argocd repo generate-spec oci://helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type oci --name stable --username test --password test --insecure-skip-server-verification

# Add a private HTTP OCI repository named 'stable'
argocd repo generate-spec oci://helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type oci --name stable --username test --password test --insecure-oci-force-http
`

command := &cobra.Command{
Expand Down Expand Up @@ -130,6 +139,7 @@ func NewGenRepoSpecCommand() *cobra.Command {
repoOpts.Repo.EnableLFS = repoOpts.EnableLfs
repoOpts.Repo.EnableOCI = repoOpts.EnableOci
repoOpts.Repo.UseAzureWorkloadIdentity = repoOpts.UseAzureWorkloadIdentity
repoOpts.Repo.InsecureOCIForceHttp = repoOpts.InsecureOCIForceHTTP

if repoOpts.Repo.Type == "helm" && repoOpts.Repo.Name == "" {
errors.CheckError(stderrors.New("must specify --name for repos of type 'helm'"))
Expand Down
4 changes: 4 additions & 0 deletions cmd/argocd/commands/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,10 @@ func (c *fakeAppServiceClient) GetApplicationSyncWindows(_ context.Context, _ *a
return nil, nil
}

func (c *fakeAppServiceClient) GetOCIMetadata(_ context.Context, _ *applicationpkg.RevisionMetadataQuery, _ ...grpc.CallOption) (*v1alpha1.OCIMetadata, error) {
return nil, nil
}

func (c *fakeAppServiceClient) RevisionMetadata(_ context.Context, _ *applicationpkg.RevisionMetadataQuery, _ ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error) {
return nil, nil
}
Expand Down
16 changes: 15 additions & 1 deletion cmd/argocd/commands/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {

# Add a private Helm OCI-based repository named 'stable' via HTTPS
argocd repo add helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type helm --name stable --enable-oci --username test --password test

# Add a private HTTPS OCI repository named 'stable'
argocd repo add oci://helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type oci --name stable --username test --password test

# Add a private OCI repository named 'stable' without verifying the server's TLS certificate
argocd repo add oci://helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type oci --name stable --username test --password test --insecure-skip-server-verification

# Add a private HTTP OCI repository named 'stable'
argocd repo add oci://helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type oci --name stable --username test --password test --insecure-oci-force-http

# Add a private Git repository on GitHub.com via GitHub App
argocd repo add https://git.example.com/repos/repo --github-app-id 1 --github-app-installation-id 2 --github-app-private-key-path test.private-key.pem
Expand Down Expand Up @@ -188,6 +197,10 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
errors.CheckError(stderrors.New("Must specify --name for repos of type 'helm'"))
}

if repoOpts.Repo.Type == "oci" && repoOpts.InsecureOCIForceHTTP {
repoOpts.Repo.InsecureOCIForceHttp = repoOpts.InsecureOCIForceHTTP
}

conn, repoIf := headless.NewClientOrDie(clientOpts, c).NewRepoClientOrDie()
defer io.Close(conn)

Expand All @@ -205,7 +218,7 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
errors.CheckError(err)

// We let the server check access to the repository before adding it. If
// it is a private repo, but we cannot access with with the credentials
// it is a private repo, but we cannot access with the credentials
// that were supplied, we bail out.
//
// Skip validation if we are just adding credentials template, chances
Expand All @@ -232,6 +245,7 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
GcpServiceAccountKey: repoOpts.Repo.GCPServiceAccountKey,
ForceHttpBasicAuth: repoOpts.Repo.ForceHttpBasicAuth,
UseAzureWorkloadIdentity: repoOpts.Repo.UseAzureWorkloadIdentity,
InsecureOciForceHttp: repoOpts.Repo.InsecureOCIForceHttp,
}
_, err = repoIf.ValidateAccess(ctx, &repoAccessReq)
errors.CheckError(err)
Expand Down
6 changes: 4 additions & 2 deletions cmd/util/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type RepoOptions struct {
Repo appsv1.Repository
Upsert bool
SshPrivateKeyPath string //nolint:revive //FIXME(var-naming)
InsecureOCIForceHTTP bool
InsecureIgnoreHostKey bool
InsecureSkipServerVerification bool
TlsClientCertPath string //nolint:revive //FIXME(var-naming)
Expand All @@ -29,7 +30,7 @@ type RepoOptions struct {
}

func AddRepoFlags(command *cobra.Command, opts *RepoOptions) {
command.Flags().StringVar(&opts.Repo.Type, "type", common.DefaultRepoType, "type of the repository, \"git\" or \"helm\"")
command.Flags().StringVar(&opts.Repo.Type, "type", common.DefaultRepoType, "type of the repository, \"git\", \"oci\" or \"helm\"")
command.Flags().StringVar(&opts.Repo.Name, "name", "", "name of the repository, mandatory for repositories of type helm")
command.Flags().StringVar(&opts.Repo.Project, "project", "", "project of the repository")
command.Flags().StringVar(&opts.Repo.Username, "username", "", "username to the repository")
Expand All @@ -41,7 +42,7 @@ func AddRepoFlags(command *cobra.Command, opts *RepoOptions) {
command.Flags().BoolVar(&opts.InsecureIgnoreHostKey, "insecure-ignore-host-key", false, "disables SSH strict host key checking (deprecated, use --insecure-skip-server-verification instead)")
command.Flags().BoolVar(&opts.InsecureSkipServerVerification, "insecure-skip-server-verification", false, "disables server certificate and host key checks")
command.Flags().BoolVar(&opts.EnableLfs, "enable-lfs", false, "enable git-lfs (Large File Support) on this repository")
command.Flags().BoolVar(&opts.EnableOci, "enable-oci", false, "enable helm-oci (Helm OCI-Based Repository)")
command.Flags().BoolVar(&opts.EnableOci, "enable-oci", false, "enable helm-oci (Helm OCI-Based Repository) (only valid for helm type repositories)")
command.Flags().Int64Var(&opts.GithubAppId, "github-app-id", 0, "id of the GitHub Application")
command.Flags().Int64Var(&opts.GithubAppInstallationId, "github-app-installation-id", 0, "installation id of the GitHub Application")
command.Flags().StringVar(&opts.GithubAppPrivateKeyPath, "github-app-private-key-path", "", "private key of the GitHub Application")
Expand All @@ -51,4 +52,5 @@ func AddRepoFlags(command *cobra.Command, opts *RepoOptions) {
command.Flags().StringVar(&opts.GCPServiceAccountKeyPath, "gcp-service-account-key-path", "", "service account key for the Google Cloud Platform")
command.Flags().BoolVar(&opts.ForceHttpBasicAuth, "force-http-basic-auth", false, "whether to force use of basic auth when connecting repository via HTTP")
command.Flags().BoolVar(&opts.UseAzureWorkloadIdentity, "use-azure-workload-identity", false, "whether to use azure workload identity for authentication")
command.Flags().BoolVar(&opts.InsecureOCIForceHTTP, "insecure-oci-force-http", false, "Use http when accessing an OCI repository")
}
Loading
Loading