Skip to content

Commit

Permalink
input plugin handler
Browse files Browse the repository at this point in the history
  • Loading branch information
mandelsoft committed Dec 9, 2024
1 parent f42bff7 commit 53a8088
Show file tree
Hide file tree
Showing 24 changed files with 800 additions and 55 deletions.
2 changes: 1 addition & 1 deletion api/ocm/extensions/accessmethods/plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (p *PluginHandler) GetMimeType(spec *AccessSpec) string {
if err != nil {
return ""
}
return info.Short
return info.MediaType
}

func (p *PluginHandler) GetReferenceHint(spec *AccessSpec, cv cpi.ComponentVersionAccess) string {
Expand Down
24 changes: 24 additions & 0 deletions api/ocm/plugin/cache/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,30 @@ func (p *pluginImpl) GetLabelMergeSpecification(name, version string) *descripto
return fallback
}

func (p *pluginImpl) GetInputTypeDescriptor(name, version string) *descriptor.InputTypeDescriptor {
if !p.IsValid() {
return nil
}

var fallback descriptor.InputTypeDescriptor
fallbackFound := false
for _, i := range p.descriptor.Inputs {
if i.Name == name {
if i.Version == version {
return &i
}
if i.Version == "" || i.Version == "v1" {
fallback = i
fallbackFound = true
}
}
}
if fallbackFound && (version == "" || version == "v1") {
return &fallback
}
return nil
}

func (p *pluginImpl) GetAccessMethodDescriptor(name, version string) *descriptor.AccessMethodDescriptor {
if !p.IsValid() {
return nil
Expand Down
2 changes: 1 addition & 1 deletion api/ocm/plugin/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const (
KIND_PLUGIN = descriptor.KIND_PLUGIN
KIND_UPLOADER = descriptor.KIND_UPLOADER
KIND_ACCESSMETHOD = descriptor.KIND_ACCESSMETHOD
KIND_INPUTTYÜE = descriptor.KIND_INPUTTYPE
KIND_INPUTTYPE = descriptor.KIND_INPUTTYPE
KIND_ACTION = descriptor.KIND_ACTION
KIND_TRANSFERHANDLER = descriptor.KIND_TRANSFERHANDLER
)
Expand Down
3 changes: 1 addition & 2 deletions api/ocm/plugin/plugin_input.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/mandelsoft/goutils/errors"

"ocm.software/ocm/api/ocm/plugin/ppi"
"ocm.software/ocm/api/ocm/plugin/ppi/cmds/accessmethod"
"ocm.software/ocm/api/ocm/plugin/ppi/cmds/input"
"ocm.software/ocm/api/ocm/plugin/ppi/cmds/input/compose"
"ocm.software/ocm/api/ocm/plugin/ppi/cmds/input/get"
Expand Down Expand Up @@ -62,7 +61,7 @@ func (p *pluginImpl) ComposeInputSpec(name string, opts flagsets.ConfigOptions,
}

func (p *pluginImpl) GetInputBlob(w io.Writer, creds, spec json.RawMessage) error {
args := []string{accessmethod.Name, get.Name, string(spec)}
args := []string{input.Name, get.Name, string(spec)}
if creds != nil {
args = append(args, "--"+get.OptCreds, string(creds))
}
Expand Down
2 changes: 1 addition & 1 deletion api/ocm/plugin/ppi/cmds/input/compose/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
"github.com/mandelsoft/goutils/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"ocm.software/ocm/api/ocm/plugin/descriptor"

"ocm.software/ocm/api/ocm/extensions/accessmethods/options"
"ocm.software/ocm/api/ocm/plugin/descriptor"
"ocm.software/ocm/api/ocm/plugin/ppi"
"ocm.software/ocm/api/utils/runtime"
)
Expand Down
10 changes: 5 additions & 5 deletions api/ocm/plugin/ppi/cmds/input/validate/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"github.com/spf13/pflag"

"ocm.software/ocm/api/credentials"
"ocm.software/ocm/api/ocm/plugin/descriptor"
"ocm.software/ocm/api/ocm/plugin/ppi"
"ocm.software/ocm/api/utils/errkind"
"ocm.software/ocm/api/utils/runtime"
)

Expand Down Expand Up @@ -82,14 +82,14 @@ type Result struct {
}

func Command(p ppi.Plugin, cmd *cobra.Command, opts *Options) error {
spec, err := p.DecodeAccessSpecification(opts.Specification)
spec, err := p.DecodeInputSpecification(opts.Specification)
if err != nil {
return errors.Wrapf(err, "access specification")
return errors.Wrapf(err, "input specification")
}

m := p.GetAccessMethod(runtime.KindVersion(spec.GetType()))
m := p.GetInputType(spec.GetType())
if m == nil {
return errors.ErrUnknown(errkind.KIND_ACCESSMETHOD, spec.GetType())
return errors.ErrUnknown(descriptor.KIND_INPUTTYPE, spec.GetType())
}
info, err := m.ValidateSpecification(p, spec)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion api/ocm/plugin/ppi/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/mandelsoft/goutils/maputils"
"github.com/spf13/cobra"
"golang.org/x/exp/slices"

"ocm.software/ocm/api/config"
"ocm.software/ocm/api/datacontext/action"
metav1 "ocm.software/ocm/api/ocm/compdesc/meta/v1"
Expand Down Expand Up @@ -334,7 +335,7 @@ func (p *plugin) RegisterInputType(m InputType) error {
},
}
p.descriptor.Inputs = append(p.descriptor.Inputs, inp)
p.accessScheme.RegisterByDecoder(m.Name(), m)
p.inputScheme.RegisterByDecoder(m.Name(), m)
p.inputs[m.Name()] = m
return nil
}
Expand Down
12 changes: 9 additions & 3 deletions api/ocm/plugin/ppi/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,16 @@ func (b *AccessMethodBase) BlobProviderBase() string {

////////////////////////////////////////////////////////////////////////////////

type InputTypeBase = blobProviderBase
type InputTypeBase struct {
blobProviderBase
}

func MustNewAInputTypeBase(name string, proto InputSpec, desc string, format string) InputTypeBase {
return MustNewBlobProviderBase(name, proto, desc, format)
func MustNewInputTypeBase(name string, proto InputSpec, desc string, format string) InputTypeBase {
return InputTypeBase{MustNewBlobProviderBase(name, proto, desc, format)}
}

func (b *InputTypeBase) Format() string {
return b.format
}

////////////////////////////////////////////////////////////////////////////////
Expand Down
21 changes: 13 additions & 8 deletions api/ocm/plugin/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package plugin

import (
"encoding/json"
"io"

"github.com/opencontainers/go-digest"

Expand All @@ -10,19 +11,23 @@ import (
"ocm.software/ocm/api/utils/iotools"
)

type AccessDataWriter struct {
plugin Plugin
creds json.RawMessage
accspec json.RawMessage
type BlobAccessWriter struct {
creds json.RawMessage
spec json.RawMessage
getter func(writer io.Writer, creds json.RawMessage, spec json.RawMessage) error
}

func NewAccessDataWriter(p Plugin, creds, accspec json.RawMessage) *AccessDataWriter {
return &AccessDataWriter{p, creds, accspec}
func NewAccessDataWriter(p Plugin, creds, accspec json.RawMessage) *BlobAccessWriter {
return &BlobAccessWriter{creds, accspec, p.Get}
}

func (d *AccessDataWriter) WriteTo(w accessio.Writer) (int64, digest.Digest, error) {
func NewInputDataWriter(p Plugin, creds, accspec json.RawMessage) *BlobAccessWriter {
return &BlobAccessWriter{creds, accspec, p.GetInputBlob}
}

func (d *BlobAccessWriter) WriteTo(w accessio.Writer) (int64, digest.Digest, error) {
dw := iotools.NewDefaultDigestWriter(accessio.NopWriteCloser(w))
err := d.plugin.Get(dw, d.creds, d.accspec)
err := d.getter(dw, d.creds, d.spec)
if err != nil {
return blobaccess.BLOB_UNKNOWN_SIZE, blobaccess.BLOB_UNKNOWN_DIGEST, err
}
Expand Down
27 changes: 27 additions & 0 deletions api/utils/runtime/scheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,33 @@ func NewDefaultScheme[T TypedObject, R TypedObjectDecoder[T]](protoUnstr Unstruc
}, nil
}

type Copyable[T any] interface {
Copy() T
}

// CopyScheme copies a Copyable scheme.
// This is not a method on Scheme, because it would be propagated by embedding
// a scheme to get the traditional methods, but would return an internal
// implementation detail.
func CopyScheme[T TypedObject, R TypedObjectDecoder[T]](s Scheme[T, R]) Scheme[T, R] {
if c, ok := s.(Copyable[Scheme[T, R]]); ok {
return c.Copy()
}
return nil
}

func (d *defaultScheme[T, R]) Copy() Scheme[T, R] {
scheme := &defaultScheme[T, R]{
instance: d.instance,
unstructured: d.unstructured,
defaultdecoder: d.defaultdecoder,
acceptUnknown: d.acceptUnknown,
types: KnownTypes[T, R]{},
}
scheme.AddKnownTypes(d)
return scheme
}

func (d *defaultScheme[T, R]) BaseScheme() Scheme[T, R] {
return d.base
}
Expand Down
2 changes: 2 additions & 0 deletions cmds/ocm/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
creds "ocm.software/ocm/cmds/ocm/commands/misccmds/credentials"
"ocm.software/ocm/cmds/ocm/commands/ocicmds"
"ocm.software/ocm/cmds/ocm/commands/ocmcmds"
inputplugins "ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/plugin"
"ocm.software/ocm/cmds/ocm/commands/ocmcmds/componentarchive"
"ocm.software/ocm/cmds/ocm/commands/ocmcmds/components"
"ocm.software/ocm/cmds/ocm/commands/ocmcmds/names"
Expand Down Expand Up @@ -393,6 +394,7 @@ func (o *CLIOptions) Complete() error {
if err != nil {
return err
}
inputplugins.RegisterPlugins(o.Context)
return o.Context.ConfigContext().Validate()
}

Expand Down
120 changes: 88 additions & 32 deletions cmds/ocm/commands/ocmcmds/common/inputs/extend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
. "github.com/mandelsoft/goutils/testutils"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
clictx "ocm.software/ocm/api/cli"
"ocm.software/ocm/api/datacontext"

"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/util/validation/field"
Expand All @@ -21,45 +23,99 @@ import (

var _ = Describe("Input Type Extension Test Environment", func() {
var (
scheme = inputs.NewInputTypeScheme(nil, inputs.DefaultInputTypeScheme)
scheme inputs.InputTypeScheme
itype = inputs.NewInputType(TYPE, &Spec{}, "", ConfigHandler())
flags *pflag.FlagSet
opts flagsets.ConfigOptions
)

BeforeEach(func() {
scheme.Register(itype)
flags = &pflag.FlagSet{}
opts = scheme.CreateConfigTypeSetConfigProvider().CreateOptions()
opts.AddFlags(flags)
Context("registry", func() {
BeforeEach(func() {
scheme = inputs.NewInputTypeScheme(nil, inputs.DefaultInputTypeScheme)
scheme.Register(itype)
flags = &pflag.FlagSet{}
opts = scheme.CreateConfigTypeSetConfigProvider().CreateOptions()
opts.AddFlags(flags)
})

It("is not in base", func() {
scheme = inputs.DefaultInputTypeScheme
Expect(scheme.GetInputType(TYPE)).To(BeNil())
})

It("derives base input type", func() {
prov := scheme.CreateConfigTypeSetConfigProvider()
MustBeSuccessful(flagsets.ParseOptionsFor(flags,
flagsets.OptionSpec(prov.GetTypeOptionType(), ociartifact.TYPE),
flagsets.OptionSpec(options.PathOption, "ghcr.io/open-component-model/image:v1.0"),
flagsets.OptionSpec(options.PlatformsOption, "linux/amd64"),
flagsets.OptionSpec(options.PlatformsOption, "/arm64"),
))
cfg := Must(prov.GetConfigFor(opts))
fmt.Printf("selected input options: %+v\n", cfg)

spec := Must(scheme.GetInputSpecFor(cfg))
Expect(spec).To(Equal(ociartifact.New("ghcr.io/open-component-model/image:v1.0", "linux/amd64", "/arm64")))
})

It("uses extended input type", func() {
prov := scheme.CreateConfigTypeSetConfigProvider()
MustBeSuccessful(flagsets.ParseOptionsFor(flags,
flagsets.OptionSpec(prov.GetTypeOptionType(), TYPE),
flagsets.OptionSpec(options.PathOption, "ghcr.io/open-component-model/image:v1.0"),
))
cfg := Must(prov.GetConfigFor(opts))
fmt.Printf("selected input options: %+v\n", cfg)

spec := Must(scheme.GetInputSpecFor(cfg))
Expect(spec).To(Equal(New("ghcr.io/open-component-model/image:v1.0")))
})
})

It("derives base input type", func() {
prov := scheme.CreateConfigTypeSetConfigProvider()
MustBeSuccessful(flagsets.ParseOptionsFor(flags,
flagsets.OptionSpec(prov.GetTypeOptionType(), ociartifact.TYPE),
flagsets.OptionSpec(options.PathOption, "ghcr.io/open-component-model/image:v1.0"),
flagsets.OptionSpec(options.PlatformsOption, "linux/amd64"),
flagsets.OptionSpec(options.PlatformsOption, "/arm64"),
))
cfg := Must(prov.GetConfigFor(opts))
fmt.Printf("selected input options: %+v\n", cfg)

spec := Must(scheme.GetInputSpecFor(cfg))
Expect(spec).To(Equal(ociartifact.New("ghcr.io/open-component-model/image:v1.0", "linux/amd64", "/arm64")))
})

It("uses extended input type", func() {
prov := scheme.CreateConfigTypeSetConfigProvider()
MustBeSuccessful(flagsets.ParseOptionsFor(flags,
flagsets.OptionSpec(prov.GetTypeOptionType(), TYPE),
flagsets.OptionSpec(options.PathOption, "ghcr.io/open-component-model/image:v1.0"),
))
cfg := Must(prov.GetConfigFor(opts))
fmt.Printf("selected input options: %+v\n", cfg)

spec := Must(scheme.GetInputSpecFor(cfg))
Expect(spec).To(Equal(New("ghcr.io/open-component-model/image:v1.0")))
Context("cli context", func() {
var ctx clictx.Context

BeforeEach(func() {
ctx = clictx.New(datacontext.MODE_EXTENDED)
scheme = inputs.For(ctx)
scheme.Register(itype)
flags = &pflag.FlagSet{}
opts = scheme.CreateConfigTypeSetConfigProvider().CreateOptions()
opts.AddFlags(flags)
})

It("is not in base", func() {
scheme = inputs.For(clictx.DefaultContext())
Expect(scheme.GetInputType(TYPE)).To(BeNil())
})

It("derives base input type", func() {
prov := scheme.CreateConfigTypeSetConfigProvider()
MustBeSuccessful(flagsets.ParseOptionsFor(flags,
flagsets.OptionSpec(prov.GetTypeOptionType(), ociartifact.TYPE),
flagsets.OptionSpec(options.PathOption, "ghcr.io/open-component-model/image:v1.0"),
flagsets.OptionSpec(options.PlatformsOption, "linux/amd64"),
flagsets.OptionSpec(options.PlatformsOption, "/arm64"),
))
cfg := Must(prov.GetConfigFor(opts))
fmt.Printf("selected input options: %+v\n", cfg)

spec := Must(scheme.GetInputSpecFor(cfg))
Expect(spec).To(Equal(ociartifact.New("ghcr.io/open-component-model/image:v1.0", "linux/amd64", "/arm64")))
})

It("uses extended input type", func() {
prov := scheme.CreateConfigTypeSetConfigProvider()
MustBeSuccessful(flagsets.ParseOptionsFor(flags,
flagsets.OptionSpec(prov.GetTypeOptionType(), TYPE),
flagsets.OptionSpec(options.PathOption, "ghcr.io/open-component-model/image:v1.0"),
))
cfg := Must(prov.GetConfigFor(opts))
fmt.Printf("selected input options: %+v\n", cfg)

spec := Must(scheme.GetInputSpecFor(cfg))
Expect(spec).To(Equal(New("ghcr.io/open-component-model/image:v1.0")))
})
})
})

Expand Down
Loading

0 comments on commit 53a8088

Please sign in to comment.