diff --git a/cmds/ocm/commands/ocmcmds/common/options/rscbyvalueoption/option.go b/cmds/ocm/commands/ocmcmds/common/options/rscbyvalueoption/option.go index b2598c73bd..4e31bd103f 100644 --- a/cmds/ocm/commands/ocmcmds/common/options/rscbyvalueoption/option.go +++ b/cmds/ocm/commands/ocmcmds/common/options/rscbyvalueoption/option.go @@ -24,25 +24,32 @@ func New() *Option { type Option struct { ResourcesByValue bool + LocalByValue bool } var _ transferhandler.TransferOption = (*Option)(nil) func (o *Option) AddFlags(fs *pflag.FlagSet) { fs.BoolVarP(&o.ResourcesByValue, "copy-resources", "V", false, "transfer referenced resources by-value") + fs.BoolVarP(&o.LocalByValue, "copy-local-resources", "L", false, "transfer referenced local resources by-value") } func (o *Option) Usage() string { s := ` It the option --copy-resources is given, all referential resources will potentially be localized, mapped to component version local -resources in the target repository. -This behaviour can be further influenced by specifying a transfer script -with the script option family. +resources in the target repository. It the option --copy-local-resources +is given, instead, only resources with the relation local will be +transferred. This behaviour can be further influenced by specifying a transfer +script with the script option family. ` return s } func (o *Option) ApplyTransferOption(opts transferhandler.TransferOptions) error { - return standard.ResourcesByValue(o.ResourcesByValue).ApplyTransferOption(opts) + err := standard.ResourcesByValue(o.ResourcesByValue).ApplyTransferOption(opts) + if err == nil { + err = standard.LocalResourcesByValue(o.LocalByValue).ApplyTransferOption(opts) + } + return err } diff --git a/cmds/ocm/commands/ocmcmds/componentarchive/transfer/cmd.go b/cmds/ocm/commands/ocmcmds/componentarchive/transfer/cmd.go index 3bff6e69d8..8d3eb60f68 100644 --- a/cmds/ocm/commands/ocmcmds/componentarchive/transfer/cmd.go +++ b/cmds/ocm/commands/ocmcmds/componentarchive/transfer/cmd.go @@ -8,6 +8,11 @@ import ( "github.com/spf13/cobra" "github.com/open-component-model/ocm/cmds/ocm/commands/common/options/formatoption" + ocmcommon "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common" + "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/options/lookupoption" + "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/options/overwriteoption" + "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/options/rscbyvalueoption" + "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/options/srcbyvalueoption" "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/names" "github.com/open-component-model/ocm/cmds/ocm/commands/verbs" "github.com/open-component-model/ocm/cmds/ocm/pkg/utils" @@ -17,6 +22,7 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/comparch" "github.com/open-component-model/ocm/pkg/contexts/ocm/transfer" + "github.com/open-component-model/ocm/pkg/contexts/ocm/transfer/transferhandler/standard" ) var ( @@ -32,7 +38,7 @@ type Command struct { // NewCommand creates a new transfer command. func NewCommand(ctx clictx.Context, names ...string) *cobra.Command { - return utils.SetupCommand(&Command{BaseCommand: utils.NewBaseCommand(ctx, formatoption.New())}, utils.Names(Names, names...)...) + return utils.SetupCommand(&Command{BaseCommand: utils.NewBaseCommand(ctx, formatoption.New(), lookupoption.New(), overwriteoption.New(), rscbyvalueoption.New(), srcbyvalueoption.New())}, utils.Names(Names, names...)...) } func (o *Command) ForName(name string) *cobra.Command { @@ -62,6 +68,13 @@ func (o *Command) Complete(args []string) error { func (o *Command) Run() error { session := ocm.NewSession(nil) defer session.Close() + session.Finalize(o.OCMContext()) + + err := o.ProcessOnOptions(ocmcommon.CompleteOptionsWithSession(o, session)) + if err != nil { + return err + } + source, err := comparch.Open(o.Context.OCMContext(), accessobj.ACC_READONLY, o.Path, 0, o.Context) if err != nil { return err @@ -74,5 +87,14 @@ func (o *Command) Run() error { return err } - return transfer.TransferVersion(common.NewPrinter(o.Context.StdOut()), nil, source, target, nil) + thdlr, err := standard.New( + lookupoption.From(o), + overwriteoption.From(o), + rscbyvalueoption.From(o), + srcbyvalueoption.From(o), + ) + if err != nil { + return err + } + return transfer.TransferVersion(common.NewPrinter(o.Context.StdOut()), nil, source, target, thdlr) } diff --git a/docs/reference/ocm_add_componentversions.md b/docs/reference/ocm_add_componentversions.md index a8ca5130a7..d82a34b56b 100644 --- a/docs/reference/ocm_add_componentversions.md +++ b/docs/reference/ocm_add_componentversions.md @@ -11,6 +11,7 @@ ocm add componentversions [] [--version ] [] {--copy-resources is given, all referential resources will potentially be localized, mapped to component version local -resources in the target repository. -This behaviour can be further influenced by specifying a transfer script -with the script option family. +resources in the target repository. It the option --copy-local-resources +is given, instead, only resources with the relation local will be +transferred. This behaviour can be further influenced by specifying a transfer +script with the script option family. ### Examples diff --git a/docs/reference/ocm_logging.md b/docs/reference/ocm_logging.md index 6c0ce36885..f5035d3de4 100644 --- a/docs/reference/ocm_logging.md +++ b/docs/reference/ocm_logging.md @@ -22,6 +22,7 @@ The following *realms* are used by the command line tool: - ocm/accessmethod/ociartifact: access method ociArtifact - ocm/credentials/dockerconfig: docker config handling as credential repository - ocm/oci.ocireg: OCI repository handling + - ocm/ocimapping: OCM to OCI Registry Mapping - ocm/plugins: OCM plugin handling - ocm/processing: output processing chains - ocm/toi: TOI logging diff --git a/docs/reference/ocm_transfer_commontransportarchive.md b/docs/reference/ocm_transfer_commontransportarchive.md index 9d3e840cbe..9499d830e4 100644 --- a/docs/reference/ocm_transfer_commontransportarchive.md +++ b/docs/reference/ocm_transfer_commontransportarchive.md @@ -9,6 +9,7 @@ ocm transfer commontransportarchive [] ### Options ``` + -L, --copy-local-resources transfer referenced local resources by-value -V, --copy-resources transfer referenced resources by-value -h, --help help for commontransportarchive --lookup stringArray repository name or spec for closure lookup fallback @@ -51,9 +52,10 @@ target repository will be overwritten, if they already exist. It the option --copy-resources is given, all referential resources will potentially be localized, mapped to component version local -resources in the target repository. -This behaviour can be further influenced by specifying a transfer script -with the script option family. +resources in the target repository. It the option --copy-local-resources +is given, instead, only resources with the relation local will be +transferred. This behaviour can be further influenced by specifying a transfer +script with the script option family. It the option --stop-on-existing is given together with the --recursive option, the recursion is stopped for component versions already existing in the diff --git a/docs/reference/ocm_transfer_componentarchive.md b/docs/reference/ocm_transfer_componentarchive.md index 55a3c8d5bd..eb2b19a437 100644 --- a/docs/reference/ocm_transfer_componentarchive.md +++ b/docs/reference/ocm_transfer_componentarchive.md @@ -9,8 +9,13 @@ ocm transfer componentarchive [] ### Options ``` - -h, --help help for componentarchive - -t, --type string archive format (directory, tar, tgz) (default "directory") + -L, --copy-local-resources transfer referenced local resources by-value + -V, --copy-resources transfer referenced resources by-value + --copy-sources transfer referenced sources by-value + -h, --help help for componentarchive + --lookup stringArray repository name or spec for closure lookup fallback + -f, --overwrite overwrite existing component versions + -t, --type string archive format (directory, tar, tgz) (default "directory") ``` ### Description @@ -32,6 +37,32 @@ target archive to use. The following formats are supported: The default format is directory. +If a component lookup for building a reference closure is required +the --lookup option can be used to specify a fallback +lookup repository. +By default the component versions are searched in the repository +holding the component version for which the closure is determined. +For *Component Archives* this is never possible, because it only +contains a single component version. Therefore, in this scenario +this option must always be specified to be able to follow component +references. + +It the option --overwrite is given, component version in the +target repository will be overwritten, if they already exist. + +It the option --copy-resources is given, all referential +resources will potentially be localized, mapped to component version local +resources in the target repository. It the option --copy-local-resources +is given, instead, only resources with the relation local will be +transferred. This behaviour can be further influenced by specifying a transfer +script with the script option family. + +It the option --copy-sources is given, all referential +sources will potentially be localized, mapped to component version local +resources in the target repository. +This behaviour can be further influenced by specifying a transfer script +with the script option family. + ### SEE ALSO diff --git a/docs/reference/ocm_transfer_componentversions.md b/docs/reference/ocm_transfer_componentversions.md index 005330c556..fb987e6845 100644 --- a/docs/reference/ocm_transfer_componentversions.md +++ b/docs/reference/ocm_transfer_componentversions.md @@ -10,6 +10,7 @@ ocm transfer componentversions [] {} ``` -c, --constraints constraints version constraint + -L, --copy-local-resources transfer referenced local resources by-value -V, --copy-resources transfer referenced resources by-value -h, --help help for componentversions --latest restrict component versions to latest @@ -105,9 +106,10 @@ target repository will be overwritten, if they already exist. It the option --copy-resources is given, all referential resources will potentially be localized, mapped to component version local -resources in the target repository. -This behaviour can be further influenced by specifying a transfer script -with the script option family. +resources in the target repository. It the option --copy-local-resources +is given, instead, only resources with the relation local will be +transferred. This behaviour can be further influenced by specifying a transfer +script with the script option family. It the option --stop-on-existing is given together with the --recursive option, the recursion is stopped for component versions already existing in the diff --git a/pkg/contexts/ocm/compdesc/versions/ocm.software/v3alpha1/jsonscheme/bindata.go b/pkg/contexts/ocm/compdesc/versions/ocm.software/v3alpha1/jsonscheme/bindata.go index 7acd101ea3..ae047676ee 100644 --- a/pkg/contexts/ocm/compdesc/versions/ocm.software/v3alpha1/jsonscheme/bindata.go +++ b/pkg/contexts/ocm/compdesc/versions/ocm.software/v3alpha1/jsonscheme/bindata.go @@ -1,6 +1,7 @@ // Code generated by go-bindata. (@generated) DO NOT EDIT. -//Package jsonscheme generated by go-bindata.// sources: +// Package jsonscheme generated by go-bindata. +// sources: // ../../../../../../../../resources/component-descriptor-ocm-v3-schema.yaml package jsonscheme @@ -93,7 +94,7 @@ func ResourcesComponentDescriptorOcmV3SchemaYaml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../../../../../../../../resources/component-descriptor-ocm-v3-schema.yaml", size: 10672, mode: os.FileMode(420), modTime: time.Unix(1677572043, 0)} + info := bindataFileInfo{name: "../../../../../../../../resources/component-descriptor-ocm-v3-schema.yaml", size: 10672, mode: os.FileMode(436), modTime: time.Unix(1680963832, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -102,8 +103,8 @@ func ResourcesComponentDescriptorOcmV3SchemaYaml() (*asset, error) { // It returns an error if the asset could not be found or // could not be loaded. func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { a, err := f() if err != nil { return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) @@ -128,8 +129,8 @@ func MustAsset(name string) []byte { // It returns an error if the asset could not be found or // could not be loaded. func AssetInfo(name string) (os.FileInfo, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { a, err := f() if err != nil { return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) @@ -166,13 +167,13 @@ var _bindata = map[string]func() (*asset, error){ // // then AssetDir("data") would return []string{"foo.txt", "img"} // AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("notexist") would return an error +// AssetDir("foo.txt") and AssetDir("nonexistent") would return an error // AssetDir("") will return []string{"data"}. func AssetDir(name string) ([]string, error) { node := _bintree if len(name) != 0 { - cannonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(cannonicalName, "/") + canonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(canonicalName, "/") for _, p := range pathList { node = node.Children[p] if node == nil { @@ -260,6 +261,6 @@ func RestoreAssets(dir, name string) error { } func _filePath(dir, name string) string { - cannonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) + canonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...) } diff --git a/pkg/contexts/ocm/compdesc/versions/v2/jsonscheme/bindata.go b/pkg/contexts/ocm/compdesc/versions/v2/jsonscheme/bindata.go index c487c91f5b..a8cd37fe49 100644 --- a/pkg/contexts/ocm/compdesc/versions/v2/jsonscheme/bindata.go +++ b/pkg/contexts/ocm/compdesc/versions/v2/jsonscheme/bindata.go @@ -1,6 +1,7 @@ // Code generated by go-bindata. (@generated) DO NOT EDIT. -//Package jsonscheme generated by go-bindata.// sources: +// Package jsonscheme generated by go-bindata. +// sources: // ../../../../../../../resources/component-descriptor-v2-schema.yaml package jsonscheme @@ -93,7 +94,7 @@ func ResourcesComponentDescriptorV2SchemaYaml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../../../../../../../resources/component-descriptor-v2-schema.yaml", size: 10448, mode: os.FileMode(420), modTime: time.Unix(1677572043, 0)} + info := bindataFileInfo{name: "../../../../../../../resources/component-descriptor-v2-schema.yaml", size: 10448, mode: os.FileMode(436), modTime: time.Unix(1680963832, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -102,8 +103,8 @@ func ResourcesComponentDescriptorV2SchemaYaml() (*asset, error) { // It returns an error if the asset could not be found or // could not be loaded. func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { a, err := f() if err != nil { return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) @@ -128,8 +129,8 @@ func MustAsset(name string) []byte { // It returns an error if the asset could not be found or // could not be loaded. func AssetInfo(name string) (os.FileInfo, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { a, err := f() if err != nil { return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) @@ -166,13 +167,13 @@ var _bindata = map[string]func() (*asset, error){ // // then AssetDir("data") would return []string{"foo.txt", "img"} // AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("notexist") would return an error +// AssetDir("foo.txt") and AssetDir("nonexistent") would return an error // AssetDir("") will return []string{"data"}. func AssetDir(name string) ([]string, error) { node := _bintree if len(name) != 0 { - cannonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(cannonicalName, "/") + canonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(canonicalName, "/") for _, p := range pathList { node = node.Children[p] if node == nil { @@ -258,6 +259,6 @@ func RestoreAssets(dir, name string) error { } func _filePath(dir, name string) string { - cannonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) + canonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...) } diff --git a/pkg/contexts/ocm/transfer/transferhandler/standard/handler.go b/pkg/contexts/ocm/transfer/transferhandler/standard/handler.go index 215bca67d1..5acc61d633 100644 --- a/pkg/contexts/ocm/transfer/transferhandler/standard/handler.go +++ b/pkg/contexts/ocm/transfer/transferhandler/standard/handler.go @@ -8,6 +8,7 @@ import ( "github.com/open-component-model/ocm/pkg/common/accessio" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" + metav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" "github.com/open-component-model/ocm/pkg/contexts/ocm/transfer/transferhandler" "github.com/open-component-model/ocm/pkg/errors" ) @@ -51,6 +52,11 @@ func (h *Handler) TransferVersion(repo ocm.Repository, src ocm.ComponentVersionA } func (h *Handler) TransferResource(src ocm.ComponentVersionAccess, a ocm.AccessSpec, r ocm.ResourceAccess) (bool, error) { + if h.opts.IsLocalResourcesByValue() { + if r.Meta().Relation == metav1.LocalRelation { + return true, nil + } + } return h.opts.IsResourcesByValue(), nil } diff --git a/pkg/contexts/ocm/transfer/transferhandler/standard/options.go b/pkg/contexts/ocm/transfer/transferhandler/standard/options.go index ac7254f98a..302ade1090 100644 --- a/pkg/contexts/ocm/transfer/transferhandler/standard/options.go +++ b/pkg/contexts/ocm/transfer/transferhandler/standard/options.go @@ -14,6 +14,7 @@ import ( type Options struct { recursive bool resourcesByValue bool + localByValue bool sourcesByValue bool keepGlobalAccess bool stopOnExisting bool @@ -22,11 +23,12 @@ type Options struct { } var ( - _ ResourcesByValueOption = (*Options)(nil) - _ SourcesByValueOption = (*Options)(nil) - _ RecursiveOption = (*Options)(nil) - _ ResolverOption = (*Options)(nil) - _ KeepGlobalAccessOption = (*Options)(nil) + _ ResourcesByValueOption = (*Options)(nil) + _ LocalResourcesByValueOption = (*Options)(nil) + _ SourcesByValueOption = (*Options)(nil) + _ RecursiveOption = (*Options)(nil) + _ ResolverOption = (*Options)(nil) + _ KeepGlobalAccessOption = (*Options)(nil) ) func (o *Options) SetOverwrite(overwrite bool) { @@ -53,6 +55,14 @@ func (o *Options) IsResourcesByValue() bool { return o.resourcesByValue } +func (o *Options) SetLocalResourcesByValue(resourcesByValue bool) { + o.localByValue = resourcesByValue +} + +func (o *Options) IsLocalResourcesByValue() bool { + return o.localByValue +} + func (o *Options) SetSourcesByValue(sourcesByValue bool) { o.sourcesByValue = sourcesByValue } @@ -144,6 +154,11 @@ type ResourcesByValueOption interface { IsResourcesByValue() bool } +type LocalResourcesByValueOption interface { + SetLocalResourcesByValue(bool) + IsLocalResourcesByValue() bool +} + type resourcesByValueOption struct { flag bool } @@ -163,6 +178,25 @@ func ResourcesByValue(args ...bool) transferhandler.TransferOption { } } +type intrscsByValueOption struct { + flag bool +} + +func (o *intrscsByValueOption) ApplyTransferOption(to transferhandler.TransferOptions) error { + if eff, ok := to.(LocalResourcesByValueOption); ok { + eff.SetLocalResourcesByValue(o.flag) + return nil + } else { + return errors.ErrNotSupported("resources by-value") + } +} + +func LocalResourcesByValue(args ...bool) transferhandler.TransferOption { + return &intrscsByValueOption{ + flag: utils.GetOptionFlag(args...), + } +} + /////////////////////////////////////////////////////////////////////////////// type SourcesByValueOption interface {