-
Notifications
You must be signed in to change notification settings - Fork 24
feat: configurable preference for relative access creation for uploader #1412
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
Open
mandelsoft
wants to merge
2
commits into
open-component-model:main
Choose a base branch
from
mandelsoft:relative
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+531
−3
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package config | ||
|
||
import ( | ||
cfgcpi "ocm.software/ocm/api/config/cpi" | ||
) | ||
|
||
// GetConfigured applies config objects of a config context | ||
// to a configuration struct of type T. | ||
// A pointer to the configured struct is returned. | ||
// Attention: T must be a struct type. | ||
func GetConfigured[T any](ctxp ContextProvider) (*T, error) { | ||
var c T | ||
err := cfgcpi.NewUpdater(ctxp.ConfigContext(), &c).Update() | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &c, nil | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,11 +20,15 @@ type IntermediateRepositorySpecAspect interface { | |
IsIntermediate() bool | ||
} | ||
|
||
type UniformRepositorySpecProvider interface { | ||
UniformRepositorySpec() *UniformRepositorySpec | ||
} | ||
|
||
type RepositorySpec interface { | ||
runtime.VersionedTypedObject | ||
UniformRepositorySpecProvider | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is every Repository Spec now a Uniform Spec Provider? |
||
|
||
Name() string | ||
UniformRepositorySpec() *UniformRepositorySpec | ||
Repository(Context, credentials.Credentials) (Repository, error) | ||
|
||
Validate(Context, credentials.Credentials, ...credentials.UsageContext) error | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,66 @@ | ||||||
package preferrelativeattr | ||||||
|
||||||
import ( | ||||||
"fmt" | ||||||
|
||||||
"ocm.software/ocm/api/datacontext" | ||||||
"ocm.software/ocm/api/utils/runtime" | ||||||
) | ||||||
|
||||||
const ( | ||||||
ATTR_KEY = "github.com/mandelsoft/ocm/preferrelativeaccess" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This attribute key should be changed.
Suggested change
|
||||||
ATTR_SHORT = "preferrelativeaccess" | ||||||
) | ||||||
|
||||||
func init() { | ||||||
datacontext.RegisterAttributeType(ATTR_KEY, AttributeType{}, ATTR_SHORT) | ||||||
} | ||||||
|
||||||
type AttributeType struct{} | ||||||
|
||||||
func (a AttributeType) Name() string { | ||||||
return ATTR_KEY | ||||||
} | ||||||
|
||||||
func (a AttributeType) Description() string { | ||||||
return ` | ||||||
*bool* | ||||||
If an artifact blob is uploaded to the technical repository | ||||||
used as OCM repository, the uploader should prefer to return | ||||||
a relative access method. | ||||||
` | ||||||
} | ||||||
|
||||||
func (a AttributeType) Encode(v interface{}, marshaller runtime.Marshaler) ([]byte, error) { | ||||||
if _, ok := v.(bool); !ok { | ||||||
return nil, fmt.Errorf("boolean required") | ||||||
} | ||||||
return marshaller.Marshal(v) | ||||||
} | ||||||
|
||||||
func (a AttributeType) Decode(data []byte, unmarshaller runtime.Unmarshaler) (interface{}, error) { | ||||||
var value bool | ||||||
err := unmarshaller.Unmarshal(data, &value) | ||||||
return value, err | ||||||
} | ||||||
|
||||||
//////////////////////////////////////////////////////////////////////////////// | ||||||
|
||||||
func Get(ctx datacontext.Context) bool { | ||||||
a := ctx.GetAttributes().GetAttribute(ATTR_KEY) | ||||||
if a == nil { | ||||||
return false | ||||||
} | ||||||
return a.(bool) | ||||||
} | ||||||
|
||||||
func Set(ctx datacontext.Context, flag bool) error { | ||||||
return ctx.GetAttributes().SetAttribute(ATTR_KEY, flag) | ||||||
} | ||||||
|
||||||
func ApplyTo(ctx datacontext.Context, flag *bool) bool { | ||||||
if a := ctx.GetAttributes().GetAttribute(ATTR_KEY); a != nil { | ||||||
*flag = a.(bool) | ||||||
} | ||||||
return *flag | ||||||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package preferrelativeattr_test | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
|
||
"ocm.software/ocm/api/config" | ||
"ocm.software/ocm/api/credentials" | ||
"ocm.software/ocm/api/datacontext" | ||
"ocm.software/ocm/api/oci" | ||
"ocm.software/ocm/api/ocm" | ||
me "ocm.software/ocm/api/ocm/extensions/attrs/keepblobattr" | ||
"ocm.software/ocm/api/utils/runtime" | ||
) | ||
|
||
var _ = Describe("attribute", func() { | ||
var ctx ocm.Context | ||
var cfgctx config.Context | ||
|
||
BeforeEach(func() { | ||
cfgctx = config.WithSharedAttributes(datacontext.New(nil)).New() | ||
credctx := credentials.WithConfigs(cfgctx).New() | ||
ocictx := oci.WithCredentials(credctx).New() | ||
ctx = ocm.WithOCIRepositories(ocictx).New() | ||
}) | ||
It("local setting", func() { | ||
Expect(me.Get(ctx)).To(BeFalse()) | ||
Expect(me.Set(ctx, true)).To(Succeed()) | ||
Expect(me.Get(ctx)).To(BeTrue()) | ||
}) | ||
|
||
It("global setting", func() { | ||
Expect(me.Get(cfgctx)).To(BeFalse()) | ||
Expect(me.Set(ctx, true)).To(Succeed()) | ||
Expect(me.Get(ctx)).To(BeTrue()) | ||
}) | ||
|
||
It("parses string", func() { | ||
Expect(me.AttributeType{}.Decode([]byte("true"), runtime.DefaultJSONEncoding)).To(BeTrue()) | ||
}) | ||
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package preferrelativeattr_test | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func TestConfig(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "OCM Prefer Relative Access Attribute") | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
api/ocm/extensions/blobhandler/handlers/oci/ocirepo/config/option.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package config | ||
|
||
import ( | ||
"net" | ||
) | ||
|
||
// UploadOptions is used to configure | ||
// the implicit OCI uploader for a local OCM repository. | ||
// It can be used to request the generation of relative | ||
// OCI access methods, generally or for dedicated targets. | ||
type UploadOptions struct { | ||
// PreferRelativeAccess enables or disables the settings. | ||
PreferRelativeAccess bool `json:"preferRelativeAccess,omitempty"` | ||
// Repositories is list of repository specs, with or without port. | ||
// If no filters are configured all repos are matched. | ||
Repositories []string `json:"repositories,omitempty"` | ||
} | ||
|
||
// PreferRelativeAccessFor checks a repo spec for using | ||
// a relative access method instead of an absolute one. | ||
// It checks hostname and optionally a port name. | ||
// The most specific configuration wins. | ||
func (o *UploadOptions) PreferRelativeAccessFor(repo string) bool { | ||
if len(o.Repositories) == 0 || !o.PreferRelativeAccess { | ||
return o.PreferRelativeAccess | ||
} | ||
|
||
fallback := false | ||
|
||
host, port, err := net.SplitHostPort(repo) | ||
if err != nil { | ||
host = repo | ||
} | ||
for _, r := range o.Repositories { | ||
rhost, rport, err := net.SplitHostPort(r) | ||
if err != nil { | ||
rhost = r | ||
} | ||
if host == rhost { | ||
if rport == "" { | ||
fallback = true | ||
} | ||
if port == rport { | ||
return true | ||
} | ||
} | ||
} | ||
return fallback | ||
} |
13 changes: 13 additions & 0 deletions
13
api/ocm/extensions/blobhandler/handlers/oci/ocirepo/config/suite_test.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package config_test | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func TestConfig(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "OCI Uploader forOCI OCM Repositories Test Suite") | ||
} |
64 changes: 64 additions & 0 deletions
64
api/ocm/extensions/blobhandler/handlers/oci/ocirepo/config/type.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package config | ||
|
||
import ( | ||
"ocm.software/ocm/api/config" | ||
cfgcpi "ocm.software/ocm/api/config/cpi" | ||
"ocm.software/ocm/api/ocm/extensions/attrs/preferrelativeattr" | ||
"ocm.software/ocm/api/utils/runtime" | ||
) | ||
|
||
const ( | ||
ConfigType = "local.oci.uploader" + cfgcpi.OCM_CONFIG_TYPE_SUFFIX | ||
ConfigTypeV1 = ConfigType + runtime.VersionSeparator + "v1" | ||
) | ||
|
||
func init() { | ||
cfgcpi.RegisterConfigType(cfgcpi.NewConfigType[*Config](ConfigType, usage)) | ||
cfgcpi.RegisterConfigType(cfgcpi.NewConfigType[*Config](ConfigTypeV1)) | ||
} | ||
|
||
// Config describes a memory based config interface. | ||
type Config struct { | ||
runtime.ObjectVersionedType `json:",inline"` | ||
UploadOptions | ||
} | ||
|
||
// New creates a new memory ConfigSpec. | ||
func New() *Config { | ||
return &Config{ | ||
ObjectVersionedType: runtime.NewVersionedTypedObject(ConfigType), | ||
} | ||
} | ||
|
||
func (a *Config) ApplyTo(ctx config.Context, target interface{}) error { | ||
t, ok := target.(*UploadOptions) | ||
if !ok { | ||
return config.ErrNoContext(ConfigType) | ||
} | ||
t.Repositories = append(t.Repositories, a.Repositories...) | ||
t.PreferRelativeAccess = a.PreferRelativeAccess | ||
return nil | ||
} | ||
|
||
const usage = ` | ||
The config type <code>` + ConfigType + `</code> can be used to set some | ||
configurations for the implicit OCI artifact upload for OCI based OCM repositories. | ||
|
||
<pre> | ||
type: ` + ConfigType + ` | ||
preferRelativeAccess: true # use relative access methods for given target repositories. | ||
repositories: | ||
- localhost:5000 | ||
</pre> | ||
|
||
If <code>preferRelativeAccess</code> is set to <code>true</code> the | ||
OCI uploader for OCI based OCM repositories does not use the | ||
OCI repository to create absolute OCI access methods | ||
if the target repository is in the <code>repositories</code> list. | ||
Instead, a relative <code>relativeOciReference</code> access method | ||
is created. | ||
If this list is empty, all uploads are handled this way. | ||
|
||
If the global attribute <code>` + preferrelativeattr.ATTR_SHORT + `</code> | ||
is configured, it overrides the <code>preferRelativeAccess</code> setting. | ||
` |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is exactly one usage of this method, so I would like to keep it an internal helper