diff --git a/client.go b/client.go index 505704985..a369ab96c 100644 --- a/client.go +++ b/client.go @@ -21,7 +21,6 @@ import ( "context" "encoding/json" "fmt" - "runtime" "strconv" "strings" "sync" @@ -52,7 +51,7 @@ import ( "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/pkg/dialer" "github.com/containerd/containerd/platforms" - "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/remotes" "github.com/containerd/containerd/remotes/docker" @@ -185,7 +184,7 @@ func NewWithConn(conn *grpc.ClientConn, opts ...ClientOpt) (*Client, error) { c := &Client{ defaultns: copts.defaultns, conn: conn, - runtime: plugin.RuntimePlugin.String() + "." + runtime.GOOS, + runtime: defaults.DefaultRuntime, } if copts.defaultPlatform != nil { @@ -826,7 +825,7 @@ func (c *Client) getSnapshotter(ctx context.Context, name string) (snapshots.Sna // GetSnapshotterSupportedPlatforms returns a platform matchers which represents the // supported platforms for the given snapshotters func (c *Client) GetSnapshotterSupportedPlatforms(ctx context.Context, snapshotterName string) (platforms.MatchComparer, error) { - filters := []string{fmt.Sprintf("type==%s, id==%s", plugin.SnapshotPlugin, snapshotterName)} + filters := []string{fmt.Sprintf("type==%s, id==%s", plugins.SnapshotPlugin, snapshotterName)} in := c.IntrospectionService() resp, err := in.Plugins(ctx, filters) @@ -857,7 +856,7 @@ func toPlatforms(pt []*apitypes.Platform) []ocispec.Platform { // GetSnapshotterCapabilities returns the capabilities of a snapshotter. func (c *Client) GetSnapshotterCapabilities(ctx context.Context, snapshotterName string) ([]string, error) { - filters := []string{fmt.Sprintf("type==%s, id==%s", plugin.SnapshotPlugin, snapshotterName)} + filters := []string{fmt.Sprintf("type==%s, id==%s", plugins.SnapshotPlugin, snapshotterName)} in := c.IntrospectionService() resp, err := in.Plugins(ctx, filters) diff --git a/cmd/containerd-stress/main.go b/cmd/containerd-stress/main.go index 731e5eaed..af36c1850 100644 --- a/cmd/containerd-stress/main.go +++ b/cmd/containerd-stress/main.go @@ -31,7 +31,7 @@ import ( "github.com/containerd/containerd" "github.com/containerd/containerd/integration/remote" "github.com/containerd/containerd/namespaces" - "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" "github.com/containerd/log" metrics "github.com/docker/go-metrics" "github.com/urfave/cli" @@ -167,7 +167,7 @@ func main() { cli.StringFlag{ Name: "runtime", Usage: "Set the runtime to stress test", - Value: plugin.RuntimeRuncV2, + Value: plugins.RuntimeRuncV2, }, cli.StringFlag{ Name: "snapshotter", diff --git a/cmd/containerd/builtins/builtins_freebsd.go b/cmd/containerd/builtins/builtins_freebsd.go index c7fdbe190..cfc7cb767 100644 --- a/cmd/containerd/builtins/builtins_freebsd.go +++ b/cmd/containerd/builtins/builtins_freebsd.go @@ -16,4 +16,6 @@ package builtins -import _ "github.com/containerd/zfs/plugin" +// Temporarily removed while plugin package is moved, to be added back +// before 2.0. +//import _ "github.com/containerd/zfs/plugin" diff --git a/cmd/containerd/builtins/zfs_linux.go b/cmd/containerd/builtins/zfs_linux.go index 5cd0869d1..51150486d 100644 --- a/cmd/containerd/builtins/zfs_linux.go +++ b/cmd/containerd/builtins/zfs_linux.go @@ -18,4 +18,8 @@ package builtins -import _ "github.com/containerd/zfs/plugin" +// zfs snapshotter is temporarily removed until it is updated to use the +// new plugin package. In the future, the external plugin package will +// make it easier to update zfs and containerd independently without +// the dependency loop. Add back before 2.0 release. +//import _ "github.com/containerd/zfs/plugin" diff --git a/cmd/containerd/command/config.go b/cmd/containerd/command/config.go index 633e73147..db5183085 100644 --- a/cmd/containerd/command/config.go +++ b/cmd/containerd/command/config.go @@ -24,7 +24,7 @@ import ( "github.com/containerd/containerd/defaults" "github.com/containerd/containerd/images" "github.com/containerd/containerd/pkg/timeout" - "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" "github.com/containerd/containerd/services/server" srvconfig "github.com/containerd/containerd/services/server/config" ocispec "github.com/opencontainers/image-spec/specs-go/v1" @@ -46,7 +46,7 @@ func outputConfig(ctx gocontext.Context, config *srvconfig.Config) error { continue } - pc, err := config.Decode(ctx, p) + pc, err := config.Decode(ctx, p.URI(), p.Config) if err != nil { return err } @@ -113,7 +113,7 @@ var configCommand = cli.Command{ } if config.Version < srvconfig.CurrentConfigVersion { - plugins := plugin.Graph(srvconfig.V2DisabledFilter(config.DisabledPlugins)) + plugins := registry.Graph(srvconfig.V2DisabledFilter(config.DisabledPlugins)) for _, p := range plugins { if p.ConfigMigration != nil { if err := p.ConfigMigration(ctx, config.Version, config.Plugins); err != nil { diff --git a/diff/lcow/lcow.go b/diff/lcow/lcow.go index afa5217d7..e4b7afe71 100644 --- a/diff/lcow/lcow.go +++ b/diff/lcow/lcow.go @@ -36,6 +36,8 @@ import ( "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/log" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" @@ -47,14 +49,14 @@ const ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.DiffPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.DiffPlugin, ID: "windows-lcow", Requires: []plugin.Type{ - plugin.MetadataPlugin, + plugins.MetadataPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - md, err := ic.Get(plugin.MetadataPlugin) + md, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } diff --git a/diff/walking/plugin/plugin.go b/diff/walking/plugin/plugin.go index a2dcc1094..40456ee96 100644 --- a/diff/walking/plugin/plugin.go +++ b/diff/walking/plugin/plugin.go @@ -23,17 +23,19 @@ import ( "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.DiffPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.DiffPlugin, ID: "walking", Requires: []plugin.Type{ - plugin.MetadataPlugin, + plugins.MetadataPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - md, err := ic.Get(plugin.MetadataPlugin) + md, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } diff --git a/diff/windows/windows.go b/diff/windows/windows.go index 2669c955b..2aeb2eded 100644 --- a/diff/windows/windows.go +++ b/diff/windows/windows.go @@ -39,20 +39,22 @@ import ( "github.com/containerd/containerd/pkg/epoch" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/log" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.DiffPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.DiffPlugin, ID: "windows", Requires: []plugin.Type{ - plugin.MetadataPlugin, + plugins.MetadataPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - md, err := ic.Get(plugin.MetadataPlugin) + md, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } diff --git a/events/plugin/plugin.go b/events/plugin/plugin.go index dee9438ba..ed89fc68b 100644 --- a/events/plugin/plugin.go +++ b/events/plugin/plugin.go @@ -19,11 +19,13 @@ package plugin import ( "github.com/containerd/containerd/events/exchange" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.EventPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.EventPlugin, ID: "exchange", InitFn: func(ic *plugin.InitContext) (interface{}, error) { return exchange.NewExchange(), nil diff --git a/gc/scheduler/scheduler.go b/gc/scheduler/scheduler.go index 51656c09b..525f1dfe0 100644 --- a/gc/scheduler/scheduler.go +++ b/gc/scheduler/scheduler.go @@ -25,6 +25,8 @@ import ( "github.com/containerd/containerd/gc" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/log" ) @@ -96,11 +98,11 @@ func (d duration) MarshalText() (text []byte, err error) { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GCPlugin, ID: "scheduler", Requires: []plugin.Type{ - plugin.MetadataPlugin, + plugins.MetadataPlugin, }, Config: &config{ PauseThreshold: 0.02, @@ -110,14 +112,14 @@ func init() { StartupDelay: duration(100 * time.Millisecond), }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - md, err := ic.Get(plugin.MetadataPlugin) + md, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } mdCollector, ok := md.(collector) if !ok { - return nil, fmt.Errorf("%s %T must implement collector", plugin.MetadataPlugin, md) + return nil, fmt.Errorf("%s %T must implement collector", plugins.MetadataPlugin, md) } m := newScheduler(mdCollector, ic.Config.(*config)) diff --git a/go.mod b/go.mod index 4c58be906..97b31620a 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,6 @@ require ( github.com/containerd/nri v0.5.0 github.com/containerd/ttrpc v1.2.2 github.com/containerd/typeurl/v2 v2.1.1 - github.com/containerd/zfs v1.2.0 github.com/containernetworking/cni v1.1.2 github.com/containernetworking/plugins v1.3.0 github.com/coreos/go-systemd/v22 v22.5.0 @@ -103,7 +102,6 @@ require ( github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect - github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect diff --git a/go.sum b/go.sum index e10aa4e6e..891017fd3 100644 --- a/go.sum +++ b/go.sum @@ -295,8 +295,6 @@ github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQ github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= -github.com/containerd/zfs v1.2.0 h1:AtAkI6CIAtBV1Pu5/06r4fsHv9JQwZOt/NoKdhSi4qA= -github.com/containerd/zfs v1.2.0/go.mod h1:NinsnukMVY2SnwkJzrEhXzDDPdJ3Ok5LnGjblu1nfmI= github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= @@ -693,8 +691,6 @@ github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WT github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= -github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU= -github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= diff --git a/integration/build_local_containerd_helper_test.go b/integration/build_local_containerd_helper_test.go index b395980cd..c493b6df0 100644 --- a/integration/build_local_containerd_helper_test.go +++ b/integration/build_local_containerd_helper_test.go @@ -26,6 +26,7 @@ import ( "github.com/containerd/containerd/pkg/cri/constants" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" ctrdsrv "github.com/containerd/containerd/services/server" srvconfig "github.com/containerd/containerd/services/server/config" "github.com/containerd/log/logtest" @@ -54,7 +55,7 @@ import ( var ( loadPluginOnce sync.Once - loadedPlugins []*plugin.Registration + loadedPlugins []plugin.Registration loadedPluginsErr error ) @@ -88,15 +89,16 @@ func buildLocalContainerdClient(t *testing.T, tmpDir string) *containerd.Client for _, p := range loadedPlugins { initContext := plugin.NewContext( ctx, - p, initialized, - config.Root, - config.State, + map[string]string{ + plugins.PropertyRootDir: filepath.Join(config.Root, p.URI()), + plugins.PropertyStateDir: filepath.Join(config.State, p.URI()), + }, ) // load the plugin specific configuration if it is provided if p.Config != nil { - pc, err := config.Decode(ctx, p) + pc, err := config.Decode(ctx, p.URI(), p.Config) assert.NoError(t, err) initContext.Config = pc diff --git a/integration/client/container_linux_test.go b/integration/client/container_linux_test.go index 19fd7aa2f..82a1c1fd7 100644 --- a/integration/client/container_linux_test.go +++ b/integration/client/container_linux_test.go @@ -38,7 +38,7 @@ import ( "github.com/containerd/containerd/containers" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/oci" - "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/runtime/v2/runc/options" "github.com/containerd/containerd/sys" @@ -1028,7 +1028,7 @@ func TestContainerRuntimeOptionsv2(t *testing.T) { ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withExitStatus(7)), - WithRuntime(plugin.RuntimeRuncV2, &options.Options{BinaryName: "no-runc"}), + WithRuntime(plugins.RuntimeRuncV2, &options.Options{BinaryName: "no-runc"}), ) if err != nil { t.Fatal(err) diff --git a/integration/client/container_test.go b/integration/client/container_test.go index 5b4d16b4d..ade0dc2dd 100644 --- a/integration/client/container_test.go +++ b/integration/client/container_test.go @@ -39,7 +39,7 @@ import ( "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/oci" "github.com/containerd/containerd/platforms" - "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" gogotypes "github.com/containerd/containerd/protobuf/types" _ "github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime/v2/runc/options" @@ -172,7 +172,7 @@ func TestContainerStart(t *testing.T) { } func readShimPath(taskID string) (string, error) { - runtime := plugin.RuntimePluginV2.String() + ".task" + runtime := plugins.RuntimePluginV2.String() + ".task" shimBinaryNamePath := filepath.Join(defaultState, runtime, testNamespace, taskID, "shim-binary-path") shimPath, err := os.ReadFile(shimBinaryNamePath) diff --git a/integration/client/daemon_config_linux_test.go b/integration/client/daemon_config_linux_test.go index f45d619b8..611c9e61c 100644 --- a/integration/client/daemon_config_linux_test.go +++ b/integration/client/daemon_config_linux_test.go @@ -29,7 +29,7 @@ import ( "github.com/containerd/cgroups/v3" . "github.com/containerd/containerd" "github.com/containerd/containerd/oci" - "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/runtime/v2/runc/options" ) @@ -55,7 +55,7 @@ version = 2 } id := t.Name() - container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("top")), WithRuntime(plugin.RuntimeRuncV2, &options.Options{ + container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("top")), WithRuntime(plugins.RuntimeRuncV2, &options.Options{ Root: runtimeRoot, })) if err != nil { diff --git a/integration/client/go.sum b/integration/client/go.sum index abf557616..3e63529d1 100644 --- a/integration/client/go.sum +++ b/integration/client/go.sum @@ -760,7 +760,6 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= -github.com/Microsoft/hcsshim v0.9.6/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= github.com/Microsoft/hcsshim v0.9.9/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= github.com/Microsoft/hcsshim v0.12.0-rc.0 h1:wX/F5huJxH9APBkhKSEAqaiZsuBvbbDnyBROZAqsSaY= github.com/Microsoft/hcsshim v0.12.0-rc.0/go.mod h1:rvOnw3YlfoNnEp45wReUngvsXbwRW+AFQ10GVjG1kMU= @@ -873,7 +872,6 @@ github.com/container-orchestrated-devices/container-device-interface v0.6.1/go.m github.com/containerd/btrfs/v2 v2.0.0/go.mod h1:swkD/7j9HApWpzl8OHfrHNxppPd9l44DFZdF94BUj9k= github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= -github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0= github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE= @@ -882,7 +880,6 @@ github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4q github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/containerd/continuity v0.4.1/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= @@ -911,7 +908,6 @@ github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izU github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4= github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0= -github.com/containerd/zfs v1.2.0/go.mod h1:NinsnukMVY2SnwkJzrEhXzDDPdJ3Ok5LnGjblu1nfmI= github.com/containernetworking/cni v1.1.1/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= github.com/containernetworking/plugins v1.3.0/go.mod h1:Pc2wcedTQQCVuROOOaLBPPxrEXqqXBFt3cZ+/yVg6l0= @@ -1195,7 +1191,6 @@ github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JV github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -1366,7 +1361,6 @@ github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WT github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -1454,7 +1448,6 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= @@ -2068,7 +2061,6 @@ golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2572,7 +2564,6 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/integration/failpoint/cmd/containerd-shim-runc-fp-v1/plugin_linux.go b/integration/failpoint/cmd/containerd-shim-runc-fp-v1/plugin_linux.go index 2781d71fb..a9a3d3501 100644 --- a/integration/failpoint/cmd/containerd-shim-runc-fp-v1/plugin_linux.go +++ b/integration/failpoint/cmd/containerd-shim-runc-fp-v1/plugin_linux.go @@ -28,6 +28,8 @@ import ( "github.com/containerd/containerd/pkg/failpoint" "github.com/containerd/containerd/pkg/shutdown" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/runtime/v2/runc/task" "github.com/containerd/containerd/runtime/v2/shim" "github.com/containerd/ttrpc" @@ -38,19 +40,19 @@ const ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.TTRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.TTRPCPlugin, ID: "task", Requires: []plugin.Type{ - plugin.EventPlugin, - plugin.InternalPlugin, + plugins.EventPlugin, + plugins.InternalPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - pp, err := ic.GetByID(plugin.EventPlugin, "publisher") + pp, err := ic.GetByID(plugins.EventPlugin, "publisher") if err != nil { return nil, err } - ss, err := ic.GetByID(plugin.InternalPlugin, "shutdown") + ss, err := ic.GetByID(plugins.InternalPlugin, "shutdown") if err != nil { return nil, err } diff --git a/leases/plugin/local.go b/leases/plugin/local.go index fb59c26d1..dbb6fc127 100644 --- a/leases/plugin/local.go +++ b/leases/plugin/local.go @@ -23,22 +23,24 @@ import ( "github.com/containerd/containerd/leases" "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.LeasePlugin, + registry.Register(&plugin.Registration{ + Type: plugins.LeasePlugin, ID: "manager", Requires: []plugin.Type{ - plugin.MetadataPlugin, - plugin.GCPlugin, + plugins.MetadataPlugin, + plugins.GCPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - m, err := ic.Get(plugin.MetadataPlugin) + m, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } - g, err := ic.Get(plugin.GCPlugin) + g, err := ic.Get(plugins.GCPlugin) if err != nil { return nil, err } diff --git a/metadata/plugin/plugin.go b/metadata/plugin/plugin.go index 02c56806c..3871e9b98 100644 --- a/metadata/plugin/plugin.go +++ b/metadata/plugin/plugin.go @@ -28,6 +28,8 @@ import ( "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/pkg/timeout" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/snapshots" "github.com/containerd/log" @@ -81,27 +83,28 @@ func (bc *BoltConfig) Validate() error { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.MetadataPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.MetadataPlugin, ID: "bolt", Requires: []plugin.Type{ - plugin.ContentPlugin, - plugin.EventPlugin, - plugin.SnapshotPlugin, + plugins.ContentPlugin, + plugins.EventPlugin, + plugins.SnapshotPlugin, }, Config: &BoltConfig{ ContentSharingPolicy: SharingPolicyShared, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - if err := os.MkdirAll(ic.Root, 0711); err != nil { + root := ic.Properties[plugins.PropertyRootDir] + if err := os.MkdirAll(root, 0711); err != nil { return nil, err } - cs, err := ic.Get(plugin.ContentPlugin) + cs, err := ic.Get(plugins.ContentPlugin) if err != nil { return nil, err } - snapshottersRaw, err := ic.GetByType(plugin.SnapshotPlugin) + snapshottersRaw, err := ic.GetByType(plugins.SnapshotPlugin) if err != nil { return nil, err } @@ -119,7 +122,7 @@ func init() { snapshotters[name] = sn.(snapshots.Snapshotter) } - ep, err := ic.Get(plugin.EventPlugin) + ep, err := ic.Get(plugins.EventPlugin) if err != nil { return nil, err } @@ -140,7 +143,7 @@ func init() { } } - path := filepath.Join(ic.Root, "meta.db") + path := filepath.Join(root, "meta.db") ic.Meta.Exports["path"] = path options := *bolt.DefaultOptions diff --git a/metrics/cgroups/cgroups.go b/metrics/cgroups/cgroups.go index 313743757..d84ff5c1a 100644 --- a/metrics/cgroups/cgroups.go +++ b/metrics/cgroups/cgroups.go @@ -25,6 +25,8 @@ import ( v2 "github.com/containerd/containerd/metrics/cgroups/v2" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/runtime" metrics "github.com/docker/go-metrics" ) @@ -35,12 +37,12 @@ type Config struct { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.TaskMonitorPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.TaskMonitorPlugin, ID: "cgroups", InitFn: New, Requires: []plugin.Type{ - plugin.EventPlugin, + plugins.EventPlugin, }, Config: &Config{}, }) @@ -58,7 +60,7 @@ func New(ic *plugin.InitContext) (interface{}, error) { err error ) - ep, err := ic.Get(plugin.EventPlugin) + ep, err := ic.Get(plugins.EventPlugin) if err != nil { return nil, err } diff --git a/pkg/cri/cri.go b/pkg/cri/cri.go index b432ae3fa..ac44981bf 100644 --- a/pkg/cri/cri.go +++ b/pkg/cri/cri.go @@ -27,6 +27,8 @@ import ( nriservice "github.com/containerd/containerd/pkg/nri" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/log" imagespec "github.com/opencontainers/image-spec/specs-go/v1" "k8s.io/klog/v2" @@ -38,14 +40,14 @@ import ( // Register CRI service plugin func init() { config := criconfig.DefaultConfig() - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "cri", Config: &config, Requires: []plugin.Type{ - plugin.EventPlugin, - plugin.ServicePlugin, - plugin.NRIApiPlugin, + plugins.EventPlugin, + plugins.ServicePlugin, + plugins.NRIApiPlugin, }, InitFn: initCRIService, }) @@ -62,10 +64,10 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) { c := criconfig.Config{ PluginConfig: *pluginConfig, - ContainerdRootDir: filepath.Dir(ic.Root), - ContainerdEndpoint: ic.Address, - RootDir: ic.Root, - StateDir: ic.State, + ContainerdRootDir: filepath.Dir(ic.Properties[plugins.PropertyRootDir]), + ContainerdEndpoint: ic.Properties[plugins.PropertyGRPCAddress], + RootDir: ic.Properties[plugins.PropertyRootDir], + StateDir: ic.Properties[plugins.PropertyStateDir], } log.G(ctx).Infof("Start cri plugin with config %+v", c) @@ -125,7 +127,7 @@ func setGLogLevel() error { // Get the NRI plugin, and set up our NRI API for it. func getNRIAPI(ic *plugin.InitContext) *nri.API { const ( - pluginType = plugin.NRIApiPlugin + pluginType = plugins.NRIApiPlugin pluginName = "nri" ) diff --git a/pkg/cri/server/helpers.go b/pkg/cri/server/helpers.go index 45f8460cb..127107535 100644 --- a/pkg/cri/server/helpers.go +++ b/pkg/cri/server/helpers.go @@ -41,7 +41,7 @@ import ( containerstore "github.com/containerd/containerd/pkg/cri/store/container" imagestore "github.com/containerd/containerd/pkg/cri/store/image" runtimeoptions "github.com/containerd/containerd/pkg/runtimeoptions/v1" - "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" runcoptions "github.com/containerd/containerd/runtime/v2/runc/options" "github.com/containerd/log" ) @@ -289,7 +289,7 @@ func generateRuntimeOptions(r criconfig.Runtime) (interface{}, error) { // getRuntimeOptionsType gets empty runtime options by the runtime type name. func getRuntimeOptionsType(t string) interface{} { switch t { - case plugin.RuntimeRuncV2: + case plugins.RuntimeRuncV2: return &runcoptions.Options{} case runtimeRunhcsV1: return &runhcsoptions.Options{} diff --git a/pkg/cri/server/helpers_test.go b/pkg/cri/server/helpers_test.go index 5e58ef12a..648b9a64f 100644 --- a/pkg/cri/server/helpers_test.go +++ b/pkg/cri/server/helpers_test.go @@ -30,7 +30,7 @@ import ( "github.com/containerd/containerd/oci" criconfig "github.com/containerd/containerd/pkg/cri/config" containerstore "github.com/containerd/containerd/pkg/cri/store/container" - "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/protobuf/types" runcoptions "github.com/containerd/containerd/runtime/v2/runc/options" "github.com/containerd/typeurl/v2" @@ -119,7 +119,7 @@ systemd_cgroup = true no_pivot = true default_runtime_name = "default" [containerd.runtimes.runcv2] - runtime_type = "` + plugin.RuntimeRuncV2 + `" + runtime_type = "` + plugins.RuntimeRuncV2 + `" ` nonNilOpts := ` systemd_cgroup = true @@ -134,7 +134,7 @@ systemd_cgroup = true Root = "/runc" NoNewKeyring = true [containerd.runtimes.runcv2] - runtime_type = "` + plugin.RuntimeRuncV2 + `" + runtime_type = "` + plugins.RuntimeRuncV2 + `" [containerd.runtimes.runcv2.options] BinaryName = "runc" Root = "/runcv2" diff --git a/pkg/cri/server/runtime_config_linux_test.go b/pkg/cri/server/runtime_config_linux_test.go index 035f88593..d712b6025 100644 --- a/pkg/cri/server/runtime_config_linux_test.go +++ b/pkg/cri/server/runtime_config_linux_test.go @@ -22,7 +22,7 @@ import ( criconfig "github.com/containerd/containerd/pkg/cri/config" "github.com/containerd/containerd/pkg/systemd" - "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" "github.com/stretchr/testify/assert" runtime "k8s.io/cri-api/pkg/apis/runtime/v1" ) @@ -30,7 +30,7 @@ import ( func newFakeRuntimeConfig(runcV2, systemdCgroup bool) criconfig.Runtime { r := criconfig.Runtime{Type: "default", Options: map[string]interface{}{}} if runcV2 { - r.Type = plugin.RuntimeRuncV2 + r.Type = plugins.RuntimeRuncV2 if systemdCgroup { r.Options["SystemdCgroup"] = true } diff --git a/pkg/cri/server/service.go b/pkg/cri/server/service.go index 4ebc4e36d..fde22c8bf 100644 --- a/pkg/cri/server/service.go +++ b/pkg/cri/server/service.go @@ -36,7 +36,7 @@ import ( imagestore "github.com/containerd/containerd/pkg/cri/store/image" snapshotstore "github.com/containerd/containerd/pkg/cri/store/snapshot" "github.com/containerd/containerd/pkg/cri/streaming" - "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/sandbox" "github.com/containerd/go-cni" "github.com/containerd/log" @@ -350,7 +350,7 @@ func (c *criService) register(s *grpc.Server) error { // imageFSPath returns containerd image filesystem path. // Note that if containerd changes directory layout, we also needs to change this. func imageFSPath(rootDir, snapshotter string) string { - return filepath.Join(rootDir, plugin.SnapshotPlugin.String()+"."+snapshotter) + return filepath.Join(rootDir, plugins.SnapshotPlugin.String()+"."+snapshotter) } func loadOCISpec(filename string) (*oci.Spec, error) { diff --git a/pkg/nri/plugin/plugin.go b/pkg/nri/plugin/plugin.go index a2fc30e59..3a9bdea39 100644 --- a/pkg/nri/plugin/plugin.go +++ b/pkg/nri/plugin/plugin.go @@ -19,11 +19,13 @@ package plugin import ( "github.com/containerd/containerd/pkg/nri" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.NRIApiPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.NRIApiPlugin, ID: "nri", Config: nri.DefaultConfig(), InitFn: initFunc, diff --git a/plugin/context.go b/plugin/context.go index f2ae149c9..de4457cb0 100644 --- a/plugin/context.go +++ b/plugin/context.go @@ -19,20 +19,15 @@ package plugin import ( "context" "fmt" - "path/filepath" - "github.com/containerd/containerd/errdefs" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" + imagespec "github.com/opencontainers/image-spec/specs-go/v1" ) // InitContext is used for plugin initialization type InitContext struct { Context context.Context - Root string - State string + Properties map[string]string Config interface{} - Address string - TTRPCAddress string RegisterReadiness func() func() // Meta is metadata plugins can fill in at init @@ -42,11 +37,13 @@ type InitContext struct { } // NewContext returns a new plugin InitContext -func NewContext(ctx context.Context, r *Registration, plugins *Set, root, state string) *InitContext { +func NewContext(ctx context.Context, plugins *Set, properties map[string]string) *InitContext { + if properties == nil { + properties = map[string]string{} + } return &InitContext{ - Context: ctx, - Root: filepath.Join(root, r.URI()), - State: filepath.Join(state, r.URI()), + Context: ctx, + Properties: properties, Meta: &Meta{ Exports: map[string]string{}, }, @@ -62,16 +59,16 @@ func (i *InitContext) Get(t Type) (interface{}, error) { // Meta contains information gathered from the registration and initialization // process. type Meta struct { - Platforms []ocispec.Platform // platforms supported by plugin - Exports map[string]string // values exported by plugin - Capabilities []string // feature switches for plugin + Platforms []imagespec.Platform // platforms supported by plugin + Exports map[string]string // values exported by plugin + Capabilities []string // feature switches for plugin } // Plugin represents an initialized plugin, used with an init context. type Plugin struct { - Registration *Registration // registration, as initialized - Config interface{} // config, as initialized - Meta *Meta + Registration Registration // registration, as initialized + Config interface{} // config, as initialized + Meta Meta instance interface{} err error // will be set if there was an error initializing the plugin @@ -115,7 +112,7 @@ func (ps *Set) Add(p *Plugin) error { } else if _, idok := byID[p.Registration.ID]; !idok { byID[p.Registration.ID] = p } else { - return fmt.Errorf("plugin %v already initialized: %w", p.Registration.URI(), errdefs.ErrAlreadyExists) + return fmt.Errorf("plugin add failed for %s: %w", p.Registration.URI(), ErrPluginInitialized) } ps.ordered = append(ps.ordered, p) @@ -127,7 +124,7 @@ func (ps *Set) Get(t Type) (interface{}, error) { for _, v := range ps.byTypeAndID[t] { return v.Instance() } - return nil, fmt.Errorf("no plugins registered for %s: %w", t, errdefs.ErrNotFound) + return nil, fmt.Errorf("no plugins registered for %s: %w", t, ErrPluginNotFound) } // GetAll returns all initialized plugins @@ -153,7 +150,7 @@ func (i *InitContext) GetByID(t Type, id string) (interface{}, error) { } p, ok := ps[id] if !ok { - return nil, fmt.Errorf("no %s plugins with id %s: %w", t, id, errdefs.ErrNotFound) + return nil, fmt.Errorf("no %s plugins with id %s: %w", t, id, ErrPluginNotFound) } return p.Instance() } @@ -162,7 +159,7 @@ func (i *InitContext) GetByID(t Type, id string) (interface{}, error) { func (i *InitContext) GetByType(t Type) (map[string]*Plugin, error) { p, ok := i.plugins.byTypeAndID[t] if !ok { - return nil, fmt.Errorf("no plugins registered for %s: %w", t, errdefs.ErrNotFound) + return nil, fmt.Errorf("no plugins registered for %s: %w", t, ErrPluginNotFound) } return p, nil diff --git a/plugin/dynamic/dynamic.go b/plugin/dynamic/dynamic.go new file mode 100644 index 000000000..30b4423a1 --- /dev/null +++ b/plugin/dynamic/dynamic.go @@ -0,0 +1,37 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package dynamic + +import "fmt" + +// Load loads all plugins at the provided path into containerd. +// +// Load is currently only implemented on non-static, non-gccgo builds for amd64 +// and arm64, and plugins must be built with the exact same version of Go as +// containerd itself. +func Load(path string) (err error) { + defer func() { + if v := recover(); v != nil { + rerr, ok := v.(error) + if !ok { + rerr = fmt.Errorf("%s", v) + } + err = rerr + } + }() + return loadPlugins(path) +} diff --git a/plugin/plugin_supported.go b/plugin/dynamic/dynamic_supported.go similarity index 98% rename from plugin/plugin_supported.go rename to plugin/dynamic/dynamic_supported.go index 0eaf47064..eff7e597f 100644 --- a/plugin/plugin_supported.go +++ b/plugin/dynamic/dynamic_supported.go @@ -16,7 +16,7 @@ limitations under the License. */ -package plugin +package dynamic import ( "fmt" diff --git a/plugin/plugin_unsupported.go b/plugin/dynamic/dynamic_unsupported.go similarity index 98% rename from plugin/plugin_unsupported.go rename to plugin/dynamic/dynamic_unsupported.go index b250be357..ccef3d37f 100644 --- a/plugin/plugin_unsupported.go +++ b/plugin/dynamic/dynamic_unsupported.go @@ -16,7 +16,7 @@ limitations under the License. */ -package plugin +package dynamic // loadPlugins is not supported; // diff --git a/plugin/plugin.go b/plugin/plugin.go index 37864f023..d68c5013a 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -20,7 +20,6 @@ import ( "context" "errors" "fmt" - "sync" ) var ( @@ -34,6 +33,10 @@ var ( // this allows the plugin loader differentiate between a plugin which is configured // not to load and one that fails to load. ErrSkipPlugin = errors.New("skip plugin") + // ErrPluginInitialized is used when a plugin is already initialized + ErrPluginInitialized = errors.New("plugin: already initialized") + // ErrPluginNotFound is used when a plugin is looked up but not found + ErrPluginNotFound = errors.New("plugin: not found") // ErrInvalidRequires will be thrown if the requirements for a plugin are // defined in an invalid manner. @@ -50,56 +53,6 @@ type Type string func (t Type) String() string { return string(t) } -const ( - // InternalPlugin implements an internal plugin to containerd - InternalPlugin Type = "io.containerd.internal.v1" - // RuntimePlugin implements a runtime - RuntimePlugin Type = "io.containerd.runtime.v1" - // RuntimePluginV2 implements a runtime v2 - RuntimePluginV2 Type = "io.containerd.runtime.v2" - // ServicePlugin implements a internal service - ServicePlugin Type = "io.containerd.service.v1" - // GRPCPlugin implements a grpc service - GRPCPlugin Type = "io.containerd.grpc.v1" - // TTRPCPlugin implements a ttrpc shim service - TTRPCPlugin Type = "io.containerd.ttrpc.v1" - // SnapshotPlugin implements a snapshotter - SnapshotPlugin Type = "io.containerd.snapshotter.v1" - // TaskMonitorPlugin implements a task monitor - TaskMonitorPlugin Type = "io.containerd.monitor.v1" - // DiffPlugin implements a differ - DiffPlugin Type = "io.containerd.differ.v1" - // MetadataPlugin implements a metadata store - MetadataPlugin Type = "io.containerd.metadata.v1" - // ContentPlugin implements a content store - ContentPlugin Type = "io.containerd.content.v1" - // GCPlugin implements garbage collection policy - GCPlugin Type = "io.containerd.gc.v1" - // EventPlugin implements event handling - EventPlugin Type = "io.containerd.event.v1" - // LeasePlugin implements lease manager - LeasePlugin Type = "io.containerd.lease.v1" - // StreamingPlugin implements a stream manager - StreamingPlugin Type = "io.containerd.streaming.v1" - // TracingProcessorPlugin implements a open telemetry span processor - TracingProcessorPlugin Type = "io.containerd.tracing.processor.v1" - // NRIApiPlugin implements the NRI adaptation interface for containerd. - NRIApiPlugin Type = "io.containerd.nri.v1" - // TransferPlugin implements a transfer service - TransferPlugin Type = "io.containerd.transfer.v1" - // SandboxStorePlugin implements a sandbox store - SandboxStorePlugin Type = "io.containerd.sandbox.store.v1" - // SandboxControllerPlugin implements a sandbox controller - SandboxControllerPlugin Type = "io.containerd.sandbox.controller.v1" - // ImageVerifierPlugin implements an image verifier service - ImageVerifierPlugin Type = "io.containerd.image-verifier.v1" -) - -const ( - // RuntimeRuncV2 is the runc runtime that supports multiple containers per shim - RuntimeRuncV2 = "io.containerd.runc.v2" -) - // Registration contains information for registering a plugin type Registration struct { // Type of the plugin @@ -115,8 +68,6 @@ type Registration struct { // context are passed in. The init function may modify the registration to // add exports, capabilities and platform support declarations. InitFn func(*InitContext) (interface{}, error) - // Disable the plugin from loading - Disable bool // ConfigMigration allows a plugin to migrate configurations from an older // version to handle plugin renames or moving of features from one plugin @@ -129,12 +80,12 @@ type Registration struct { } // Init the registered plugin -func (r *Registration) Init(ic *InitContext) *Plugin { +func (r Registration) Init(ic *InitContext) *Plugin { p, err := r.InitFn(ic) return &Plugin{ Registration: r, Config: ic.Config, - Meta: ic.Meta, + Meta: *ic.Meta, instance: p, err: err, } @@ -145,41 +96,64 @@ func (r *Registration) URI() string { return r.Type.String() + "." + r.ID } -var register = struct { - sync.RWMutex - r []*Registration -}{} +// DisableFilter filters out disabled plugins +type DisableFilter func(r *Registration) bool -// Load loads all plugins at the provided path into containerd. -// -// Load is currently only implemented on non-static, non-gccgo builds for amd64 -// and arm64, and plugins must be built with the exact same version of Go as -// containerd itself. -func Load(path string) (err error) { - defer func() { - if v := recover(); v != nil { - rerr, ok := v.(error) - if !ok { - rerr = fmt.Errorf("%s", v) - } - err = rerr +// Registry is list of registrations which can be registered to and +// produce a filtered and ordered output. +// The Registry itself is immutable and the list will be copied +// and appeneded to a new registry when new items are registered. +type Registry []*Registration + +// Graph computes the ordered list of registrations based on their dependencies, +// filtering out any plugins which match the provided filter. +func (registry Registry) Graph(filter DisableFilter) []Registration { + disabled := map[*Registration]bool{} + for _, r := range registry { + if filter(r) { + disabled[r] = true } - }() - return loadPlugins(path) + } + + ordered := make([]Registration, 0, len(registry)-len(disabled)) + added := map[*Registration]bool{} + for _, r := range registry { + if disabled[r] { + continue + } + children(r, registry, added, disabled, &ordered) + if !added[r] { + ordered = append(ordered, *r) + added[r] = true + } + } + return ordered } -// Register allows plugins to register -func Register(r *Registration) { - register.Lock() - defer register.Unlock() +func children(reg *Registration, registry []*Registration, added, disabled map[*Registration]bool, ordered *[]Registration) { + for _, t := range reg.Requires { + for _, r := range registry { + if !disabled[r] && r.URI() != reg.URI() && (t == "*" || r.Type == t) { + children(r, registry, added, disabled, ordered) + if !added[r] { + *ordered = append(*ordered, *r) + added[r] = true + } + } + } + } +} +// Register adds the registration to a Registry and returns the +// updated Registry, panicking if registration could not succeed. +func (registry Registry) Register(r *Registration) Registry { if r.Type == "" { panic(ErrNoType) } if r.ID == "" { panic(ErrNoPluginID) } - if err := checkUnique(r); err != nil { + if err := checkUnique(registry, r); err != nil { panic(err) } @@ -189,66 +163,14 @@ func Register(r *Registration) { } } - register.r = append(register.r, r) + return append(registry, r) } -// Reset removes all global registrations -func Reset() { - register.Lock() - defer register.Unlock() - register.r = nil -} - -func checkUnique(r *Registration) error { - for _, registered := range register.r { +func checkUnique(registry Registry, r *Registration) error { + for _, registered := range registry { if r.URI() == registered.URI() { return fmt.Errorf("%s: %w", r.URI(), ErrIDRegistered) } } return nil } - -// DisableFilter filters out disabled plugins -type DisableFilter func(r *Registration) bool - -// Graph returns an ordered list of registered plugins for initialization. -// Plugins in disableList specified by id will be disabled. -func Graph(filter DisableFilter) (ordered []*Registration) { - register.RLock() - defer register.RUnlock() - - for _, r := range register.r { - if filter(r) { - r.Disable = true - } - } - - added := map[*Registration]bool{} - for _, r := range register.r { - if r.Disable { - continue - } - children(r, added, &ordered) - if !added[r] { - ordered = append(ordered, r) - added[r] = true - } - } - return ordered -} - -func children(reg *Registration, added map[*Registration]bool, ordered *[]*Registration) { - for _, t := range reg.Requires { - for _, r := range register.r { - if !r.Disable && - r.URI() != reg.URI() && - (t == "*" || r.Type == t) { - children(r, added, ordered) - if !added[r] { - *ordered = append(*ordered, r) - added[r] = true - } - } - } - } -} diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go index 585d731cf..d80c77be1 100644 --- a/plugin/plugin_test.go +++ b/plugin/plugin_test.go @@ -22,227 +22,201 @@ import ( "github.com/containerd/containerd/services" ) -func registerClear() { - register.Lock() - defer register.Unlock() - register.r = nil -} - func mockPluginFilter(*Registration) bool { return false } -var tasksServiceRequires = []Type{ - RuntimePlugin, - RuntimePluginV2, - MetadataPlugin, - TaskMonitorPlugin, -} - // TestContainerdPlugin tests the logic of Graph, use the containerd's plugin func TestContainerdPlugin(t *testing.T) { - registerClear() - Register(&Registration{ + // Plugin types commonly used by containerd + const ( + InternalPlugin Type = "io.containerd.internal.v1" + RuntimePlugin Type = "io.containerd.runtime.v1" + RuntimePluginV2 Type = "io.containerd.runtime.v2" + ServicePlugin Type = "io.containerd.service.v1" + GRPCPlugin Type = "io.containerd.grpc.v1" + SnapshotPlugin Type = "io.containerd.snapshotter.v1" + TaskMonitorPlugin Type = "io.containerd.monitor.v1" + DiffPlugin Type = "io.containerd.differ.v1" + MetadataPlugin Type = "io.containerd.metadata.v1" + ContentPlugin Type = "io.containerd.content.v1" + GCPlugin Type = "io.containerd.gc.v1" + LeasePlugin Type = "io.containerd.lease.v1" + TracingProcessorPlugin Type = "io.containerd.tracing.processor.v1" + ) + + var register Registry + register = register.Register(&Registration{ Type: TaskMonitorPlugin, ID: "cgroups", - }) - Register(&Registration{ - Type: ServicePlugin, - ID: services.TasksService, - Requires: tasksServiceRequires, - }) - Register(&Registration{ + }).Register(&Registration{ + Type: ServicePlugin, + ID: services.TasksService, + Requires: []Type{ + RuntimePlugin, + RuntimePluginV2, + MetadataPlugin, + TaskMonitorPlugin, + }, + }).Register(&Registration{ Type: ServicePlugin, ID: services.IntrospectionService, - }) - Register(&Registration{ + }).Register(&Registration{ Type: ServicePlugin, ID: services.NamespacesService, Requires: []Type{ MetadataPlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "namespaces", Requires: []Type{ ServicePlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "content", Requires: []Type{ ServicePlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "containers", Requires: []Type{ ServicePlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: ServicePlugin, ID: services.ContainersService, Requires: []Type{ MetadataPlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "events", - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "leases", Requires: []Type{ LeasePlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: LeasePlugin, ID: "manager", Requires: []Type{ MetadataPlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "diff", Requires: []Type{ ServicePlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: ServicePlugin, ID: services.DiffService, Requires: []Type{ DiffPlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: ServicePlugin, ID: services.SnapshotsService, Requires: []Type{ MetadataPlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "snapshots", Requires: []Type{ ServicePlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "version", - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "images", Requires: []Type{ ServicePlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: GCPlugin, ID: "scheduler", Requires: []Type{ MetadataPlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: RuntimePluginV2, ID: "task", Requires: []Type{ MetadataPlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "tasks", Requires: []Type{ ServicePlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "introspection", Requires: []Type{"*"}, - }) - Register(&Registration{ + }).Register(&Registration{ Type: ServicePlugin, ID: services.ContentService, Requires: []Type{ MetadataPlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "healthcheck", - }) - Register(&Registration{ + }).Register(&Registration{ Type: InternalPlugin, ID: "opt", - }) - Register(&Registration{ + }).Register(&Registration{ Type: GRPCPlugin, ID: "cri", Requires: []Type{ ServicePlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: RuntimePlugin, ID: "linux", Requires: []Type{ MetadataPlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: InternalPlugin, Requires: []Type{ ServicePlugin, }, ID: "restart", - }) - Register(&Registration{ + }).Register(&Registration{ Type: DiffPlugin, ID: "walking", Requires: []Type{ MetadataPlugin, }, - }) - Register(&Registration{ + }).Register(&Registration{ Type: SnapshotPlugin, ID: "native", - }) - Register(&Registration{ + }).Register(&Registration{ Type: SnapshotPlugin, ID: "overlayfs", - }) - Register(&Registration{ + }).Register(&Registration{ Type: ContentPlugin, ID: "content", - }) - Register(&Registration{ + }).Register(&Registration{ Type: MetadataPlugin, ID: "bolt", Requires: []Type{ ContentPlugin, SnapshotPlugin, }, - }) - - Register(&Registration{ + }).Register(&Registration{ Type: TracingProcessorPlugin, ID: "otlp", - }) - - Register(&Registration{ + }).Register(&Registration{ Type: InternalPlugin, ID: "tracing", Requires: []Type{ @@ -250,7 +224,7 @@ func TestContainerdPlugin(t *testing.T) { }, }) - ordered := Graph(mockPluginFilter) + ordered := register.Graph(mockPluginFilter) expectedURI := []string{ "io.containerd.monitor.v1.cgroups", "io.containerd.content.v1.content", @@ -290,7 +264,7 @@ func TestContainerdPlugin(t *testing.T) { cmpOrdered(t, ordered, expectedURI) } -func cmpOrdered(t *testing.T, ordered []*Registration, expectedURI []string) { +func cmpOrdered(t *testing.T, ordered []Registration, expectedURI []string) { if len(ordered) != len(expectedURI) { t.Fatalf("ordered compare failed, %d != %d", len(ordered), len(expectedURI)) } @@ -306,6 +280,7 @@ func TestPluginGraph(t *testing.T) { for _, testcase := range []struct { input []*Registration expectedURI []string + filter DisableFilter }{ // test requires * { @@ -380,21 +355,27 @@ func TestPluginGraph(t *testing.T) { ID: "content", }, { - Type: "disable", - ID: "disable", - Disable: true, + Type: "disable", + ID: "disable", }, }, expectedURI: []string{ "content.content", }, + filter: func(r *Registration) bool { + return r.Type == "disable" + }, }, } { - registerClear() + var register Registry for _, in := range testcase.input { - Register(in) + register = register.Register(in) } - ordered := Graph(mockPluginFilter) + var filter DisableFilter = mockPluginFilter + if testcase.filter != nil { + filter = testcase.filter + } + ordered := register.Graph(filter) cmpOrdered(t, ordered, testcase.expectedURI) } } diff --git a/plugin/registry/register.go b/plugin/registry/register.go new file mode 100644 index 000000000..5c5d75c6f --- /dev/null +++ b/plugin/registry/register.go @@ -0,0 +1,50 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package registry + +import ( + "sync" + + "github.com/containerd/containerd/plugin" +) + +var register = struct { + sync.RWMutex + r plugin.Registry +}{} + +// Register allows plugins to register +func Register(r *plugin.Registration) { + register.Lock() + defer register.Unlock() + register.r = register.r.Register(r) +} + +// Reset removes all global registrations +func Reset() { + register.Lock() + defer register.Unlock() + register.r = nil +} + +// Graph returns an ordered list of registered plugins for initialization. +// Plugins in disableList specified by id will be disabled. +func Graph(filter plugin.DisableFilter) []plugin.Registration { + register.RLock() + defer register.RUnlock() + return register.r.Graph(filter) +} diff --git a/plugins/imageverifier/plugin.go b/plugins/imageverifier/plugin.go index 0c8fce7d0..14b23d0b8 100644 --- a/plugins/imageverifier/plugin.go +++ b/plugins/imageverifier/plugin.go @@ -22,12 +22,14 @@ import ( "github.com/containerd/containerd/pkg/imageverifier/bindir" "github.com/containerd/containerd/pkg/tomlext" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ) // Register default image verifier service plugin func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.ImageVerifierPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.ImageVerifierPlugin, ID: "bindir", Config: defaultConfig(), InitFn: func(ic *plugin.InitContext) (interface{}, error) { diff --git a/plugins/sandbox/controller.go b/plugins/sandbox/controller.go index a772bd704..12769e266 100644 --- a/plugins/sandbox/controller.go +++ b/plugins/sandbox/controller.go @@ -29,6 +29,8 @@ import ( "github.com/containerd/containerd/mount" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/runtime" v2 "github.com/containerd/containerd/runtime/v2" "github.com/containerd/containerd/sandbox" @@ -38,26 +40,26 @@ import ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.SandboxControllerPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.SandboxControllerPlugin, ID: "local", Requires: []plugin.Type{ - plugin.RuntimePluginV2, - plugin.EventPlugin, - plugin.SandboxStorePlugin, + plugins.RuntimePluginV2, + plugins.EventPlugin, + plugins.SandboxStorePlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - shimPlugin, err := ic.GetByID(plugin.RuntimePluginV2, "shim") + shimPlugin, err := ic.GetByID(plugins.RuntimePluginV2, "shim") if err != nil { return nil, err } - exchangePlugin, err := ic.GetByID(plugin.EventPlugin, "exchange") + exchangePlugin, err := ic.GetByID(plugins.EventPlugin, "exchange") if err != nil { return nil, err } - sbPlugin, err := ic.GetByID(plugin.SandboxStorePlugin, "local") + sbPlugin, err := ic.GetByID(plugins.SandboxStorePlugin, "local") if err != nil { return nil, err } diff --git a/plugins/sandbox/store.go b/plugins/sandbox/store.go index 8b3df117f..c5f588815 100644 --- a/plugins/sandbox/store.go +++ b/plugins/sandbox/store.go @@ -19,17 +19,19 @@ package sandbox import ( "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.SandboxStorePlugin, + registry.Register(&plugin.Registration{ + Type: plugins.SandboxStorePlugin, ID: "local", Requires: []plugin.Type{ - plugin.MetadataPlugin, + plugins.MetadataPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - m, err := ic.Get(plugin.MetadataPlugin) + m, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } diff --git a/plugins/streaming/manager.go b/plugins/streaming/manager.go index 8c9546d7e..8aeb60953 100644 --- a/plugins/streaming/manager.go +++ b/plugins/streaming/manager.go @@ -28,17 +28,19 @@ import ( "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/pkg/streaming" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.StreamingPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.StreamingPlugin, ID: "manager", Requires: []plugin.Type{ - plugin.MetadataPlugin, + plugins.MetadataPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - md, err := ic.Get(plugin.MetadataPlugin) + md, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } diff --git a/plugins/transfer/plugin.go b/plugins/transfer/plugin.go index 08fe35166..bda8b0fe8 100644 --- a/plugins/transfer/plugin.go +++ b/plugins/transfer/plugin.go @@ -29,6 +29,8 @@ import ( "github.com/containerd/containerd/pkg/unpack" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/log" // Load packages with type registrations @@ -39,30 +41,30 @@ import ( // Register local transfer service plugin func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.TransferPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.TransferPlugin, ID: "local", Requires: []plugin.Type{ - plugin.LeasePlugin, - plugin.MetadataPlugin, - plugin.DiffPlugin, - plugin.ImageVerifierPlugin, + plugins.LeasePlugin, + plugins.MetadataPlugin, + plugins.DiffPlugin, + plugins.ImageVerifierPlugin, }, Config: defaultConfig(), InitFn: func(ic *plugin.InitContext) (interface{}, error) { config := ic.Config.(*transferConfig) - m, err := ic.Get(plugin.MetadataPlugin) + m, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } ms := m.(*metadata.DB) - l, err := ic.Get(plugin.LeasePlugin) + l, err := ic.Get(plugins.LeasePlugin) if err != nil { return nil, err } vfs := make(map[string]imageverifier.ImageVerifier) - vps, err := ic.GetByType(plugin.ImageVerifierPlugin) + vps, err := ic.GetByType(plugins.ImageVerifierPlugin) if err != nil { return nil, err } @@ -82,7 +84,7 @@ func init() { for _, uc := range config.UnpackConfiguration { p, err := platforms.Parse(uc.Platform) if err != nil { - return nil, fmt.Errorf("%s: platform configuration %v invalid", plugin.TransferPlugin, uc.Platform) + return nil, fmt.Errorf("%s: platform configuration %v invalid", plugins.TransferPlugin, uc.Platform) } sn := ms.Snapshotter(uc.Snapshotter) @@ -90,7 +92,7 @@ func init() { return nil, fmt.Errorf("snapshotter %q not found: %w", uc.Snapshotter, errdefs.ErrNotFound) } - diffPlugins, err := ic.GetByType(plugin.DiffPlugin) + diffPlugins, err := ic.GetByType(plugins.DiffPlugin) if err != nil { return nil, fmt.Errorf("error loading diff plugins: %w", err) } diff --git a/plugins/types.go b/plugins/types.go new file mode 100644 index 000000000..2f25f8c51 --- /dev/null +++ b/plugins/types.go @@ -0,0 +1,84 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// plugins package stores all the plugin types used by containerd internally. +// +// External plugins should copy from these types and avoid importing this +// package. +package plugins + +import "github.com/containerd/containerd/plugin" + +const ( + // InternalPlugin implements an internal plugin to containerd + InternalPlugin plugin.Type = "io.containerd.internal.v1" + // RuntimePlugin implements a runtime + RuntimePlugin plugin.Type = "io.containerd.runtime.v1" + // RuntimePluginV2 implements a runtime v2 + RuntimePluginV2 plugin.Type = "io.containerd.runtime.v2" + // ServicePlugin implements a internal service + ServicePlugin plugin.Type = "io.containerd.service.v1" + // GRPCPlugin implements a grpc service + GRPCPlugin plugin.Type = "io.containerd.grpc.v1" + // TTRPCPlugin implements a ttrpc shim service + TTRPCPlugin plugin.Type = "io.containerd.ttrpc.v1" + // SnapshotPlugin implements a snapshotter + SnapshotPlugin plugin.Type = "io.containerd.snapshotter.v1" + // TaskMonitorPlugin implements a task monitor + TaskMonitorPlugin plugin.Type = "io.containerd.monitor.v1" + // DiffPlugin implements a differ + DiffPlugin plugin.Type = "io.containerd.differ.v1" + // MetadataPlugin implements a metadata store + MetadataPlugin plugin.Type = "io.containerd.metadata.v1" + // ContentPlugin implements a content store + ContentPlugin plugin.Type = "io.containerd.content.v1" + // GCPlugin implements garbage collection policy + GCPlugin plugin.Type = "io.containerd.gc.v1" + // EventPlugin implements event handling + EventPlugin plugin.Type = "io.containerd.event.v1" + // LeasePlugin implements lease manager + LeasePlugin plugin.Type = "io.containerd.lease.v1" + // StreamingPlugin implements a stream manager + StreamingPlugin plugin.Type = "io.containerd.streaming.v1" + // TracingProcessorPlugin implements a open telemetry span processor + TracingProcessorPlugin plugin.Type = "io.containerd.tracing.processor.v1" + // NRIApiPlugin implements the NRI adaptation interface for containerd. + NRIApiPlugin plugin.Type = "io.containerd.nri.v1" + // TransferPlugin implements a transfer service + TransferPlugin plugin.Type = "io.containerd.transfer.v1" + // SandboxStorePlugin implements a sandbox store + SandboxStorePlugin plugin.Type = "io.containerd.sandbox.store.v1" + // SandboxControllerPlugin implements a sandbox controller + SandboxControllerPlugin plugin.Type = "io.containerd.sandbox.controller.v1" + // ImageVerifierPlugin implements an image verifier service + ImageVerifierPlugin plugin.Type = "io.containerd.image-verifier.v1" +) + +const ( + // RuntimeRuncV2 is the runc runtime that supports multiple containers per shim + RuntimeRuncV2 = "io.containerd.runc.v2" +) + +const ( + // PropertyRootDir sets the root directory property for a plugin + PropertyRootDir = "io.containerd.plugin.root" + // PropertyStateDir sets the state directory property for a plugin + PropertyStateDir = "io.containerd.plugin.state" + // PropertyGRPCAddress is the grpc address used for client connections to containerd + PropertyGRPCAddress = "io.containerd.plugin.grpc.address" + // PropertyGRPCAddress is the ttrpc address used for client connections to containerd + PropertyTTRPCAddress = "io.containerd.plugin.ttrpc.address" +) diff --git a/runtime/restart/monitor/monitor.go b/runtime/restart/monitor/monitor.go index f6e312968..97d41bfc3 100644 --- a/runtime/restart/monitor/monitor.go +++ b/runtime/restart/monitor/monitor.go @@ -26,6 +26,8 @@ import ( "github.com/containerd/containerd" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/runtime/restart" "github.com/containerd/log" ) @@ -51,11 +53,11 @@ type Config struct { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.InternalPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.InternalPlugin, Requires: []plugin.Type{ - plugin.EventPlugin, - plugin.ServicePlugin, + plugins.EventPlugin, + plugins.ServicePlugin, }, ID: "restart", Config: &Config{ diff --git a/runtime/v2/example/example.go b/runtime/v2/example/example.go index 36618fefa..68ad833f4 100644 --- a/runtime/v2/example/example.go +++ b/runtime/v2/example/example.go @@ -24,25 +24,27 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/pkg/shutdown" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/runtime/v2/shim" "github.com/containerd/ttrpc" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.TTRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.TTRPCPlugin, ID: "task", Requires: []plugin.Type{ - plugin.EventPlugin, - plugin.InternalPlugin, + plugins.EventPlugin, + plugins.InternalPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - pp, err := ic.GetByID(plugin.EventPlugin, "publisher") + pp, err := ic.GetByID(plugins.EventPlugin, "publisher") if err != nil { return nil, err } - ss, err := ic.GetByID(plugin.InternalPlugin, "shutdown") + ss, err := ic.GetByID(plugins.InternalPlugin, "shutdown") if err != nil { return nil, err } diff --git a/runtime/v2/manager.go b/runtime/v2/manager.go index e45de8c1f..33803c3d7 100644 --- a/runtime/v2/manager.go +++ b/runtime/v2/manager.go @@ -34,6 +34,8 @@ import ( "github.com/containerd/containerd/pkg/timeout" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/protobuf" "github.com/containerd/containerd/runtime" shimbinary "github.com/containerd/containerd/runtime/v2/shim" @@ -50,12 +52,12 @@ type Config struct { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.RuntimePluginV2, + registry.Register(&plugin.Registration{ + Type: plugins.RuntimePluginV2, ID: "task", Requires: []plugin.Type{ - plugin.EventPlugin, - plugin.MetadataPlugin, + plugins.EventPlugin, + plugins.MetadataPlugin, }, Config: &Config{ Platforms: defaultPlatforms(), @@ -69,11 +71,11 @@ func init() { ic.Meta.Platforms = supportedPlatforms - m, err := ic.Get(plugin.MetadataPlugin) + m, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } - ep, err := ic.GetByID(plugin.EventPlugin, "exchange") + ep, err := ic.GetByID(plugins.EventPlugin, "exchange") if err != nil { return nil, err } @@ -82,10 +84,10 @@ func init() { events := ep.(*exchange.Exchange) shimManager, err := NewShimManager(ic.Context, &ManagerConfig{ - Root: ic.Root, - State: ic.State, - Address: ic.Address, - TTRPCAddress: ic.TTRPCAddress, + Root: ic.Properties[plugins.PropertyRootDir], + State: ic.Properties[plugins.PropertyStateDir], + Address: ic.Properties[plugins.PropertyGRPCAddress], + TTRPCAddress: ic.Properties[plugins.PropertyTTRPCAddress], Events: events, Store: cs, SchedCore: config.SchedCore, @@ -103,11 +105,11 @@ func init() { // However, due to time limits and to avoid migration steps in 1.6 release, // use the following workaround. // This expected to be removed in 1.7. - plugin.Register(&plugin.Registration{ - Type: plugin.RuntimePluginV2, + registry.Register(&plugin.Registration{ + Type: plugins.RuntimePluginV2, ID: "shim", InitFn: func(ic *plugin.InitContext) (interface{}, error) { - taskManagerI, err := ic.GetByID(plugin.RuntimePluginV2, "task") + taskManagerI, err := ic.GetByID(plugins.RuntimePluginV2, "task") if err != nil { return nil, err } @@ -176,7 +178,7 @@ type ShimManager struct { // ID of the shim manager func (m *ShimManager) ID() string { - return plugin.RuntimePluginV2.String() + ".shim" + return plugins.RuntimePluginV2.String() + ".shim" } // Start launches a new shim instance @@ -400,7 +402,7 @@ func NewTaskManager(shims *ShimManager) *TaskManager { // ID of the task manager func (m *TaskManager) ID() string { - return plugin.RuntimePluginV2.String() + ".task" + return plugins.RuntimePluginV2.String() + ".task" } // Create launches new shim instance and creates new task diff --git a/runtime/v2/runc/pause/sandbox.go b/runtime/v2/runc/pause/sandbox.go index 1156c81da..25a3871ee 100644 --- a/runtime/v2/runc/pause/sandbox.go +++ b/runtime/v2/runc/pause/sandbox.go @@ -24,6 +24,8 @@ import ( "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/pkg/shutdown" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/runtime/v2/shim" "github.com/containerd/log" "github.com/containerd/ttrpc" @@ -33,14 +35,14 @@ import ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.TTRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.TTRPCPlugin, ID: "pause", Requires: []plugin.Type{ - plugin.InternalPlugin, + plugins.InternalPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - ss, err := ic.GetByID(plugin.InternalPlugin, "shutdown") + ss, err := ic.GetByID(plugins.InternalPlugin, "shutdown") if err != nil { return nil, err } diff --git a/runtime/v2/runc/task/plugin/plugin_linux.go b/runtime/v2/runc/task/plugin/plugin_linux.go index 603a27459..2a70dbf64 100644 --- a/runtime/v2/runc/task/plugin/plugin_linux.go +++ b/runtime/v2/runc/task/plugin/plugin_linux.go @@ -19,24 +19,26 @@ package plugin import ( "github.com/containerd/containerd/pkg/shutdown" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/runtime/v2/runc/task" "github.com/containerd/containerd/runtime/v2/shim" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.TTRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.TTRPCPlugin, ID: "task", Requires: []plugin.Type{ - plugin.EventPlugin, - plugin.InternalPlugin, + plugins.EventPlugin, + plugins.InternalPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - pp, err := ic.GetByID(plugin.EventPlugin, "publisher") + pp, err := ic.GetByID(plugins.EventPlugin, "publisher") if err != nil { return nil, err } - ss, err := ic.GetByID(plugin.InternalPlugin, "shutdown") + ss, err := ic.GetByID(plugins.InternalPlugin, "shutdown") if err != nil { return nil, err } diff --git a/runtime/v2/shim/shim.go b/runtime/v2/shim/shim.go index 9f945a0e6..eb5dea724 100644 --- a/runtime/v2/shim/shim.go +++ b/runtime/v2/shim/shim.go @@ -34,6 +34,8 @@ import ( "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/pkg/shutdown" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/protobuf" "github.com/containerd/containerd/protobuf/proto" "github.com/containerd/containerd/version" @@ -283,8 +285,8 @@ func run(ctx context.Context, manager Manager, name string, config Config) error } } - plugin.Register(&plugin.Registration{ - Type: plugin.InternalPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.InternalPlugin, ID: "shutdown", InitFn: func(ic *plugin.InitContext) (interface{}, error) { return sd, nil @@ -292,8 +294,8 @@ func run(ctx context.Context, manager Manager, name string, config Config) error }) // Register event plugin - plugin.Register(&plugin.Registration{ - Type: plugin.EventPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.EventPlugin, ID: "publisher", InitFn: func(ic *plugin.InitContext) (interface{}, error) { return publisher, nil @@ -306,24 +308,24 @@ func run(ctx context.Context, manager Manager, name string, config Config) error ttrpcUnaryInterceptors = []ttrpc.UnaryServerInterceptor{} ) - plugins := plugin.Graph(func(*plugin.Registration) bool { return false }) - for _, p := range plugins { + + for _, p := range registry.Graph(func(*plugin.Registration) bool { return false }) { id := p.URI() log.G(ctx).WithField("type", p.Type).Infof("loading plugin %q...", id) initContext := plugin.NewContext( ctx, - p, initialized, - // NOTE: Root is empty since the shim does not support persistent storage, - // shim plugins should make use state directory for writing files to disk. - // The state directory will be destroyed when the shim if cleaned up or - // on reboot - "", - bundlePath, + map[string]string{ + // NOTE: Root is empty since the shim does not support persistent storage, + // shim plugins should make use state directory for writing files to disk. + // The state directory will be destroyed when the shim if cleaned up or + // on reboot + plugins.PropertyStateDir: filepath.Join(bundlePath, p.URI()), + plugins.PropertyGRPCAddress: addressFlag, + plugins.PropertyTTRPCAddress: ttrpcAddress, + }, ) - initContext.Address = addressFlag - initContext.TTRPCAddress = ttrpcAddress // load the plugin specific configuration if it is provided // TODO: Read configuration passed into shim, or from state directory? diff --git a/services.go b/services.go index edb8872e5..410f57921 100644 --- a/services.go +++ b/services.go @@ -31,6 +31,7 @@ import ( "github.com/containerd/containerd/leases" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/sandbox" srv "github.com/containerd/containerd/services" "github.com/containerd/containerd/services/introspection" @@ -183,16 +184,16 @@ func WithInMemoryServices(ic *plugin.InitContext) ClientOpt { return func(c *clientOpts) error { var opts []ServicesOpt for t, fn := range map[plugin.Type]func(interface{}) ServicesOpt{ - plugin.EventPlugin: func(i interface{}) ServicesOpt { + plugins.EventPlugin: func(i interface{}) ServicesOpt { return WithEventService(i.(EventService)) }, - plugin.LeasePlugin: func(i interface{}) ServicesOpt { + plugins.LeasePlugin: func(i interface{}) ServicesOpt { return WithLeasesService(i.(leases.Manager)) }, - plugin.SandboxStorePlugin: func(i interface{}) ServicesOpt { + plugins.SandboxStorePlugin: func(i interface{}) ServicesOpt { return WithSandboxStore(i.(sandbox.Store)) }, - plugin.SandboxControllerPlugin: func(i interface{}) ServicesOpt { + plugins.SandboxControllerPlugin: func(i interface{}) ServicesOpt { return WithSandboxController(i.(sandbox.Controller)) }, } { @@ -203,7 +204,7 @@ func WithInMemoryServices(ic *plugin.InitContext) ClientOpt { opts = append(opts, fn(i)) } - plugins, err := ic.GetByType(plugin.ServicePlugin) + plugins, err := ic.GetByType(plugins.ServicePlugin) if err != nil { return fmt.Errorf("failed to get service plugin: %w", err) } diff --git a/services/containers/local.go b/services/containers/local.go index 2c85422d7..197ea114c 100644 --- a/services/containers/local.go +++ b/services/containers/local.go @@ -27,6 +27,8 @@ import ( "github.com/containerd/containerd/events" "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/services" bolt "go.etcd.io/bbolt" @@ -37,19 +39,19 @@ import ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.ServicePlugin, + registry.Register(&plugin.Registration{ + Type: plugins.ServicePlugin, ID: services.ContainersService, Requires: []plugin.Type{ - plugin.EventPlugin, - plugin.MetadataPlugin, + plugins.EventPlugin, + plugins.MetadataPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - m, err := ic.Get(plugin.MetadataPlugin) + m, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } - ep, err := ic.Get(plugin.EventPlugin) + ep, err := ic.Get(plugins.EventPlugin) if err != nil { return nil, err } diff --git a/services/containers/service.go b/services/containers/service.go index 50b8399f7..fe19d4672 100644 --- a/services/containers/service.go +++ b/services/containers/service.go @@ -23,24 +23,26 @@ import ( api "github.com/containerd/containerd/api/services/containers/v1" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/services" "google.golang.org/grpc" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "containers", Requires: []plugin.Type{ - plugin.ServicePlugin, + plugins.ServicePlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - plugins, err := ic.GetByType(plugin.ServicePlugin) + sps, err := ic.GetByType(plugins.ServicePlugin) if err != nil { return nil, err } - p, ok := plugins[services.ContainersService] + p, ok := sps[services.ContainersService] if !ok { return nil, errors.New("containers service not found") } diff --git a/services/content/service.go b/services/content/service.go index 4717e62eb..7c3d19a0d 100644 --- a/services/content/service.go +++ b/services/content/service.go @@ -21,19 +21,21 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/services" "github.com/containerd/containerd/services/content/contentserver" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "content", Requires: []plugin.Type{ - plugin.ServicePlugin, + plugins.ServicePlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - plugins, err := ic.GetByType(plugin.ServicePlugin) + plugins, err := ic.GetByType(plugins.ServicePlugin) if err != nil { return nil, err } diff --git a/services/content/store.go b/services/content/store.go index 4d67af65e..59eab12f0 100644 --- a/services/content/store.go +++ b/services/content/store.go @@ -24,6 +24,8 @@ import ( "github.com/containerd/containerd/events" "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/services" digest "github.com/opencontainers/go-digest" ) @@ -35,19 +37,19 @@ type store struct { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.ServicePlugin, + registry.Register(&plugin.Registration{ + Type: plugins.ServicePlugin, ID: services.ContentService, Requires: []plugin.Type{ - plugin.EventPlugin, - plugin.MetadataPlugin, + plugins.EventPlugin, + plugins.MetadataPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - m, err := ic.Get(plugin.MetadataPlugin) + m, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } - ep, err := ic.Get(plugin.EventPlugin) + ep, err := ic.Get(plugins.EventPlugin) if err != nil { return nil, err } diff --git a/services/diff/local.go b/services/diff/local.go index 5f7d3f2b3..350993bf8 100644 --- a/services/diff/local.go +++ b/services/diff/local.go @@ -26,6 +26,8 @@ import ( "github.com/containerd/containerd/mount" "github.com/containerd/containerd/oci" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/services" "github.com/containerd/typeurl/v2" ocispec "github.com/opencontainers/image-spec/specs-go/v1" @@ -48,15 +50,15 @@ type differ interface { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.ServicePlugin, + registry.Register(&plugin.Registration{ + Type: plugins.ServicePlugin, ID: services.DiffService, Requires: []plugin.Type{ - plugin.DiffPlugin, + plugins.DiffPlugin, }, Config: defaultDifferConfig, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - differs, err := ic.GetByType(plugin.DiffPlugin) + differs, err := ic.GetByType(plugins.DiffPlugin) if err != nil { return nil, err } diff --git a/services/diff/service.go b/services/diff/service.go index 13f3558e8..198fe989f 100644 --- a/services/diff/service.go +++ b/services/diff/service.go @@ -22,23 +22,25 @@ import ( diffapi "github.com/containerd/containerd/api/services/diff/v1" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/services" "google.golang.org/grpc" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "diff", Requires: []plugin.Type{ - plugin.ServicePlugin, + plugins.ServicePlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - plugins, err := ic.GetByType(plugin.ServicePlugin) + sps, err := ic.GetByType(plugins.ServicePlugin) if err != nil { return nil, err } - p, ok := plugins[services.DiffService] + p, ok := sps[services.DiffService] if !ok { return nil, errors.New("diff service not found") } diff --git a/services/events/service.go b/services/events/service.go index 309ad42e0..3e35a3c65 100644 --- a/services/events/service.go +++ b/services/events/service.go @@ -26,6 +26,8 @@ import ( "github.com/containerd/containerd/events" "github.com/containerd/containerd/events/exchange" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/protobuf" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/ttrpc" @@ -33,14 +35,14 @@ import ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "events", Requires: []plugin.Type{ - plugin.EventPlugin, + plugins.EventPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - ep, err := ic.GetByID(plugin.EventPlugin, "exchange") + ep, err := ic.GetByID(plugins.EventPlugin, "exchange") if err != nil { return nil, err } diff --git a/services/healthcheck/service.go b/services/healthcheck/service.go index f924f042c..3f2b918e3 100644 --- a/services/healthcheck/service.go +++ b/services/healthcheck/service.go @@ -18,6 +18,8 @@ package healthcheck import ( "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "google.golang.org/grpc" "google.golang.org/grpc/health" @@ -29,8 +31,8 @@ type service struct { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "healthcheck", InitFn: func(*plugin.InitContext) (interface{}, error) { return newService() diff --git a/services/images/local.go b/services/images/local.go index 11edf62b3..107232d41 100644 --- a/services/images/local.go +++ b/services/images/local.go @@ -28,6 +28,8 @@ import ( "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/pkg/epoch" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/services" "github.com/containerd/log" @@ -37,25 +39,25 @@ import ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.ServicePlugin, + registry.Register(&plugin.Registration{ + Type: plugins.ServicePlugin, ID: services.ImagesService, Requires: []plugin.Type{ - plugin.EventPlugin, - plugin.MetadataPlugin, - plugin.GCPlugin, + plugins.EventPlugin, + plugins.MetadataPlugin, + plugins.GCPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - m, err := ic.Get(plugin.MetadataPlugin) + m, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } - g, err := ic.Get(plugin.GCPlugin) + g, err := ic.Get(plugins.GCPlugin) if err != nil { return nil, err } - ep, err := ic.Get(plugin.EventPlugin) + ep, err := ic.Get(plugins.EventPlugin) if err != nil { return nil, err } diff --git a/services/images/service.go b/services/images/service.go index 355c9e8c3..28d5f511c 100644 --- a/services/images/service.go +++ b/services/images/service.go @@ -22,24 +22,26 @@ import ( imagesapi "github.com/containerd/containerd/api/services/images/v1" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/services" "google.golang.org/grpc" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "images", Requires: []plugin.Type{ - plugin.ServicePlugin, + plugins.ServicePlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - plugins, err := ic.GetByType(plugin.ServicePlugin) + sps, err := ic.GetByType(plugins.ServicePlugin) if err != nil { return nil, err } - p, ok := plugins[services.ImagesService] + p, ok := sps[services.ImagesService] if !ok { return nil, errors.New("images service not found") } diff --git a/services/introspection/local.go b/services/introspection/local.go index 5ed328b40..23cda5f08 100644 --- a/services/introspection/local.go +++ b/services/introspection/local.go @@ -28,6 +28,8 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/filters" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/services" "github.com/google/uuid" @@ -38,15 +40,15 @@ import ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.ServicePlugin, + registry.Register(&plugin.Registration{ + Type: plugins.ServicePlugin, ID: services.IntrospectionService, Requires: []plugin.Type{}, InitFn: func(ic *plugin.InitContext) (interface{}, error) { // this service fetches all plugins through the plugin set of the plugin context return &Local{ plugins: ic.Plugins(), - root: ic.Root, + root: ic.Properties[plugins.PropertyRootDir], }, nil }, }) diff --git a/services/introspection/service.go b/services/introspection/service.go index 60013b52c..95ba2657b 100644 --- a/services/introspection/service.go +++ b/services/introspection/service.go @@ -22,22 +22,24 @@ import ( api "github.com/containerd/containerd/api/services/introspection/v1" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/services" "google.golang.org/grpc" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "introspection", - Requires: []plugin.Type{plugin.ServicePlugin}, + Requires: []plugin.Type{plugins.ServicePlugin}, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - plugins, err := ic.GetByType(plugin.ServicePlugin) + sps, err := ic.GetByType(plugins.ServicePlugin) if err != nil { return nil, err } - p, ok := plugins[services.IntrospectionService] + p, ok := sps[services.IntrospectionService] if !ok { return nil, errors.New("introspection service not found") } @@ -51,7 +53,7 @@ func init() { if !ok { return nil, errors.New("could not create a local client for introspection service") } - localClient.UpdateLocal(ic.Root) + localClient.UpdateLocal(ic.Properties[plugins.PropertyRootDir]) return &server{ local: localClient, diff --git a/services/leases/service.go b/services/leases/service.go index 9cebf7330..4c519801f 100644 --- a/services/leases/service.go +++ b/services/leases/service.go @@ -23,20 +23,22 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/leases" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/protobuf" ptypes "github.com/containerd/containerd/protobuf/types" "google.golang.org/grpc" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "leases", Requires: []plugin.Type{ - plugin.LeasePlugin, + plugins.LeasePlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - i, err := ic.GetByID(plugin.LeasePlugin, "manager") + i, err := ic.GetByID(plugins.LeasePlugin, "manager") if err != nil { return nil, err } diff --git a/services/namespaces/local.go b/services/namespaces/local.go index a4a2da05e..3e76fa30d 100644 --- a/services/namespaces/local.go +++ b/services/namespaces/local.go @@ -27,6 +27,8 @@ import ( "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/services" bolt "go.etcd.io/bbolt" @@ -36,19 +38,19 @@ import ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.ServicePlugin, + registry.Register(&plugin.Registration{ + Type: plugins.ServicePlugin, ID: services.NamespacesService, Requires: []plugin.Type{ - plugin.EventPlugin, - plugin.MetadataPlugin, + plugins.EventPlugin, + plugins.MetadataPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - m, err := ic.Get(plugin.MetadataPlugin) + m, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } - ep, err := ic.Get(plugin.EventPlugin) + ep, err := ic.Get(plugins.EventPlugin) if err != nil { return nil, err } diff --git a/services/namespaces/service.go b/services/namespaces/service.go index 9a5fe1d1b..7273a58fd 100644 --- a/services/namespaces/service.go +++ b/services/namespaces/service.go @@ -22,24 +22,26 @@ import ( api "github.com/containerd/containerd/api/services/namespaces/v1" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/services" "google.golang.org/grpc" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "namespaces", Requires: []plugin.Type{ - plugin.ServicePlugin, + plugins.ServicePlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - plugins, err := ic.GetByType(plugin.ServicePlugin) + sps, err := ic.GetByType(plugins.ServicePlugin) if err != nil { return nil, err } - p, ok := plugins[services.NamespacesService] + p, ok := sps[services.NamespacesService] if !ok { return nil, errors.New("namespaces service not found") } diff --git a/services/opt/service.go b/services/opt/service.go index 76280ba62..4e01c1e5e 100644 --- a/services/opt/service.go +++ b/services/opt/service.go @@ -22,6 +22,8 @@ import ( "path/filepath" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ) // Config for the opt manager @@ -31,8 +33,8 @@ type Config struct { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.InternalPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.InternalPlugin, ID: "opt", Config: &Config{ Path: defaultPath, diff --git a/services/sandbox/controller_service.go b/services/sandbox/controller_service.go index ec47ff95d..487828bbc 100644 --- a/services/sandbox/controller_service.go +++ b/services/sandbox/controller_service.go @@ -27,26 +27,28 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/events" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/protobuf" "github.com/containerd/containerd/sandbox" "github.com/containerd/log" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "sandbox-controllers", Requires: []plugin.Type{ - plugin.SandboxControllerPlugin, - plugin.EventPlugin, + plugins.SandboxControllerPlugin, + plugins.EventPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - sc, err := ic.GetByID(plugin.SandboxControllerPlugin, "local") + sc, err := ic.GetByID(plugins.SandboxControllerPlugin, "local") if err != nil { return nil, err } - ep, err := ic.Get(plugin.EventPlugin) + ep, err := ic.Get(plugins.EventPlugin) if err != nil { return nil, err } diff --git a/services/sandbox/store_service.go b/services/sandbox/store_service.go index 5110a291c..4c3972a07 100644 --- a/services/sandbox/store_service.go +++ b/services/sandbox/store_service.go @@ -25,19 +25,21 @@ import ( "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/sandbox" "github.com/containerd/log" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "sandboxes", Requires: []plugin.Type{ - plugin.SandboxStorePlugin, + plugins.SandboxStorePlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - sp, err := ic.GetByID(plugin.SandboxStorePlugin, "local") + sp, err := ic.GetByID(plugins.SandboxStorePlugin, "local") if err != nil { return nil, err } diff --git a/services/server/config/config.go b/services/server/config/config.go index 4d57f6cfa..00b6b96a7 100644 --- a/services/server/config/config.go +++ b/services/server/config/config.go @@ -239,11 +239,10 @@ type ProxyPlugin struct { } // Decode unmarshals a plugin specific configuration by plugin id -func (c *Config) Decode(ctx context.Context, p *plugin.Registration) (interface{}, error) { - id := p.URI() +func (c *Config) Decode(ctx context.Context, id string, config interface{}) (interface{}, error) { data, ok := c.Plugins[id] if !ok { - return p.Config, nil + return config, nil } b, err := toml.Marshal(data) @@ -251,7 +250,7 @@ func (c *Config) Decode(ctx context.Context, p *plugin.Registration) (interface{ return nil, err } - if err := toml.NewDecoder(bytes.NewReader(b)).DisallowUnknownFields().Decode(p.Config); err != nil { + if err := toml.NewDecoder(bytes.NewReader(b)).DisallowUnknownFields().Decode(config); err != nil { var serr *toml.StrictMissingError if errors.As(err, &serr) { for _, derr := range serr.Errors { @@ -260,7 +259,7 @@ func (c *Config) Decode(ctx context.Context, p *plugin.Registration) (interface{ "key": strings.Join(derr.Key(), " "), }).WithError(err).Warn("Ignoring unknown key in TOML for plugin") } - err = toml.Unmarshal(b, p.Config) + err = toml.Unmarshal(b, config) } if err != nil { return nil, err @@ -268,7 +267,7 @@ func (c *Config) Decode(ctx context.Context, p *plugin.Registration) (interface{ } - return p.Config, nil + return config, nil } // LoadConfig loads the containerd server config from the provided path diff --git a/services/server/config/config_test.go b/services/server/config/config_test.go index 742af453f..e81800501 100644 --- a/services/server/config/config_test.go +++ b/services/server/config/config_test.go @@ -25,7 +25,6 @@ import ( "github.com/stretchr/testify/assert" - "github.com/containerd/containerd/plugin" "github.com/containerd/log/logtest" ) @@ -201,7 +200,7 @@ func TestDecodePlugin(t *testing.T) { ctx := logtest.WithT(context.Background(), t) data := ` version = 2 -[plugins."io.containerd.runtime.v1.linux"] +[plugins."io.containerd.runtime.v2.task"] shim_debug = true ` @@ -216,7 +215,7 @@ version = 2 assert.NoError(t, err) pluginConfig := map[string]interface{}{} - _, err = out.Decode(ctx, &plugin.Registration{Type: "io.containerd.runtime.v1", ID: "linux", Config: &pluginConfig}) + _, err = out.Decode(ctx, "io.containerd.runtime.v2.task", &pluginConfig) assert.NoError(t, err) assert.Equal(t, true, pluginConfig["shim_debug"]) } @@ -226,7 +225,7 @@ version = 2 func TestDecodePluginInV1Config(t *testing.T) { ctx := logtest.WithT(context.Background(), t) data := ` -[plugins.linux] +[plugins.task] shim_debug = true ` @@ -244,7 +243,7 @@ func TestDecodePluginInV1Config(t *testing.T) { assert.Equal(t, 3, out.Version) pluginConfig := map[string]interface{}{} - _, err = out.Decode(ctx, &plugin.Registration{Type: "io.containerd.runtime.v1", ID: "linux", Config: &pluginConfig}) + _, err = out.Decode(ctx, "io.containerd.runtime.v2.task", &pluginConfig) assert.NoError(t, err) assert.Equal(t, true, pluginConfig["shim_debug"]) } diff --git a/services/server/server.go b/services/server/server.go index 95310b0cd..4f5a6976d 100644 --- a/services/server/server.go +++ b/services/server/server.go @@ -46,6 +46,9 @@ import ( "github.com/containerd/containerd/pkg/timeout" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/dynamic" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" srvconfig "github.com/containerd/containerd/services/server/config" ssproxy "github.com/containerd/containerd/snapshots/proxy" "github.com/containerd/containerd/sys" @@ -127,7 +130,7 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) { } timeout.Set(key, d) } - plugins, err := LoadPlugins(ctx, config) + loaded, err := LoadPlugins(ctx, config) if err != nil { return nil, err } @@ -223,7 +226,7 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) { // Run each plugin migration for each version to ensure that migration logic is simple and // focused on upgrading from one version at a time. for v := version; v < srvconfig.CurrentConfigVersion; v++ { - for _, p := range plugins { + for _, p := range loaded { if p.ConfigMigration != nil { if err := p.ConfigMigration(ctx, v, config.Plugins); err != nil { return nil, err @@ -237,20 +240,21 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) { log.G(ctx).WithField("t", migrationT).Warnf("Configuration migrated from version %d, use `containerd config migrate` to avoid migration", version) } - for _, p := range plugins { + for _, p := range loaded { id := p.URI() log.G(ctx).WithField("type", p.Type).Infof("loading plugin %q...", id) var mustSucceed int32 initContext := plugin.NewContext( ctx, - p, initialized, - config.Root, - config.State, + map[string]string{ + plugins.PropertyRootDir: filepath.Join(config.Root, id), + plugins.PropertyStateDir: filepath.Join(config.State, id), + plugins.PropertyGRPCAddress: config.GRPC.Address, + plugins.PropertyTTRPCAddress: config.TTRPC.Address, + }, ) - initContext.Address = config.GRPC.Address - initContext.TTRPCAddress = config.TTRPC.Address initContext.RegisterReadiness = func() func() { atomic.StoreInt32(&mustSucceed, 1) return s.RegisterReadiness() @@ -258,7 +262,7 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) { // load the plugin specific configuration if it is provided if p.Config != nil { - pc, err := config.Decode(ctx, p) + pc, err := config.Decode(ctx, id, p.Config) if err != nil { return nil, err } @@ -425,22 +429,23 @@ func (s *Server) Wait() { // LoadPlugins loads all plugins into containerd and generates an ordered graph // of all plugins. -func LoadPlugins(ctx context.Context, config *srvconfig.Config) ([]*plugin.Registration, error) { +func LoadPlugins(ctx context.Context, config *srvconfig.Config) ([]plugin.Registration, error) { // load all plugins into containerd path := config.PluginDir if path == "" { path = filepath.Join(config.Root, "plugins") } - if err := plugin.Load(path); err != nil { + if err := dynamic.Load(path); err != nil { return nil, err } // load additional plugins that don't automatically register themselves - plugin.Register(&plugin.Registration{ - Type: plugin.ContentPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.ContentPlugin, ID: "content", InitFn: func(ic *plugin.InitContext) (interface{}, error) { - ic.Meta.Exports["root"] = ic.Root - return local.NewStore(ic.Root) + root := ic.Properties[plugins.PropertyRootDir] + ic.Meta.Exports["root"] = root + return local.NewStore(root) }, }) @@ -456,20 +461,20 @@ func LoadPlugins(ctx context.Context, config *srvconfig.Config) ([]*plugin.Regis ) switch pp.Type { - case string(plugin.SnapshotPlugin), "snapshot": - t = plugin.SnapshotPlugin + case string(plugins.SnapshotPlugin), "snapshot": + t = plugins.SnapshotPlugin ssname := name f = func(conn *grpc.ClientConn) interface{} { return ssproxy.NewSnapshotter(ssapi.NewSnapshotsClient(conn), ssname) } - case string(plugin.ContentPlugin), "content": - t = plugin.ContentPlugin + case string(plugins.ContentPlugin), "content": + t = plugins.ContentPlugin f = func(conn *grpc.ClientConn) interface{} { return csproxy.NewContentStore(csapi.NewContentClient(conn)) } - case string(plugin.DiffPlugin), "diff": - t = plugin.DiffPlugin + case string(plugins.DiffPlugin), "diff": + t = plugins.DiffPlugin f = func(conn *grpc.ClientConn) interface{} { return diffproxy.NewDiffApplier(diffapi.NewDiffClient(conn)) } @@ -485,7 +490,7 @@ func LoadPlugins(ctx context.Context, config *srvconfig.Config) ([]*plugin.Regis p = platforms.DefaultSpec() } - plugin.Register(&plugin.Registration{ + registry.Register(&plugin.Registration{ Type: t, ID: name, InitFn: func(ic *plugin.InitContext) (interface{}, error) { @@ -503,7 +508,7 @@ func LoadPlugins(ctx context.Context, config *srvconfig.Config) ([]*plugin.Regis filter := srvconfig.V2DisabledFilter // return the ordered graph for plugins - return plugin.Graph(filter(config.DisabledPlugins)), nil + return registry.Graph(filter(config.DisabledPlugins)), nil } type proxyClients struct { diff --git a/services/server/server_test.go b/services/server/server_test.go index 3c0faaf0f..fb72b1cf9 100644 --- a/services/server/server_test.go +++ b/services/server/server_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" srvconfig "github.com/containerd/containerd/services/server/config" "github.com/stretchr/testify/assert" ) @@ -57,8 +58,8 @@ func TestCreateTopLevelDirectoriesWithEmptyRootPath(t *testing.T) { } func TestMigration(t *testing.T) { - plugin.Reset() - defer plugin.Reset() + registry.Reset() + defer registry.Reset() version := srvconfig.CurrentConfigVersion - 1 @@ -67,7 +68,7 @@ func TestMigration(t *testing.T) { NotMigrated string `toml:"notmigrated"` } - plugin.Register(&plugin.Registration{ + registry.Register(&plugin.Registration{ Type: "io.containerd.test", ID: "t1", Config: &testConfig{}, @@ -86,7 +87,7 @@ func TestMigration(t *testing.T) { return nil, nil }, }) - plugin.Register(&plugin.Registration{ + registry.Register(&plugin.Registration{ Type: "io.containerd.new", Requires: []plugin.Type{ "io.containerd.test", // Ensure this test runs second diff --git a/services/snapshots/service.go b/services/snapshots/service.go index 5c1334338..0a1c46903 100644 --- a/services/snapshots/service.go +++ b/services/snapshots/service.go @@ -24,6 +24,8 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/services" "github.com/containerd/containerd/snapshots" @@ -32,11 +34,11 @@ import ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "snapshots", Requires: []plugin.Type{ - plugin.ServicePlugin, + plugins.ServicePlugin, }, InitFn: newService, }) @@ -50,11 +52,11 @@ type service struct { } func newService(ic *plugin.InitContext) (interface{}, error) { - plugins, err := ic.GetByType(plugin.ServicePlugin) + sps, err := ic.GetByType(plugins.ServicePlugin) if err != nil { return nil, err } - p, ok := plugins[services.SnapshotsService] + p, ok := sps[services.SnapshotsService] if !ok { return nil, errors.New("snapshots service not found") } diff --git a/services/snapshots/snapshotters.go b/services/snapshots/snapshotters.go index 2dcc01cb7..d7af9149d 100644 --- a/services/snapshots/snapshotters.go +++ b/services/snapshots/snapshotters.go @@ -19,18 +19,20 @@ package snapshots import ( "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/services" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.ServicePlugin, + registry.Register(&plugin.Registration{ + Type: plugins.ServicePlugin, ID: services.SnapshotsService, Requires: []plugin.Type{ - plugin.MetadataPlugin, + plugins.MetadataPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - m, err := ic.Get(plugin.MetadataPlugin) + m, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } diff --git a/services/streaming/service.go b/services/streaming/service.go index 0e445f1a5..f19e7fb16 100644 --- a/services/streaming/service.go +++ b/services/streaming/service.go @@ -24,6 +24,8 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/pkg/streaming" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/protobuf" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/log" @@ -41,14 +43,14 @@ func init() { panic(err) } - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "streaming", Requires: []plugin.Type{ - plugin.StreamingPlugin, + plugins.StreamingPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - i, err := ic.GetByID(plugin.StreamingPlugin, "manager") + i, err := ic.GetByID(plugins.StreamingPlugin, "manager") if err != nil { return nil, err } diff --git a/services/tasks/local.go b/services/tasks/local.go index 5a062b48a..be6cd298c 100644 --- a/services/tasks/local.go +++ b/services/tasks/local.go @@ -19,6 +19,7 @@ package tasks import ( "bytes" "context" + "errors" "fmt" "io" "os" @@ -41,6 +42,8 @@ import ( "github.com/containerd/containerd/pkg/rdt" "github.com/containerd/containerd/pkg/timeout" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/protobuf" "github.com/containerd/containerd/protobuf/proto" ptypes "github.com/containerd/containerd/protobuf/types" @@ -74,8 +77,8 @@ type Config struct { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.ServicePlugin, + registry.Register(&plugin.Registration{ + Type: plugins.ServicePlugin, ID: services.TasksService, Requires: tasksServiceRequires, Config: &Config{}, @@ -88,24 +91,24 @@ func init() { func initFunc(ic *plugin.InitContext) (interface{}, error) { config := ic.Config.(*Config) - v2r, err := ic.GetByID(plugin.RuntimePluginV2, "task") + v2r, err := ic.GetByID(plugins.RuntimePluginV2, "task") if err != nil { return nil, err } - m, err := ic.Get(plugin.MetadataPlugin) + m, err := ic.Get(plugins.MetadataPlugin) if err != nil { return nil, err } - ep, err := ic.Get(plugin.EventPlugin) + ep, err := ic.Get(plugins.EventPlugin) if err != nil { return nil, err } - monitor, err := ic.Get(plugin.TaskMonitorPlugin) + monitor, err := ic.Get(plugins.TaskMonitorPlugin) if err != nil { - if !errdefs.IsNotFound(err) { + if !errors.Is(err, plugin.ErrPluginNotFound) { return nil, err } monitor = runtime.NewNoopMonitor() diff --git a/services/tasks/local_darwin.go b/services/tasks/local_darwin.go index 8231572b7..1d0d43940 100644 --- a/services/tasks/local_darwin.go +++ b/services/tasks/local_darwin.go @@ -20,10 +20,11 @@ package tasks import ( "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" ) var tasksServiceRequires = []plugin.Type{ - plugin.RuntimePluginV2, - plugin.MetadataPlugin, - plugin.TaskMonitorPlugin, + plugins.RuntimePluginV2, + plugins.MetadataPlugin, + plugins.TaskMonitorPlugin, } diff --git a/services/tasks/local_freebsd.go b/services/tasks/local_freebsd.go index 285c1de99..4221a1109 100644 --- a/services/tasks/local_freebsd.go +++ b/services/tasks/local_freebsd.go @@ -18,11 +18,12 @@ package tasks import ( "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" ) var tasksServiceRequires = []plugin.Type{ - plugin.EventPlugin, - plugin.RuntimePluginV2, - plugin.MetadataPlugin, - plugin.TaskMonitorPlugin, + plugins.EventPlugin, + plugins.RuntimePluginV2, + plugins.MetadataPlugin, + plugins.TaskMonitorPlugin, } diff --git a/services/tasks/local_unix.go b/services/tasks/local_unix.go index 1df9eb808..ddff2ebb5 100644 --- a/services/tasks/local_unix.go +++ b/services/tasks/local_unix.go @@ -20,12 +20,12 @@ package tasks import ( "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" ) var tasksServiceRequires = []plugin.Type{ - plugin.EventPlugin, - plugin.RuntimePlugin, - plugin.RuntimePluginV2, - plugin.MetadataPlugin, - plugin.TaskMonitorPlugin, + plugins.EventPlugin, + plugins.RuntimePluginV2, + plugins.MetadataPlugin, + plugins.TaskMonitorPlugin, } diff --git a/services/tasks/local_windows.go b/services/tasks/local_windows.go index 285c1de99..4221a1109 100644 --- a/services/tasks/local_windows.go +++ b/services/tasks/local_windows.go @@ -18,11 +18,12 @@ package tasks import ( "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" ) var tasksServiceRequires = []plugin.Type{ - plugin.EventPlugin, - plugin.RuntimePluginV2, - plugin.MetadataPlugin, - plugin.TaskMonitorPlugin, + plugins.EventPlugin, + plugins.RuntimePluginV2, + plugins.MetadataPlugin, + plugins.TaskMonitorPlugin, } diff --git a/services/tasks/service.go b/services/tasks/service.go index 3cd56ece5..e141a7108 100644 --- a/services/tasks/service.go +++ b/services/tasks/service.go @@ -22,6 +22,8 @@ import ( api "github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/services" "google.golang.org/grpc" @@ -32,18 +34,18 @@ var ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "tasks", Requires: []plugin.Type{ - plugin.ServicePlugin, + plugins.ServicePlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - plugins, err := ic.GetByType(plugin.ServicePlugin) + sps, err := ic.GetByType(plugins.ServicePlugin) if err != nil { return nil, err } - p, ok := plugins[services.TasksService] + p, ok := sps[services.TasksService] if !ok { return nil, errors.New("tasks service not found") } diff --git a/services/transfer/service.go b/services/transfer/service.go index 7f98c3ef0..c03aa0a33 100644 --- a/services/transfer/service.go +++ b/services/transfer/service.go @@ -24,8 +24,10 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/pkg/streaming" "github.com/containerd/containerd/pkg/transfer" - "github.com/containerd/containerd/pkg/transfer/plugins" + tplugins "github.com/containerd/containerd/pkg/transfer/plugins" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/log" "github.com/containerd/typeurl/v2" @@ -36,12 +38,12 @@ import ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "transfer", Requires: []plugin.Type{ - plugin.TransferPlugin, - plugin.StreamingPlugin, + plugins.TransferPlugin, + plugins.StreamingPlugin, }, InitFn: newService, }) @@ -54,21 +56,21 @@ type service struct { } func newService(ic *plugin.InitContext) (interface{}, error) { - plugins, err := ic.GetByType(plugin.TransferPlugin) + sps, err := ic.GetByType(plugins.TransferPlugin) if err != nil { return nil, err } // TODO: how to determine order? - t := make([]transfer.Transferrer, 0, len(plugins)) - for _, p := range plugins { + t := make([]transfer.Transferrer, 0, len(sps)) + for _, p := range sps { i, err := p.Instance() if err != nil { return nil, err } t = append(t, i.(transfer.Transferrer)) } - sp, err := ic.GetByID(plugin.StreamingPlugin, "manager") + sp, err := ic.GetByID(plugins.StreamingPlugin, "manager") if err != nil { return nil, err } @@ -134,7 +136,7 @@ func (s *service) Transfer(ctx context.Context, req *transferapi.TransferRequest } func (s *service) convertAny(ctx context.Context, a typeurl.Any) (interface{}, error) { - obj, err := plugins.ResolveType(a) + obj, err := tplugins.ResolveType(a) if err != nil { if errdefs.IsNotFound(err) { return typeurl.UnmarshalAny(a) diff --git a/services/version/service.go b/services/version/service.go index 0344dd9b3..269627f60 100644 --- a/services/version/service.go +++ b/services/version/service.go @@ -21,6 +21,8 @@ import ( api "github.com/containerd/containerd/api/services/version/v1" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" ptypes "github.com/containerd/containerd/protobuf/types" ctrdversion "github.com/containerd/containerd/version" "google.golang.org/grpc" @@ -29,8 +31,8 @@ import ( var _ api.VersionServer = &service{} func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.GRPCPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.GRPCPlugin, ID: "version", InitFn: initFunc, }) diff --git a/snapshots/blockfile/plugin/plugin.go b/snapshots/blockfile/plugin/plugin.go index 03defdea4..0defcec19 100644 --- a/snapshots/blockfile/plugin/plugin.go +++ b/snapshots/blockfile/plugin/plugin.go @@ -21,6 +21,8 @@ import ( "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/snapshots/blockfile" ) @@ -44,8 +46,8 @@ type Config struct { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.SnapshotPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.SnapshotPlugin, ID: "blockfile", Config: &Config{}, InitFn: func(ic *plugin.InitContext) (interface{}, error) { @@ -57,7 +59,7 @@ func init() { } var opts []blockfile.Opt - root := ic.Root + root := ic.Properties[plugins.PropertyRootDir] if len(config.RootPath) != 0 { root = config.RootPath } diff --git a/snapshots/btrfs/plugin/plugin.go b/snapshots/btrfs/plugin/plugin.go index f6635846c..e48010598 100644 --- a/snapshots/btrfs/plugin/plugin.go +++ b/snapshots/btrfs/plugin/plugin.go @@ -25,6 +25,8 @@ import ( "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/snapshots/btrfs" ) @@ -35,9 +37,9 @@ type Config struct { } func init() { - plugin.Register(&plugin.Registration{ + registry.Register(&plugin.Registration{ ID: "btrfs", - Type: plugin.SnapshotPlugin, + Type: plugins.SnapshotPlugin, Config: &Config{}, InitFn: func(ic *plugin.InitContext) (interface{}, error) { ic.Meta.Platforms = []ocispec.Platform{platforms.DefaultSpec()} @@ -47,7 +49,7 @@ func init() { return nil, errors.New("invalid btrfs configuration") } - root := ic.Root + root := ic.Properties[plugins.PropertyRootDir] if len(config.RootPath) != 0 { root = config.RootPath } diff --git a/snapshots/devmapper/plugin/plugin.go b/snapshots/devmapper/plugin/plugin.go index ae2aa7676..47c375bf9 100644 --- a/snapshots/devmapper/plugin/plugin.go +++ b/snapshots/devmapper/plugin/plugin.go @@ -24,12 +24,14 @@ import ( "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/snapshots/devmapper" ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.SnapshotPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.SnapshotPlugin, ID: "devmapper", Config: &devmapper.Config{}, InitFn: func(ic *plugin.InitContext) (interface{}, error) { @@ -45,7 +47,7 @@ func init() { } if config.RootPath == "" { - config.RootPath = ic.Root + config.RootPath = ic.Properties[plugins.PropertyRootDir] } return devmapper.NewSnapshotter(ic.Context, config) diff --git a/snapshots/lcow/lcow.go b/snapshots/lcow/lcow.go index bbcda4423..3f398223e 100644 --- a/snapshots/lcow/lcow.go +++ b/snapshots/lcow/lcow.go @@ -37,6 +37,8 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/snapshots/storage" "github.com/containerd/continuity/fs" @@ -45,15 +47,15 @@ import ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.SnapshotPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.SnapshotPlugin, ID: "windows-lcow", InitFn: func(ic *plugin.InitContext) (interface{}, error) { ic.Meta.Platforms = append(ic.Meta.Platforms, ocispec.Platform{ OS: "linux", Architecture: runtime.GOARCH, }) - return NewSnapshotter(ic.Root) + return NewSnapshotter(ic.Properties[plugins.PropertyRootDir]) }, }) } diff --git a/snapshots/native/plugin/plugin.go b/snapshots/native/plugin/plugin.go index 8544f3ba0..d79846547 100644 --- a/snapshots/native/plugin/plugin.go +++ b/snapshots/native/plugin/plugin.go @@ -21,6 +21,8 @@ import ( "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/snapshots/native" ) @@ -31,8 +33,8 @@ type Config struct { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.SnapshotPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.SnapshotPlugin, ID: "native", Config: &Config{}, InitFn: func(ic *plugin.InitContext) (interface{}, error) { @@ -43,7 +45,7 @@ func init() { return nil, errors.New("invalid native configuration") } - root := ic.Root + root := ic.Properties[plugins.PropertyRootDir] if len(config.RootPath) != 0 { root = config.RootPath } diff --git a/snapshots/overlay/plugin/plugin.go b/snapshots/overlay/plugin/plugin.go index 89adeebb2..be3cdeb75 100644 --- a/snapshots/overlay/plugin/plugin.go +++ b/snapshots/overlay/plugin/plugin.go @@ -23,6 +23,8 @@ import ( "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/snapshots/overlay" "github.com/containerd/containerd/snapshots/overlay/overlayutils" ) @@ -49,8 +51,8 @@ type Config struct { } func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.SnapshotPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.SnapshotPlugin, ID: "overlayfs", Config: &Config{}, InitFn: func(ic *plugin.InitContext) (interface{}, error) { @@ -61,7 +63,7 @@ func init() { return nil, errors.New("invalid overlay configuration") } - root := ic.Root + root := ic.Properties[plugins.PropertyRootDir] if config.RootPath != "" { root = config.RootPath } diff --git a/snapshots/windows/windows.go b/snapshots/windows/windows.go index c651f1d97..5a9adf10b 100644 --- a/snapshots/windows/windows.go +++ b/snapshots/windows/windows.go @@ -38,6 +38,8 @@ import ( "github.com/containerd/containerd/mount" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/snapshots/storage" "github.com/containerd/continuity/fs" @@ -46,12 +48,12 @@ import ( ) func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.SnapshotPlugin, + registry.Register(&plugin.Registration{ + Type: plugins.SnapshotPlugin, ID: "windows", InitFn: func(ic *plugin.InitContext) (interface{}, error) { ic.Meta.Platforms = []ocispec.Platform{platforms.DefaultSpec()} - return NewSnapshotter(ic.Root) + return NewSnapshotter(ic.Properties[plugins.PropertyRootDir]) }, }) } diff --git a/task.go b/task.go index 7a502c7fa..dbe61dd31 100644 --- a/task.go +++ b/task.go @@ -35,7 +35,7 @@ import ( "github.com/containerd/containerd/images" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/oci" - "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/protobuf" google_protobuf "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/rootfs" @@ -309,7 +309,7 @@ func (t *task) Delete(ctx context.Context, opts ...ProcessDeleteOpts) (*ExitStat switch status.Status { case Stopped, Unknown, "": case Created: - if t.client.runtime == plugin.RuntimePlugin.String()+".windows" { + if t.client.runtime == plugins.RuntimePlugin.String()+".windows" { // On windows Created is akin to Stopped break } @@ -326,7 +326,7 @@ func (t *task) Delete(ctx context.Context, opts ...ProcessDeleteOpts) (*ExitStat // io.Wait locks for restored tasks on Windows unless we call // io.Close first (https://github.com/containerd/containerd/issues/5621) // in other cases, preserve the contract and let IO finish before closing - if t.client.runtime == plugin.RuntimePlugin.String()+".windows" { + if t.client.runtime == plugins.RuntimePlugin.String()+".windows" { t.io.Close() } // io.Cancel is used to cancel the io goroutine while it is in @@ -690,7 +690,7 @@ func isCheckpointPathExist(runtime string, v interface{}) bool { } switch runtime { - case plugin.RuntimeRuncV2: + case plugins.RuntimeRuncV2: if opts, ok := v.(*options.CheckpointOptions); ok && opts.ImagePath != "" { return true } diff --git a/tracing/plugin/otlp.go b/tracing/plugin/otlp.go index 0a390cc2d..1f466a2a0 100644 --- a/tracing/plugin/otlp.go +++ b/tracing/plugin/otlp.go @@ -25,6 +25,8 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/plugin/registry" + "github.com/containerd/containerd/plugins" "github.com/containerd/containerd/tracing" "github.com/containerd/log" "github.com/sirupsen/logrus" @@ -41,9 +43,9 @@ import ( const exporterPlugin = "otlp" func init() { - plugin.Register(&plugin.Registration{ + registry.Register(&plugin.Registration{ ID: exporterPlugin, - Type: plugin.TracingProcessorPlugin, + Type: plugins.TracingProcessorPlugin, Config: &OTLPConfig{}, InitFn: func(ic *plugin.InitContext) (interface{}, error) { cfg := ic.Config.(*OTLPConfig) @@ -54,14 +56,19 @@ func init() { return trace.NewBatchSpanProcessor(exp), nil }, }) - plugin.Register(&plugin.Registration{ - ID: "tracing", - Type: plugin.InternalPlugin, - Requires: []plugin.Type{plugin.TracingProcessorPlugin}, - Config: &TraceConfig{ServiceName: "containerd", TraceSamplingRatio: 1.0}, + registry.Register(&plugin.Registration{ + ID: "tracing", + Type: plugins.InternalPlugin, + Requires: []plugin.Type{ + plugins.TracingProcessorPlugin, + }, + Config: &TraceConfig{ + ServiceName: "containerd", + TraceSamplingRatio: 1.0, + }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { //get TracingProcessorPlugin which is a dependency - plugins, err := ic.GetByType(plugin.TracingProcessorPlugin) + plugins, err := ic.GetByType(plugins.TracingProcessorPlugin) if err != nil { return nil, fmt.Errorf("failed to get tracing processors: %w", err) } diff --git a/vendor/github.com/containerd/zfs/.gitignore b/vendor/github.com/containerd/zfs/.gitignore deleted file mode 100644 index e98e2bb4e..000000000 --- a/vendor/github.com/containerd/zfs/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.test - -# Support running go modules in vendor mode for local development -/vendor/ diff --git a/vendor/github.com/containerd/zfs/LICENSE b/vendor/github.com/containerd/zfs/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/vendor/github.com/containerd/zfs/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/containerd/zfs/README.md b/vendor/github.com/containerd/zfs/README.md deleted file mode 100644 index b74703724..000000000 --- a/vendor/github.com/containerd/zfs/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# [containerd](https://github.com/containerd/containerd) ZFS snapshotter plugin - -[![PkgGoDev](https://pkg.go.dev/badge/github.com/containerd/zfs)](https://pkg.go.dev/github.com/containerd/zfs) -[![Build Status](https://github.com/containerd/zfs/actions/workflows/ci.yml/badge.svg)](https://github.com/containerd/zfs/actions/workflows/ci.yml) -[![Go Report Card](https://goreportcard.com/badge/github.com/containerd/zfs)](https://goreportcard.com/report/github.com/containerd/zfs) -[![codecov](https://codecov.io/gh/containerd/zfs/branch/main/graph/badge.svg)](https://codecov.io/gh/containerd/zfs) - -ZFS snapshotter plugin for containerd. - -This plugin is tested on Linux with Ubuntu. It should be compatible with FreeBSD. - -## Usage - -The plugin is built-in by default since containerd 1.1. -No need to recompile containerd or execute a proxy snapshotter process. - -1. Set up a ZFS filesystem. -The ZFS filesystem name is arbitrary but the mount point needs to be `/var/lib/containerd/io.containerd.snapshotter.v1.zfs`, when the containerd root is set to `/var/lib/containerd`. -```console -$ zfs create -o mountpoint=/var/lib/containerd/io.containerd.snapshotter.v1.zfs your-zpool/containerd -``` - -2. Start containerd. - -3. e.g. `ctr pull --snapshotter=zfs ...` - -## Project details - -The zfs plugin is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). -As a containerd sub-project, you will find the: - * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), - * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS), - * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) - -information in our [`containerd/project`](https://github.com/containerd/project) repository. diff --git a/vendor/github.com/containerd/zfs/codecov.yml b/vendor/github.com/containerd/zfs/codecov.yml deleted file mode 100644 index 69cb76019..000000000 --- a/vendor/github.com/containerd/zfs/codecov.yml +++ /dev/null @@ -1 +0,0 @@ -comment: false diff --git a/vendor/github.com/containerd/zfs/plugin/plugin.go b/vendor/github.com/containerd/zfs/plugin/plugin.go deleted file mode 100644 index b318949fc..000000000 --- a/vendor/github.com/containerd/zfs/plugin/plugin.go +++ /dev/null @@ -1,62 +0,0 @@ -//go:build linux || freebsd - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package plugin - -import ( - "errors" - "fmt" - - "github.com/containerd/containerd/platforms" - "github.com/containerd/containerd/plugin" - "github.com/containerd/zfs" -) - -// Config represents configuration for the zfs plugin -type Config struct { - // Root directory for the plugin - RootPath string `toml:"root_path"` -} - -func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.SnapshotPlugin, - ID: "zfs", - Config: &Config{}, - InitFn: func(ic *plugin.InitContext) (interface{}, error) { - ic.Meta.Platforms = append(ic.Meta.Platforms, platforms.DefaultSpec()) - - // get config - config, ok := ic.Config.(*Config) - if !ok { - return nil, errors.New("invalid zfs configuration") - } - // use default ic.Root as root path if config doesn't have a valid root path - root := ic.Root - if len(config.RootPath) != 0 { - root = config.RootPath - } - ic.Meta.Exports["root"] = root - snapshotter, err := zfs.NewSnapshotter(root) - if err != nil { - return nil, fmt.Errorf("%s: %w", err.Error(), plugin.ErrSkipPlugin) - } - return snapshotter, nil - }, - }) -} diff --git a/vendor/github.com/containerd/zfs/zfs.go b/vendor/github.com/containerd/zfs/zfs.go deleted file mode 100644 index 508d271f8..000000000 --- a/vendor/github.com/containerd/zfs/zfs.go +++ /dev/null @@ -1,368 +0,0 @@ -//go:build linux || freebsd - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package zfs - -import ( - "context" - "fmt" - "math" - "path/filepath" - - "github.com/containerd/containerd/mount" - "github.com/containerd/containerd/snapshots" - "github.com/containerd/containerd/snapshots/storage" - "github.com/containerd/log" - "github.com/mistifyio/go-zfs/v3" -) - -const ( - // snapshotSuffix is used as follows: - // active := filepath.Join(dataset.Name, id) - // committed := active + "@" + snapshotSuffix - snapshotSuffix = "snapshot" - - // Using this typed MaxInt64 to prevent integer overlow on 32bit - maxSnapshotSize int64 = math.MaxInt64 -) - -type snapshotter struct { - dataset *zfs.Dataset - ms *storage.MetaStore -} - -// NewSnapshotter returns a Snapshotter using zfs. Uses the provided -// root directory for snapshots and stores the metadata in -// a file in the provided root. -// root needs to be a mount point of zfs. -func NewSnapshotter(root string) (snapshots.Snapshotter, error) { - m, err := mount.Lookup(root) - if err != nil { - return nil, err - } - if m.FSType != "zfs" { - return nil, fmt.Errorf("path %s must be a zfs filesystem to be used with the zfs snapshotter", root) - } - dataset, err := zfs.GetDataset(m.Source) - if err != nil { - return nil, err - } - - ms, err := storage.NewMetaStore(filepath.Join(root, "metadata.db")) - if err != nil { - return nil, err - } - - b := &snapshotter{ - dataset: dataset, - ms: ms, - } - return b, nil -} - -var zfsCreateProperties = map[string]string{ - "mountpoint": "legacy", -} - -// createFilesystem creates but not mount. -func createFilesystem(datasetName string) (*zfs.Dataset, error) { - return zfs.CreateFilesystem(datasetName, zfsCreateProperties) -} - -// cloneFilesystem clones but not mount. -func cloneFilesystem(datasetName string, snapshot *zfs.Dataset) (*zfs.Dataset, error) { - return snapshot.Clone(datasetName, zfsCreateProperties) -} - -func destroy(dataset *zfs.Dataset) error { - return dataset.Destroy(zfs.DestroyDefault) -} - -func destroySnapshot(dataset *zfs.Dataset) error { - return dataset.Destroy(zfs.DestroyDeferDeletion) -} - -// Stat returns the info for an active or committed snapshot by name or -// key. -// -// Should be used for parent resolution, existence checks and to discern -// the kind of snapshot. -func (z *snapshotter) Stat(ctx context.Context, key string) (snapshots.Info, error) { - ctx, t, err := z.ms.TransactionContext(ctx, false) - if err != nil { - return snapshots.Info{}, err - } - defer t.Rollback() //nolint:errcheck - _, info, _, err := storage.GetInfo(ctx, key) - if err != nil { - return snapshots.Info{}, err - } - - return info, nil -} - -// Usage retrieves the disk usage of the top-level snapshot. -func (z *snapshotter) Usage(ctx context.Context, key string) (snapshots.Usage, error) { - return z.usage(ctx, key) -} - -func (z *snapshotter) usage(ctx context.Context, key string) (snapshots.Usage, error) { - ctx, t, err := z.ms.TransactionContext(ctx, false) - if err != nil { - return snapshots.Usage{}, err - } - id, info, usage, err := storage.GetInfo(ctx, key) - t.Rollback() //nolint:errcheck - - if err != nil { - return snapshots.Usage{}, err - } - - if info.Kind == snapshots.KindActive { - activeName := filepath.Join(z.dataset.Name, id) - sDataset, err := zfs.GetDataset(activeName) - if err != nil { - return snapshots.Usage{}, err - } - - if int64(sDataset.Used) > maxSnapshotSize { - return snapshots.Usage{}, fmt.Errorf("Dataset size exceeds maximum snapshot size of %d bytes", maxSnapshotSize) - } - - usage = snapshots.Usage{ - Size: int64(sDataset.Used), - Inodes: -1, - } - } - - return usage, nil -} - -// Walk the committed snapshots. -func (z *snapshotter) Walk(ctx context.Context, fn snapshots.WalkFunc, filters ...string) error { - ctx, t, err := z.ms.TransactionContext(ctx, false) - if err != nil { - return err - } - defer t.Rollback() //nolint:errcheck - return storage.WalkInfo(ctx, fn, filters...) -} - -func (z *snapshotter) Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) { - return z.createSnapshot(ctx, snapshots.KindActive, key, parent, opts...) -} - -func (z *snapshotter) View(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) { - return z.createSnapshot(ctx, snapshots.KindView, key, parent, opts...) -} - -func (z *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) { - ctx, t, err := z.ms.TransactionContext(ctx, true) - if err != nil { - return nil, err - } - defer func() { - if err != nil && t != nil { - if rerr := t.Rollback(); rerr != nil { - log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction") - } - } - }() - - a, err := storage.CreateSnapshot(ctx, kind, key, parent, opts...) - if err != nil { - return nil, err - } - - targetName := filepath.Join(z.dataset.Name, a.ID) - var target *zfs.Dataset - if len(a.ParentIDs) == 0 { - target, err = createFilesystem(targetName) - if err != nil { - return nil, err - } - } else { - parent0Name := filepath.Join(z.dataset.Name, a.ParentIDs[0]) + "@" + snapshotSuffix - parent0, err := zfs.GetDataset(parent0Name) - if err != nil { - return nil, err - } - target, err = cloneFilesystem(targetName, parent0) - if err != nil { - return nil, err - } - } - - err = t.Commit() - t = nil - if err != nil { - if derr := destroy(target); derr != nil { - log.G(ctx).WithError(derr).WithField("targetName", targetName).Error("failed to delete dataset") - } - return nil, err - } - readonly := kind == snapshots.KindView - return z.mounts(target, readonly) -} - -func (z *snapshotter) mounts(dataset *zfs.Dataset, readonly bool) ([]mount.Mount, error) { - var options []string - if readonly { - options = append(options, "ro") - } - return []mount.Mount{ - { - Type: "zfs", - Source: dataset.Name, - Options: options, - }, - }, nil -} - -func (z *snapshotter) Commit(ctx context.Context, name, key string, opts ...snapshots.Opt) (err error) { - usage, err := z.usage(ctx, key) - if err != nil { - return fmt.Errorf("failed to compute usage: %w", err) - } - - ctx, t, err := z.ms.TransactionContext(ctx, true) - if err != nil { - return err - } - defer func() { - if err != nil && t != nil { - if rerr := t.Rollback(); rerr != nil { - log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction") - } - } - }() - - id, err := storage.CommitActive(ctx, key, name, usage, opts...) - if err != nil { - return fmt.Errorf("failed to commit: %w", err) - } - - activeName := filepath.Join(z.dataset.Name, id) - active, err := zfs.GetDataset(activeName) - if err != nil { - return err - } - snapshot, err := active.Snapshot(snapshotSuffix, false) - if err != nil { - return err - } - err = t.Commit() - t = nil - if err != nil { - snapshotName := activeName + "@" + snapshotSuffix - if derr := destroySnapshot(snapshot); derr != nil { - log.G(ctx).WithError(derr).WithField("snapshotName", snapshotName).Error("failed to delete dataset") - } - return err - } - return nil -} - -// Mounts returns the mounts for the transaction identified by key. Can be -// called on an read-write or readonly transaction. -// -// This can be used to recover mounts after calling View or Prepare. -func (z *snapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, error) { - ctx, t, err := z.ms.TransactionContext(ctx, false) - if err != nil { - return nil, err - } - s, err := storage.GetSnapshot(ctx, key) - t.Rollback() //nolint:errcheck - if err != nil { - return nil, fmt.Errorf("failed to get active snapshot: %w", err) - } - sName := filepath.Join(z.dataset.Name, s.ID) - sDataset, err := zfs.GetDataset(sName) - if err != nil { - return nil, err - } - return z.mounts(sDataset, false) -} - -// Remove abandons the transaction identified by key. All resources -// associated with the key will be removed. -func (z *snapshotter) Remove(ctx context.Context, key string) (err error) { - ctx, t, err := z.ms.TransactionContext(ctx, true) - if err != nil { - return err - } - defer func() { - if err != nil && t != nil { - if rerr := t.Rollback(); rerr != nil { - log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction") - } - } - // FIXME: rolling back the removed ZFS dataset is unsupported yet - }() - - id, k, err := storage.Remove(ctx, key) - if err != nil { - return fmt.Errorf("failed to remove snapshot: %w", err) - } - - datasetName := filepath.Join(z.dataset.Name, id) - if k == snapshots.KindCommitted { - snapshotName := datasetName + "@" + snapshotSuffix - snapshot, err := zfs.GetDataset(snapshotName) - if err != nil { - return err - } - if err = destroySnapshot(snapshot); err != nil { - return err - } - } - dataset, err := zfs.GetDataset(datasetName) - if err != nil { - return err - } - if err = destroy(dataset); err != nil { - return err - } - err = t.Commit() - t = nil - return err -} - -func (o *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpaths ...string) (snapshots.Info, error) { - ctx, t, err := o.ms.TransactionContext(ctx, true) - if err != nil { - return snapshots.Info{}, err - } - - info, err = storage.UpdateInfo(ctx, info, fieldpaths...) - if err != nil { - t.Rollback() //nolint:errcheck - return snapshots.Info{}, err - } - - if err := t.Commit(); err != nil { - return snapshots.Info{}, err - } - - return info, nil -} - -func (o *snapshotter) Close() error { - return o.ms.Close() -} diff --git a/vendor/github.com/mistifyio/go-zfs/v3/.envrc b/vendor/github.com/mistifyio/go-zfs/v3/.envrc deleted file mode 100644 index f310aea66..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/.envrc +++ /dev/null @@ -1,4 +0,0 @@ -has nix && use nix -dotenv_if_exists -PATH_add bin -path_add GOBIN bin diff --git a/vendor/github.com/mistifyio/go-zfs/v3/.gitignore b/vendor/github.com/mistifyio/go-zfs/v3/.gitignore deleted file mode 100644 index 0867490ad..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -bin -go-zfs.test -.vagrant - -# added by lint-install -out/ diff --git a/vendor/github.com/mistifyio/go-zfs/v3/.golangci.yml b/vendor/github.com/mistifyio/go-zfs/v3/.golangci.yml deleted file mode 100644 index 499c3eca1..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/.golangci.yml +++ /dev/null @@ -1,207 +0,0 @@ -run: - # The default runtime timeout is 1m, which doesn't work well on Github Actions. - timeout: 4m - -# NOTE: This file is populated by the lint-install tool. Local adjustments may be overwritten. -linters-settings: - cyclop: - # NOTE: This is a very high transitional threshold - max-complexity: 37 - package-average: 34.0 - skip-tests: true - - gocognit: - # NOTE: This is a very high transitional threshold - min-complexity: 98 - - dupl: - threshold: 200 - - goconst: - min-len: 4 - min-occurrences: 5 - ignore-tests: true - - gosec: - excludes: - - G107 # Potential HTTP request made with variable url - - G204 # Subprocess launched with function call as argument or cmd arguments - - G404 # Use of weak random number generator (math/rand instead of crypto/rand - - errorlint: - # these are still common in Go: for instance, exit errors. - asserts: false - - exhaustive: - default-signifies-exhaustive: true - - nestif: - min-complexity: 8 - - nolintlint: - require-explanation: true - allow-unused: false - require-specific: true - - revive: - ignore-generated-header: true - severity: warning - rules: - - name: atomic - - name: blank-imports - - name: bool-literal-in-expr - - name: confusing-naming - - name: constant-logical-expr - - name: context-as-argument - - name: context-keys-type - - name: deep-exit - - name: defer - - name: range-val-in-closure - - name: range-val-address - - name: dot-imports - - name: error-naming - - name: error-return - - name: error-strings - - name: errorf - - name: exported - - name: identical-branches - - name: if-return - - name: import-shadowing - - name: increment-decrement - - name: indent-error-flow - - name: indent-error-flow - - name: package-comments - - name: range - - name: receiver-naming - - name: redefines-builtin-id - - name: superfluous-else - - name: struct-tag - - name: time-naming - - name: unexported-naming - - name: unexported-return - - name: unnecessary-stmt - - name: unreachable-code - - name: unused-parameter - - name: var-declaration - - name: var-naming - - name: unconditional-recursion - - name: waitgroup-by-value - - staticcheck: - go: "1.16" - - unused: - go: "1.16" - -output: - sort-results: true - -linters: - disable-all: true - enable: - - asciicheck - - bodyclose - - cyclop - - deadcode - - dogsled - - dupl - - durationcheck - - errcheck - - errname - - errorlint - - exhaustive - - exportloopref - - forcetypeassert - - gocognit - - goconst - - gocritic - - godot - - gofmt - - gofumpt - - gosec - - goheader - - goimports - - goprintffuncname - - gosimple - - govet - - ifshort - - importas - - ineffassign - - makezero - - misspell - - nakedret - - nestif - - nilerr - - noctx - - nolintlint - - predeclared - # disabling for the initial iteration of the linting tool - # - promlinter - - revive - - rowserrcheck - - sqlclosecheck - - staticcheck - - structcheck - - stylecheck - - thelper - - tparallel - - typecheck - - unconvert - - unparam - - unused - - varcheck - - wastedassign - - whitespace - - # Disabled linters, due to being misaligned with Go practices - # - exhaustivestruct - # - gochecknoglobals - # - gochecknoinits - # - goconst - # - godox - # - goerr113 - # - gomnd - # - lll - # - nlreturn - # - testpackage - # - wsl - # Disabled linters, due to not being relevant to our code base: - # - maligned - # - prealloc "For most programs usage of prealloc will be a premature optimization." - # Disabled linters due to bad error messages or bugs - # - tagliatelle - -issues: - # Excluding configuration per-path, per-linter, per-text and per-source - exclude-rules: - - path: _test\.go - linters: - - dupl - - errcheck - - forcetypeassert - - gocyclo - - gosec - - noctx - - - path: .*cmd.* - linters: - - noctx - - - path: main\.go - linters: - - noctx - - - path: .*cmd.* - text: "deep-exit" - - - path: main\.go - text: "deep-exit" - - # This check is of questionable value - - linters: - - tparallel - text: "call t.Parallel on the top level as well as its subtests" - - # Don't hide lint issues just because there are many of them - max-same-issues: 0 - max-issues-per-linter: 0 diff --git a/vendor/github.com/mistifyio/go-zfs/v3/.yamllint b/vendor/github.com/mistifyio/go-zfs/v3/.yamllint deleted file mode 100644 index 9a08ad176..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/.yamllint +++ /dev/null @@ -1,16 +0,0 @@ ---- -extends: default - -rules: - braces: - max-spaces-inside: 1 - brackets: - max-spaces-inside: 1 - comments: disable - comments-indentation: disable - document-start: disable - line-length: - level: warning - max: 160 - allow-non-breakable-inline-mappings: true - truthy: disable diff --git a/vendor/github.com/mistifyio/go-zfs/v3/CHANGELOG.md b/vendor/github.com/mistifyio/go-zfs/v3/CHANGELOG.md deleted file mode 100644 index 349245d03..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/CHANGELOG.md +++ /dev/null @@ -1,250 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -This project adheres to [Semantic Versioning](http://semver.org/). -This change log follows the advice of [Keep a CHANGELOG](https://github.com/olivierlacan/keep-a-changelog). - -## [Unreleased] - -## [3.0.0] - 2022-03-30 - -### Added - -- Rename, Mount and Unmount methods -- Parse more fields into Zpool type: - - dedupratio - - fragmentation - - freeing - - leaked - - readonly -- Parse more fields into Dataset type: - - referenced -- Incremental Send -- Parse numbers in exact format -- Support for Solaris (non-blockint, best-effort status) -- Debug logging for command invocation -- Use GitHub Actions for CI -- Nix shell for dev env reproducibility -- Direnv file for ease of dev -- Formatting/lint checks (enforced by CI) -- Go Module -- FreeBSD based vagrant machine - -### Changed - -- Temporarily adjust TestDiff expected strings depending on ZFS version -- Use one `zfs list`/`zpool list` call instead of many `zfs get`/`zpool get` -- ZFS docs links now point to OpenZFS pages -- Ubuntu vagrant box changed to generic/ubuntu2004 - -### Fixed - -- `GetProperty` returning `VALUE` instead of the actual value - -### Shortlog - - Amit Krishnan (1): - Issue #39 and Issue #40 - Enable Solaris support for go-zfs Switch from zfs/zpool get to zfs/zpool list for better performance Signed-off-by: Amit Krishnan - - Anand Patil (3): - Added Rename - Small fix to rename. - Added mount and umount methods - - Brian Akins (1): - Add 'referenced' to zfs properties - - Brian Bickerton (3): - Add debug logging before and after running external zfs command - Don't export the default no-op logger - Update uuid package repo url - - Dmitry Teselkin (1): - Issue #52 - fix parseLine for fragmentation field - - Edward Betts (1): - correct spelling mistake - - Justin Cormack (1): - Switch to google/uuid which is the maintained version of pborman/uuid - - Manuel Mendez (40): - rename Umount -> Unmount to follow zfs command name - add missing Unmount/Mount docs - always allocate largest Mount slice - add travis config - travis: update to go 1.7 - travis: get go deps first - test: add nok helper to verify an error occurred - test: add test for Dataset.GetProperty - ci: swap #cerana on freenode for slack - ci: install new deps for 0.7 relases - ci: bump zol versions - ci: bump go versions - ci: use better gometalinter invocations - ci: add ccache - ci: set env earlier in before_install - fix test nok error printing - test: restructure TestDiff to deal with different order of changes - test: better unicode path handling in TestDiff - travis: bump zfs and go versions - cache zfs artifacts - Add nix-shell and direnv goodness - prettierify all the files - Add go based tools - Add Makefile and rules.mk files - gofumptize the code base - Use tinkerbell/lint-install to setup linters - make golangci-lint happy - Update CONTRIBUTING.md with make based approach - Add GitHub Actions - Drop Travis CI - One sentence per line - Update documentation links to openzfs-docs pages - Format Vagrantfile using rufo - Add go-zfs.test to .gitignore - test: Avoid reptitive/duplicate error logging and quitting - test: Use t.Logf instead of fmt.Printf - test: Better cleanup and error handling in zpoolTest - test: Do not mark TestDatasets as a t.Helper. - test: Change zpoolTest to a pure helper that returns a clean up function - test: Move helpers to a different file - vagrant: Add set -euxo pipefail to provision script - vagrant: Update to generic/ubuntu2004 - vagrant: Minor fixes to Vagrantfile - vagrant: Update to go 1.17.8 - vagrant: Run go tests as part of provision script - vagrant: Indent heredoc script - vagrant: Add freebsd machine - - Matt Layher (1): - Parse more fields into Zpool type - - Michael Crosby (1): - Add incremental send - - Rikard Gynnerstedt (1): - remove command name from joined args - - Sebastiaan van Stijn (1): - Add go.mod and rename to github.com/mistifyio/go-zfs/v3 (v3.0.0) - - mikudeko (1): - Fix GetProperty always returning 'VALUE' - -## [2.1.1] - 2015-05-29 - -### Fixed - -- Ignoring first pool listed -- Incorrect `zfs get` argument ordering - -### Shortlog - - Alexey Guskov (1): - zfs command uses different order of arguments on freebsd - - Brian Akins (4): - test that ListZpools returns expected zpool - test error first - test error first - fix test to check correct return value - - James Cunningham (1): - Fix Truncating First Zpool - - Pat Norton (2): - Added Use of Go Tools - Update CONTRIBUTING.md - -## [2.1.0] - 2014-12-08 - -### Added - -- Parse hardlink modification count returned from `zfs diff` - -### Fixed - -- Continuing instead of erroring when rolling back a non-snapshot - -### Shortlog - - Brian Akins (2): - need to return the error here - use named struct fields - - Jörg Thalheim (1): - zfs diff handle hardlinks modification now - -## [2.0.0] - 2014-12-02 - -### Added - -- Flags for Destroy: - - DESTROY_DEFAULT - - DESTROY_DEFER_DELETION (`zfs destroy ... -d`) - - DESTROY_FORCE (`zfs destroy ... -f`) - - DESTROY_RECURSIVE_CLONES (`zfs destroy ... -R`) - - DESTROY_RECURSIVE (`zfs destroy ... -r`) - - etc -- Diff method (`zfs diff`) -- LogicalUsed and Origin properties to Dataset -- Type constants for Dataset -- State constants for Zpool -- Logger interface -- Improve documentation - -### Shortlog - - Brian Akins (8): - remove reflection - style change for switches - need to check for error - keep in scope - go 1.3.3 - golint cleanup - Just test if logical used is greater than 0, as this appears to be implementation specific - add docs to satisfy golint - - Jörg Thalheim (8): - Add deferred flag to zfs.Destroy() - add Logicalused property - Add Origin property - gofmt - Add zfs.Diff - Add Logger - add recursive destroy with clones - use CamelCase-style constants - - Matt Layher (4): - Improve documentation, document common ZFS operations, provide more references - Add zpool state constants, for easier health checking - Add dataset type constants, for easier type checking - Fix string split in command.Run(), use strings.Fields() instead of strings.Split() - -## [1.0.0] - 2014-11-12 - -### Shortlog - - Brian Akins (7): - add godoc badge - Add example - add information about zpool to struct and parser - Add Quota - add Children call - add Children call - fix snapshot tests - - Brian Bickerton (3): - MIST-150 Change Snapshot second paramater from properties map[string][string] to recursive bool - MIST-150 Add Rollback method and related tests - MIST-160 Add SendSnapshot streaming method and tests - - Matt Layher (1): - Add Error struct type and tests, enabling easier error return checking - -[3.0.0]: https://github.com/mistifyio/go-zfs/compare/v2.1.1...v3.0.0 -[2.1.1]: https://github.com/mistifyio/go-zfs/compare/v2.1.0...v2.1.1 -[2.1.0]: https://github.com/mistifyio/go-zfs/compare/v2.0.0...v2.1.0 -[2.0.0]: https://github.com/mistifyio/go-zfs/compare/v1.0.0...v2.0.0 -[1.0.0]: https://github.com/mistifyio/go-zfs/compare/v0.0.0...v1.0.0 diff --git a/vendor/github.com/mistifyio/go-zfs/v3/CONTRIBUTING.md b/vendor/github.com/mistifyio/go-zfs/v3/CONTRIBUTING.md deleted file mode 100644 index 9f625d564..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/CONTRIBUTING.md +++ /dev/null @@ -1,64 +0,0 @@ -## How to Contribute - -We always welcome contributions to help make `go-zfs` better. -Please take a moment to read this document if you would like to contribute. - -### Reporting issues - -We use [Github issues](https://github.com/mistifyio/go-zfs/issues) to track bug reports, feature requests, and submitting pull requests. - -If you find a bug: - -- Use the GitHub issue search to check whether the bug has already been reported. -- If the issue has been fixed, try to reproduce the issue using the latest `master` branch of the repository. -- If the issue still reproduces or has not yet been reported, try to isolate the problem before opening an issue, if possible. Also provide the steps taken to reproduce the bug. - -### Pull requests - -We welcome bug fixes, improvements, and new features. -Before embarking on making significant changes, please open an issue and ask first so that you do not risk duplicating efforts or spending time working on something that may be out of scope. -For minor items, just open a pull request. - -[Fork the project](https://help.github.com/articles/fork-a-repo), clone your fork, and add the upstream to your remote: - - $ git clone git@github.com:/go-zfs.git - $ cd go-zfs - $ git remote add upstream https://github.com/mistifyio/go-zfs.git - -If you need to pull new changes committed upstream: - - $ git checkout master - $ git fetch upstream - $ git merge upstream/master - -Don' work directly on master as this makes it harder to merge later. -Create a feature branch for your fix or new feature: - - $ git checkout -b - -Please try to commit your changes in logical chunks. -Ideally, you should include the issue number in the commit message. - - $ git commit -m "Issue # - " - -Push your feature branch to your fork. - - $ git push origin - -[Open a Pull Request](https://help.github.com/articles/using-pull-requests) against the upstream master branch. -Please give your pull request a clear title and description and note which issue(s) your pull request fixes. - -- All linters should be happy (can be run with `make verify`). -- Every exported function should have [documentation](http://blog.golang.org/godoc-documenting-go-code) and corresponding [tests](http://golang.org/doc/code.html#Testing). - -**Important:** By submitting a patch, you agree to allow the project owners to license your work under the [Apache 2.0 License](./LICENSE). - -### Go Tools - -For consistency and to catch minor issues for all of go code, please run `make verify`. - -Many editors can execute the above on save. - ---- - -Guidelines based on http://azkaban.github.io/contributing.html diff --git a/vendor/github.com/mistifyio/go-zfs/v3/LICENSE b/vendor/github.com/mistifyio/go-zfs/v3/LICENSE deleted file mode 100644 index f4c265cfe..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright (c) 2014, OmniTI Computer Consulting, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/vendor/github.com/mistifyio/go-zfs/v3/Makefile b/vendor/github.com/mistifyio/go-zfs/v3/Makefile deleted file mode 100644 index 1c5f55e8c..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -help: ## Print this help - @grep --no-filename -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sed 's/:.*## /·/' | sort | column -t -W 2 -s '·' -c $(shell tput cols) - -all: test ## Run tests - --include rules.mk --include lint.mk - -test: ## Run tests - go test ./... - -verify: gofumpt prettier lint ## Verify code style, is lint free, freshness ... - git diff | (! grep .) - -fix: gofumpt-fix prettier-fix ## Fix code formatting errors - -tools: ${toolsBins} ## Build Go based build tools - -.PHONY: all help test tools verify diff --git a/vendor/github.com/mistifyio/go-zfs/v3/README.md b/vendor/github.com/mistifyio/go-zfs/v3/README.md deleted file mode 100644 index c91183300..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Go Wrapper for ZFS - -Simple wrappers for ZFS command line tools. - -[![GoDoc](https://godoc.org/github.com/mistifyio/go-zfs?status.svg)](https://godoc.org/github.com/mistifyio/go-zfs) - -## Requirements - -You need a working ZFS setup. To use on Ubuntu 14.04, setup ZFS: - - sudo apt-get install python-software-properties - sudo apt-add-repository ppa:zfs-native/stable - sudo apt-get update - sudo apt-get install ubuntu-zfs libzfs-dev - -Developed using Go 1.3, but currently there isn't anything 1.3 specific. Don't use Ubuntu packages for Go, use http://golang.org/doc/install - -Generally you need root privileges to use anything zfs related. - -## Status - -This has been only been tested on Ubuntu 14.04 - -In the future, we hope to work directly with libzfs. - -# Hacking - -The tests have decent examples for most functions. - -```go -//assuming a zpool named test -//error handling omitted - - -f, err := zfs.CreateFilesystem("test/snapshot-test", nil) -ok(t, err) - -s, err := f.Snapshot("test", nil) -ok(t, err) - -// snapshot is named "test/snapshot-test@test" - -c, err := s.Clone("test/clone-test", nil) - -err := c.Destroy() -err := s.Destroy() -err := f.Destroy() - -``` - -# Contributing - -See the [contributing guidelines](./CONTRIBUTING.md) diff --git a/vendor/github.com/mistifyio/go-zfs/v3/Vagrantfile b/vendor/github.com/mistifyio/go-zfs/v3/Vagrantfile deleted file mode 100644 index 7d8d2decd..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/Vagrantfile +++ /dev/null @@ -1,33 +0,0 @@ -GOVERSION = "1.17.8" - -Vagrant.configure("2") do |config| - config.vm.define "ubuntu" do |ubuntu| - ubuntu.vm.box = "generic/ubuntu2004" - end - config.vm.define "freebsd" do |freebsd| - freebsd.vm.box = "generic/freebsd13" - end - config.ssh.forward_agent = true - config.vm.synced_folder ".", "/home/vagrant/go/src/github.com/mistifyio/go-zfs", create: true - config.vm.provision "shell", inline: <<-EOF - set -euxo pipefail - - os=$(uname -s|tr '[A-Z]' '[a-z]') - case $os in - linux) apt-get update -y && apt-get install -y --no-install-recommends gcc libc-dev zfsutils-linux ;; - esac - - cd /tmp - curl -fLO --retry-max-time 30 --retry 10 https://go.dev/dl/go#{GOVERSION}.$os-amd64.tar.gz - tar -C /usr/local -zxf go#{GOVERSION}.$os-amd64.tar.gz - ln -nsf /usr/local/go/bin/go /usr/local/bin/go - rm -rf go*.tar.gz - - chown -R vagrant:vagrant /home/vagrant/go - cd /home/vagrant/go/src/github.com/mistifyio/go-zfs - go test -c - sudo ./go-zfs.test -test.v - CGO_ENABLED=0 go test -c - sudo ./go-zfs.test -test.v - EOF -end diff --git a/vendor/github.com/mistifyio/go-zfs/v3/error.go b/vendor/github.com/mistifyio/go-zfs/v3/error.go deleted file mode 100644 index 5408ccdb5..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/error.go +++ /dev/null @@ -1,18 +0,0 @@ -package zfs - -import ( - "fmt" -) - -// Error is an error which is returned when the `zfs` or `zpool` shell -// commands return with a non-zero exit code. -type Error struct { - Err error - Debug string - Stderr string -} - -// Error returns the string representation of an Error. -func (e Error) Error() string { - return fmt.Sprintf("%s: %q => %s", e.Err, e.Debug, e.Stderr) -} diff --git a/vendor/github.com/mistifyio/go-zfs/v3/lint.mk b/vendor/github.com/mistifyio/go-zfs/v3/lint.mk deleted file mode 100644 index a1e0a4fd3..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/lint.mk +++ /dev/null @@ -1,75 +0,0 @@ -# BEGIN: lint-install -makefile lint.mk . -# http://github.com/tinkerbell/lint-install - -.PHONY: lint -lint: _lint - -LINT_ARCH := $(shell uname -m) -LINT_OS := $(shell uname) -LINT_OS_LOWER := $(shell echo $(LINT_OS) | tr '[:upper:]' '[:lower:]') -LINT_ROOT := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) - -# shellcheck and hadolint lack arm64 native binaries: rely on x86-64 emulation -ifeq ($(LINT_OS),Darwin) - ifeq ($(LINT_ARCH),arm64) - LINT_ARCH=x86_64 - endif -endif - -LINTERS := -FIXERS := - -SHELLCHECK_VERSION ?= v0.8.0 -SHELLCHECK_BIN := out/linters/shellcheck-$(SHELLCHECK_VERSION)-$(LINT_ARCH) -$(SHELLCHECK_BIN): - mkdir -p out/linters - rm -rf out/linters/shellcheck-* - curl -sSfL https://github.com/koalaman/shellcheck/releases/download/$(SHELLCHECK_VERSION)/shellcheck-$(SHELLCHECK_VERSION).$(LINT_OS_LOWER).$(LINT_ARCH).tar.xz | tar -C out/linters -xJf - - mv out/linters/shellcheck-$(SHELLCHECK_VERSION)/shellcheck $@ - rm -rf out/linters/shellcheck-$(SHELLCHECK_VERSION)/shellcheck - -LINTERS += shellcheck-lint -shellcheck-lint: $(SHELLCHECK_BIN) - $(SHELLCHECK_BIN) $(shell find . -name "*.sh") - -FIXERS += shellcheck-fix -shellcheck-fix: $(SHELLCHECK_BIN) - $(SHELLCHECK_BIN) $(shell find . -name "*.sh") -f diff | { read -t 1 line || exit 0; { echo "$$line" && cat; } | git apply -p2; } - -GOLANGCI_LINT_CONFIG := $(LINT_ROOT)/.golangci.yml -GOLANGCI_LINT_VERSION ?= v1.43.0 -GOLANGCI_LINT_BIN := out/linters/golangci-lint-$(GOLANGCI_LINT_VERSION)-$(LINT_ARCH) -$(GOLANGCI_LINT_BIN): - mkdir -p out/linters - rm -rf out/linters/golangci-lint-* - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b out/linters $(GOLANGCI_LINT_VERSION) - mv out/linters/golangci-lint $@ - -LINTERS += golangci-lint-lint -golangci-lint-lint: $(GOLANGCI_LINT_BIN) - find . -name go.mod -execdir "$(GOLANGCI_LINT_BIN)" run -c "$(GOLINT_CONFIG)" \; - -FIXERS += golangci-lint-fix -golangci-lint-fix: $(GOLANGCI_LINT_BIN) - find . -name go.mod -execdir "$(GOLANGCI_LINT_BIN)" run -c "$(GOLINT_CONFIG)" --fix \; - -YAMLLINT_VERSION ?= 1.26.3 -YAMLLINT_ROOT := out/linters/yamllint-$(YAMLLINT_VERSION) -YAMLLINT_BIN := $(YAMLLINT_ROOT)/dist/bin/yamllint -$(YAMLLINT_BIN): - mkdir -p out/linters - rm -rf out/linters/yamllint-* - curl -sSfL https://github.com/adrienverge/yamllint/archive/refs/tags/v$(YAMLLINT_VERSION).tar.gz | tar -C out/linters -zxf - - cd $(YAMLLINT_ROOT) && pip3 install --target dist . - -LINTERS += yamllint-lint -yamllint-lint: $(YAMLLINT_BIN) - PYTHONPATH=$(YAMLLINT_ROOT)/dist $(YAMLLINT_ROOT)/dist/bin/yamllint . - -.PHONY: _lint $(LINTERS) -_lint: $(LINTERS) - -.PHONY: fix $(FIXERS) -fix: $(FIXERS) - -# END: lint-install -makefile lint.mk . diff --git a/vendor/github.com/mistifyio/go-zfs/v3/rules.mk b/vendor/github.com/mistifyio/go-zfs/v3/rules.mk deleted file mode 100644 index 4746c978a..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/rules.mk +++ /dev/null @@ -1,49 +0,0 @@ -# Only use the recipes defined in these makefiles -MAKEFLAGS += --no-builtin-rules -.SUFFIXES: -# Delete target files if there's an error -# This avoids a failure to then skip building on next run if the output is created by shell redirection for example -# Not really necessary for now, but just good to have already if it becomes necessary later. -.DELETE_ON_ERROR: -# Treat the whole recipe as a one shell script/invocation instead of one-per-line -.ONESHELL: -# Use bash instead of plain sh -SHELL := bash -.SHELLFLAGS := -o pipefail -euc - -version := $(shell git rev-parse --short HEAD) -tag := $(shell git tag --points-at HEAD) -ifneq (,$(tag)) -version := $(tag)-$(version) -endif -LDFLAGS := -ldflags "-X main.version=$(version)" -export CGO_ENABLED := 0 - -ifeq ($(origin GOBIN), undefined) -GOBIN := ${PWD}/bin -export GOBIN -PATH := ${GOBIN}:${PATH} -export PATH -endif - -toolsBins := $(addprefix bin/,$(notdir $(shell grep '^\s*_' tooling/tools.go | awk -F'"' '{print $$2}'))) - -# installs cli tools defined in tools.go -$(toolsBins): tooling/go.mod tooling/go.sum tooling/tools.go -$(toolsBins): CMD=$(shell awk -F'"' '/$(@F)"/ {print $$2}' tooling/tools.go) -$(toolsBins): - cd tooling && go install $(CMD) - -.PHONY: gofumpt -gofumpt: bin/gofumpt - gofumpt -s -d . - -gofumpt-fix: bin/gofumpt - gofumpt -s -w . - -.PHONY: prettier prettier-fix -prettier: - prettier --list-different --ignore-path .gitignore . - -prettier-fix: - prettier --write --ignore-path .gitignore . diff --git a/vendor/github.com/mistifyio/go-zfs/v3/shell.nix b/vendor/github.com/mistifyio/go-zfs/v3/shell.nix deleted file mode 100644 index e0ea24c16..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/shell.nix +++ /dev/null @@ -1,26 +0,0 @@ -let _pkgs = import { }; -in { pkgs ? import (_pkgs.fetchFromGitHub { - owner = "NixOS"; - repo = "nixpkgs"; - #branch@date: 21.11@2022-02-13 - rev = "560ad8a2f89586ab1a14290f128ad6a393046065"; - sha256 = "0s0dv1clfpjyzy4p6ywxvzmwx9ddbr2yl77jf1wqdbr0x1206hb8"; -}) { } }: - -with pkgs; - -mkShell { - buildInputs = [ - git - gnumake - gnused - go - nixfmt - nodePackages.prettier - python3Packages.pip - python3Packages.setuptools - rufo - shfmt - vagrant - ]; -} diff --git a/vendor/github.com/mistifyio/go-zfs/v3/utils.go b/vendor/github.com/mistifyio/go-zfs/v3/utils.go deleted file mode 100644 index b69942b53..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/utils.go +++ /dev/null @@ -1,357 +0,0 @@ -package zfs - -import ( - "bytes" - "errors" - "fmt" - "io" - "os/exec" - "regexp" - "runtime" - "strconv" - "strings" - - "github.com/google/uuid" -) - -type command struct { - Command string - Stdin io.Reader - Stdout io.Writer -} - -func (c *command) Run(arg ...string) ([][]string, error) { - cmd := exec.Command(c.Command, arg...) - - var stdout, stderr bytes.Buffer - - if c.Stdout == nil { - cmd.Stdout = &stdout - } else { - cmd.Stdout = c.Stdout - } - - if c.Stdin != nil { - cmd.Stdin = c.Stdin - } - cmd.Stderr = &stderr - - id := uuid.New().String() - joinedArgs := cmd.Path - if len(cmd.Args) > 1 { - joinedArgs = strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ") - } - - logger.Log([]string{"ID:" + id, "START", joinedArgs}) - if err := cmd.Run(); err != nil { - return nil, &Error{ - Err: err, - Debug: joinedArgs, - Stderr: stderr.String(), - } - } - logger.Log([]string{"ID:" + id, "FINISH"}) - - // assume if you passed in something for stdout, that you know what to do with it - if c.Stdout != nil { - return nil, nil - } - - lines := strings.Split(stdout.String(), "\n") - - // last line is always blank - lines = lines[0 : len(lines)-1] - output := make([][]string, len(lines)) - - for i, l := range lines { - output[i] = strings.Split(l, "\t") - } - - return output, nil -} - -func setString(field *string, value string) { - v := "" - if value != "-" { - v = value - } - *field = v -} - -func setUint(field *uint64, value string) error { - var v uint64 - if value != "-" { - var err error - v, err = strconv.ParseUint(value, 10, 64) - if err != nil { - return err - } - } - *field = v - return nil -} - -func (d *Dataset) parseLine(line []string) error { - var err error - - if len(line) != len(dsPropList) { - return errors.New("output does not match what is expected on this platform") - } - setString(&d.Name, line[0]) - setString(&d.Origin, line[1]) - - if err = setUint(&d.Used, line[2]); err != nil { - return err - } - if err = setUint(&d.Avail, line[3]); err != nil { - return err - } - - setString(&d.Mountpoint, line[4]) - setString(&d.Compression, line[5]) - setString(&d.Type, line[6]) - - if err = setUint(&d.Volsize, line[7]); err != nil { - return err - } - if err = setUint(&d.Quota, line[8]); err != nil { - return err - } - if err = setUint(&d.Referenced, line[9]); err != nil { - return err - } - - if runtime.GOOS == "solaris" { - return nil - } - - if err = setUint(&d.Written, line[10]); err != nil { - return err - } - if err = setUint(&d.Logicalused, line[11]); err != nil { - return err - } - return setUint(&d.Usedbydataset, line[12]) -} - -/* - * from zfs diff`s escape function: - * - * Prints a file name out a character at a time. If the character is - * not in the range of what we consider "printable" ASCII, display it - * as an escaped 3-digit octal value. ASCII values less than a space - * are all control characters and we declare the upper end as the - * DELete character. This also is the last 7-bit ASCII character. - * We choose to treat all 8-bit ASCII as not printable for this - * application. - */ -func unescapeFilepath(path string) (string, error) { - buf := make([]byte, 0, len(path)) - llen := len(path) - for i := 0; i < llen; { - if path[i] == '\\' { - if llen < i+4 { - return "", fmt.Errorf("invalid octal code: too short") - } - octalCode := path[(i + 1):(i + 4)] - val, err := strconv.ParseUint(octalCode, 8, 8) - if err != nil { - return "", fmt.Errorf("invalid octal code: %w", err) - } - buf = append(buf, byte(val)) - i += 4 - } else { - buf = append(buf, path[i]) - i++ - } - } - return string(buf), nil -} - -var changeTypeMap = map[string]ChangeType{ - "-": Removed, - "+": Created, - "M": Modified, - "R": Renamed, -} - -var inodeTypeMap = map[string]InodeType{ - "B": BlockDevice, - "C": CharacterDevice, - "/": Directory, - ">": Door, - "|": NamedPipe, - "@": SymbolicLink, - "P": EventPort, - "=": Socket, - "F": File, -} - -// matches (+1) or (-1). -var referenceCountRegex = regexp.MustCompile(`\(([+-]\d+?)\)`) - -func parseReferenceCount(field string) (int, error) { - matches := referenceCountRegex.FindStringSubmatch(field) - if matches == nil { - return 0, fmt.Errorf("regexp does not match") - } - return strconv.Atoi(matches[1]) -} - -func parseInodeChange(line []string) (*InodeChange, error) { - llen := len(line) // nolint:ifshort // llen *is* actually used - if llen < 1 { - return nil, fmt.Errorf("empty line passed") - } - - changeType := changeTypeMap[line[0]] - if changeType == 0 { - return nil, fmt.Errorf("unknown change type '%s'", line[0]) - } - - switch changeType { - case Renamed: - if llen != 4 { - return nil, fmt.Errorf("mismatching number of fields: expect 4, got: %d", llen) - } - case Modified: - if llen != 4 && llen != 3 { - return nil, fmt.Errorf("mismatching number of fields: expect 3..4, got: %d", llen) - } - default: - if llen != 3 { - return nil, fmt.Errorf("mismatching number of fields: expect 3, got: %d", llen) - } - } - - inodeType := inodeTypeMap[line[1]] - if inodeType == 0 { - return nil, fmt.Errorf("unknown inode type '%s'", line[1]) - } - - path, err := unescapeFilepath(line[2]) - if err != nil { - return nil, fmt.Errorf("failed to parse filename: %w", err) - } - - var newPath string - var referenceCount int - switch changeType { - case Renamed: - newPath, err = unescapeFilepath(line[3]) - if err != nil { - return nil, fmt.Errorf("failed to parse filename: %w", err) - } - case Modified: - if llen == 4 { - referenceCount, err = parseReferenceCount(line[3]) - if err != nil { - return nil, fmt.Errorf("failed to parse reference count: %w", err) - } - } - default: - newPath = "" - } - - return &InodeChange{ - Change: changeType, - Type: inodeType, - Path: path, - NewPath: newPath, - ReferenceCountChange: referenceCount, - }, nil -} - -// example input for parseInodeChanges -// M / /testpool/bar/ -// + F /testpool/bar/hello.txt -// M / /testpool/bar/hello.txt (+1) -// M / /testpool/bar/hello-hardlink - -func parseInodeChanges(lines [][]string) ([]*InodeChange, error) { - changes := make([]*InodeChange, len(lines)) - - for i, line := range lines { - c, err := parseInodeChange(line) - if err != nil { - return nil, fmt.Errorf("failed to parse line %d of zfs diff: %w, got: '%s'", i, err, line) - } - changes[i] = c - } - return changes, nil -} - -func listByType(t, filter string) ([]*Dataset, error) { - args := []string{"list", "-rHp", "-t", t, "-o", dsPropListOptions} - - if filter != "" { - args = append(args, filter) - } - out, err := zfsOutput(args...) - if err != nil { - return nil, err - } - - var datasets []*Dataset - - name := "" - var ds *Dataset - for _, line := range out { - if name != line[0] { - name = line[0] - ds = &Dataset{Name: name} - datasets = append(datasets, ds) - } - if err := ds.parseLine(line); err != nil { - return nil, err - } - } - - return datasets, nil -} - -func propsSlice(properties map[string]string) []string { - args := make([]string, 0, len(properties)*3) - for k, v := range properties { - args = append(args, "-o") - args = append(args, fmt.Sprintf("%s=%s", k, v)) - } - return args -} - -func (z *Zpool) parseLine(line []string) error { - prop := line[1] - val := line[2] - - var err error - - switch prop { - case "name": - setString(&z.Name, val) - case "health": - setString(&z.Health, val) - case "allocated": - err = setUint(&z.Allocated, val) - case "size": - err = setUint(&z.Size, val) - case "free": - err = setUint(&z.Free, val) - case "fragmentation": - // Trim trailing "%" before parsing uint - i := strings.Index(val, "%") - if i < 0 { - i = len(val) - } - err = setUint(&z.Fragmentation, val[:i]) - case "readonly": - z.ReadOnly = val == "on" - case "freeing": - err = setUint(&z.Freeing, val) - case "leaked": - err = setUint(&z.Leaked, val) - case "dedupratio": - // Trim trailing "x" before parsing float64 - z.DedupRatio, err = strconv.ParseFloat(val[:len(val)-1], 64) - } - return err -} diff --git a/vendor/github.com/mistifyio/go-zfs/v3/utils_notsolaris.go b/vendor/github.com/mistifyio/go-zfs/v3/utils_notsolaris.go deleted file mode 100644 index b1ce59656..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/utils_notsolaris.go +++ /dev/null @@ -1,19 +0,0 @@ -//go:build !solaris -// +build !solaris - -package zfs - -import "strings" - -var ( - // List of ZFS properties to retrieve from zfs list command on a non-Solaris platform. - dsPropList = []string{"name", "origin", "used", "available", "mountpoint", "compression", "type", "volsize", "quota", "referenced", "written", "logicalused", "usedbydataset"} - - dsPropListOptions = strings.Join(dsPropList, ",") - - // List of Zpool properties to retrieve from zpool list command on a non-Solaris platform. - zpoolPropList = []string{"name", "health", "allocated", "size", "free", "readonly", "dedupratio", "fragmentation", "freeing", "leaked"} - - zpoolPropListOptions = strings.Join(zpoolPropList, ",") - zpoolArgs = []string{"get", "-Hp", zpoolPropListOptions} -) diff --git a/vendor/github.com/mistifyio/go-zfs/v3/utils_solaris.go b/vendor/github.com/mistifyio/go-zfs/v3/utils_solaris.go deleted file mode 100644 index f19aebabb..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/utils_solaris.go +++ /dev/null @@ -1,19 +0,0 @@ -//go:build solaris -// +build solaris - -package zfs - -import "strings" - -var ( - // List of ZFS properties to retrieve from zfs list command on a Solaris platform - dsPropList = []string{"name", "origin", "used", "available", "mountpoint", "compression", "type", "volsize", "quota", "referenced"} - - dsPropListOptions = strings.Join(dsPropList, ",") - - // List of Zpool properties to retrieve from zpool list command on a non-Solaris platform - zpoolPropList = []string{"name", "health", "allocated", "size", "free", "readonly", "dedupratio"} - - zpoolPropListOptions = strings.Join(zpoolPropList, ",") - zpoolArgs = []string{"get", "-Hp", zpoolPropListOptions} -) diff --git a/vendor/github.com/mistifyio/go-zfs/v3/zfs.go b/vendor/github.com/mistifyio/go-zfs/v3/zfs.go deleted file mode 100644 index 1166bdc21..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/zfs.go +++ /dev/null @@ -1,449 +0,0 @@ -// Package zfs provides wrappers around the ZFS command line tools. -package zfs - -import ( - "errors" - "fmt" - "io" - "strconv" - "strings" -) - -// ZFS dataset types, which can indicate if a dataset is a filesystem, snapshot, or volume. -const ( - DatasetFilesystem = "filesystem" - DatasetSnapshot = "snapshot" - DatasetVolume = "volume" -) - -// Dataset is a ZFS dataset. A dataset could be a clone, filesystem, snapshot, or volume. -// The Type struct member can be used to determine a dataset's type. -// -// The field definitions can be found in the ZFS manual: -// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. -type Dataset struct { - Name string - Origin string - Used uint64 - Avail uint64 - Mountpoint string - Compression string - Type string - Written uint64 - Volsize uint64 - Logicalused uint64 - Usedbydataset uint64 - Quota uint64 - Referenced uint64 -} - -// InodeType is the type of inode as reported by Diff. -type InodeType int - -// Types of Inodes. -const ( - _ = iota // 0 == unknown type - BlockDevice InodeType = iota - CharacterDevice - Directory - Door - NamedPipe - SymbolicLink - EventPort - Socket - File -) - -// ChangeType is the type of inode change as reported by Diff. -type ChangeType int - -// Types of Changes. -const ( - _ = iota // 0 == unknown type - Removed ChangeType = iota - Created - Modified - Renamed -) - -// DestroyFlag is the options flag passed to Destroy. -type DestroyFlag int - -// Valid destroy options. -const ( - DestroyDefault DestroyFlag = 1 << iota - DestroyRecursive = 1 << iota - DestroyRecursiveClones = 1 << iota - DestroyDeferDeletion = 1 << iota - DestroyForceUmount = 1 << iota -) - -// InodeChange represents a change as reported by Diff. -type InodeChange struct { - Change ChangeType - Type InodeType - Path string - NewPath string - ReferenceCountChange int -} - -// Logger can be used to log commands/actions. -type Logger interface { - Log(cmd []string) -} - -type defaultLogger struct{} - -func (*defaultLogger) Log([]string) { -} - -var logger Logger = &defaultLogger{} - -// SetLogger set a log handler to log all commands including arguments before they are executed. -func SetLogger(l Logger) { - if l != nil { - logger = l - } -} - -// zfs is a helper function to wrap typical calls to zfs that ignores stdout. -func zfs(arg ...string) error { - _, err := zfsOutput(arg...) - return err -} - -// zfs is a helper function to wrap typical calls to zfs. -func zfsOutput(arg ...string) ([][]string, error) { - c := command{Command: "zfs"} - return c.Run(arg...) -} - -// Datasets returns a slice of ZFS datasets, regardless of type. -// A filter argument may be passed to select a dataset with the matching name, or empty string ("") may be used to select all datasets. -func Datasets(filter string) ([]*Dataset, error) { - return listByType("all", filter) -} - -// Snapshots returns a slice of ZFS snapshots. -// A filter argument may be passed to select a snapshot with the matching name, or empty string ("") may be used to select all snapshots. -func Snapshots(filter string) ([]*Dataset, error) { - return listByType(DatasetSnapshot, filter) -} - -// Filesystems returns a slice of ZFS filesystems. -// A filter argument may be passed to select a filesystem with the matching name, or empty string ("") may be used to select all filesystems. -func Filesystems(filter string) ([]*Dataset, error) { - return listByType(DatasetFilesystem, filter) -} - -// Volumes returns a slice of ZFS volumes. -// A filter argument may be passed to select a volume with the matching name, or empty string ("") may be used to select all volumes. -func Volumes(filter string) ([]*Dataset, error) { - return listByType(DatasetVolume, filter) -} - -// GetDataset retrieves a single ZFS dataset by name. -// This dataset could be any valid ZFS dataset type, such as a clone, filesystem, snapshot, or volume. -func GetDataset(name string) (*Dataset, error) { - out, err := zfsOutput("list", "-Hp", "-o", dsPropListOptions, name) - if err != nil { - return nil, err - } - - ds := &Dataset{Name: name} - for _, line := range out { - if err := ds.parseLine(line); err != nil { - return nil, err - } - } - - return ds, nil -} - -// Clone clones a ZFS snapshot and returns a clone dataset. -// An error will be returned if the input dataset is not of snapshot type. -func (d *Dataset) Clone(dest string, properties map[string]string) (*Dataset, error) { - if d.Type != DatasetSnapshot { - return nil, errors.New("can only clone snapshots") - } - args := make([]string, 2, 4) - args[0] = "clone" - args[1] = "-p" - if properties != nil { - args = append(args, propsSlice(properties)...) - } - args = append(args, []string{d.Name, dest}...) - if err := zfs(args...); err != nil { - return nil, err - } - return GetDataset(dest) -} - -// Unmount unmounts currently mounted ZFS file systems. -func (d *Dataset) Unmount(force bool) (*Dataset, error) { - if d.Type == DatasetSnapshot { - return nil, errors.New("cannot unmount snapshots") - } - args := make([]string, 1, 3) - args[0] = "umount" - if force { - args = append(args, "-f") - } - args = append(args, d.Name) - if err := zfs(args...); err != nil { - return nil, err - } - return GetDataset(d.Name) -} - -// Mount mounts ZFS file systems. -func (d *Dataset) Mount(overlay bool, options []string) (*Dataset, error) { - if d.Type == DatasetSnapshot { - return nil, errors.New("cannot mount snapshots") - } - args := make([]string, 1, 5) - args[0] = "mount" - if overlay { - args = append(args, "-O") - } - if options != nil { - args = append(args, "-o") - args = append(args, strings.Join(options, ",")) - } - args = append(args, d.Name) - if err := zfs(args...); err != nil { - return nil, err - } - return GetDataset(d.Name) -} - -// ReceiveSnapshot receives a ZFS stream from the input io.Reader. -// A new snapshot is created with the specified name, and streams the input data into the newly-created snapshot. -func ReceiveSnapshot(input io.Reader, name string) (*Dataset, error) { - c := command{Command: "zfs", Stdin: input} - if _, err := c.Run("receive", name); err != nil { - return nil, err - } - return GetDataset(name) -} - -// SendSnapshot sends a ZFS stream of a snapshot to the input io.Writer. -// An error will be returned if the input dataset is not of snapshot type. -func (d *Dataset) SendSnapshot(output io.Writer) error { - if d.Type != DatasetSnapshot { - return errors.New("can only send snapshots") - } - - c := command{Command: "zfs", Stdout: output} - _, err := c.Run("send", d.Name) - return err -} - -// IncrementalSend sends a ZFS stream of a snapshot to the input io.Writer using the baseSnapshot as the starting point. -// An error will be returned if the input dataset is not of snapshot type. -func (d *Dataset) IncrementalSend(baseSnapshot *Dataset, output io.Writer) error { - if d.Type != DatasetSnapshot || baseSnapshot.Type != DatasetSnapshot { - return errors.New("can only send snapshots") - } - c := command{Command: "zfs", Stdout: output} - _, err := c.Run("send", "-i", baseSnapshot.Name, d.Name) - return err -} - -// CreateVolume creates a new ZFS volume with the specified name, size, and properties. -// -// A full list of available ZFS properties may be found in the ZFS manual: -// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. -func CreateVolume(name string, size uint64, properties map[string]string) (*Dataset, error) { - args := make([]string, 4, 5) - args[0] = "create" - args[1] = "-p" - args[2] = "-V" - args[3] = strconv.FormatUint(size, 10) - if properties != nil { - args = append(args, propsSlice(properties)...) - } - args = append(args, name) - if err := zfs(args...); err != nil { - return nil, err - } - return GetDataset(name) -} - -// Destroy destroys a ZFS dataset. -// If the destroy bit flag is set, any descendents of the dataset will be recursively destroyed, including snapshots. -// If the deferred bit flag is set, the snapshot is marked for deferred deletion. -func (d *Dataset) Destroy(flags DestroyFlag) error { - args := make([]string, 1, 3) - args[0] = "destroy" - if flags&DestroyRecursive != 0 { - args = append(args, "-r") - } - - if flags&DestroyRecursiveClones != 0 { - args = append(args, "-R") - } - - if flags&DestroyDeferDeletion != 0 { - args = append(args, "-d") - } - - if flags&DestroyForceUmount != 0 { - args = append(args, "-f") - } - - args = append(args, d.Name) - err := zfs(args...) - return err -} - -// SetProperty sets a ZFS property on the receiving dataset. -// -// A full list of available ZFS properties may be found in the ZFS manual: -// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. -func (d *Dataset) SetProperty(key, val string) error { - prop := strings.Join([]string{key, val}, "=") - err := zfs("set", prop, d.Name) - return err -} - -// GetProperty returns the current value of a ZFS property from the receiving dataset. -// -// A full list of available ZFS properties may be found in the ZFS manual: -// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. -func (d *Dataset) GetProperty(key string) (string, error) { - out, err := zfsOutput("get", "-H", key, d.Name) - if err != nil { - return "", err - } - - return out[0][2], nil -} - -// Rename renames a dataset. -func (d *Dataset) Rename(name string, createParent, recursiveRenameSnapshots bool) (*Dataset, error) { - args := make([]string, 3, 5) - args[0] = "rename" - args[1] = d.Name - args[2] = name - if createParent { - args = append(args, "-p") - } - if recursiveRenameSnapshots { - args = append(args, "-r") - } - if err := zfs(args...); err != nil { - return d, err - } - - return GetDataset(name) -} - -// Snapshots returns a slice of all ZFS snapshots of a given dataset. -func (d *Dataset) Snapshots() ([]*Dataset, error) { - return Snapshots(d.Name) -} - -// CreateFilesystem creates a new ZFS filesystem with the specified name and properties. -// -// A full list of available ZFS properties may be found in the ZFS manual: -// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. -func CreateFilesystem(name string, properties map[string]string) (*Dataset, error) { - args := make([]string, 1, 4) - args[0] = "create" - - if properties != nil { - args = append(args, propsSlice(properties)...) - } - - args = append(args, name) - if err := zfs(args...); err != nil { - return nil, err - } - return GetDataset(name) -} - -// Snapshot creates a new ZFS snapshot of the receiving dataset, using the specified name. -// Optionally, the snapshot can be taken recursively, creating snapshots of all descendent filesystems in a single, atomic operation. -func (d *Dataset) Snapshot(name string, recursive bool) (*Dataset, error) { - args := make([]string, 1, 4) - args[0] = "snapshot" - if recursive { - args = append(args, "-r") - } - snapName := fmt.Sprintf("%s@%s", d.Name, name) - args = append(args, snapName) - if err := zfs(args...); err != nil { - return nil, err - } - return GetDataset(snapName) -} - -// Rollback rolls back the receiving ZFS dataset to a previous snapshot. -// Optionally, intermediate snapshots can be destroyed. -// A ZFS snapshot rollback cannot be completed without this option, if more recent snapshots exist. -// An error will be returned if the input dataset is not of snapshot type. -func (d *Dataset) Rollback(destroyMoreRecent bool) error { - if d.Type != DatasetSnapshot { - return errors.New("can only rollback snapshots") - } - - args := make([]string, 1, 3) - args[0] = "rollback" - if destroyMoreRecent { - args = append(args, "-r") - } - args = append(args, d.Name) - - err := zfs(args...) - return err -} - -// Children returns a slice of children of the receiving ZFS dataset. -// A recursion depth may be specified, or a depth of 0 allows unlimited recursion. -func (d *Dataset) Children(depth uint64) ([]*Dataset, error) { - args := []string{"list"} - if depth > 0 { - args = append(args, "-d") - args = append(args, strconv.FormatUint(depth, 10)) - } else { - args = append(args, "-r") - } - args = append(args, "-t", "all", "-Hp", "-o", dsPropListOptions) - args = append(args, d.Name) - - out, err := zfsOutput(args...) - if err != nil { - return nil, err - } - - var datasets []*Dataset - name := "" - var ds *Dataset - for _, line := range out { - if name != line[0] { - name = line[0] - ds = &Dataset{Name: name} - datasets = append(datasets, ds) - } - if err := ds.parseLine(line); err != nil { - return nil, err - } - } - return datasets[1:], nil -} - -// Diff returns changes between a snapshot and the given ZFS dataset. -// The snapshot name must include the filesystem part as it is possible to compare clones with their origin snapshots. -func (d *Dataset) Diff(snapshot string) ([]*InodeChange, error) { - args := []string{"diff", "-FH", snapshot, d.Name} - out, err := zfsOutput(args...) - if err != nil { - return nil, err - } - inodeChanges, err := parseInodeChanges(out) - if err != nil { - return nil, err - } - return inodeChanges, nil -} diff --git a/vendor/github.com/mistifyio/go-zfs/v3/zpool.go b/vendor/github.com/mistifyio/go-zfs/v3/zpool.go deleted file mode 100644 index a0bd6471a..000000000 --- a/vendor/github.com/mistifyio/go-zfs/v3/zpool.go +++ /dev/null @@ -1,116 +0,0 @@ -package zfs - -// ZFS zpool states, which can indicate if a pool is online, offline, degraded, etc. -// -// More information regarding zpool states can be found in the ZFS manual: -// https://openzfs.github.io/openzfs-docs/man/7/zpoolconcepts.7.html#Device_Failure_and_Recovery -const ( - ZpoolOnline = "ONLINE" - ZpoolDegraded = "DEGRADED" - ZpoolFaulted = "FAULTED" - ZpoolOffline = "OFFLINE" - ZpoolUnavail = "UNAVAIL" - ZpoolRemoved = "REMOVED" -) - -// Zpool is a ZFS zpool. -// A pool is a top-level structure in ZFS, and can contain many descendent datasets. -type Zpool struct { - Name string - Health string - Allocated uint64 - Size uint64 - Free uint64 - Fragmentation uint64 - ReadOnly bool - Freeing uint64 - Leaked uint64 - DedupRatio float64 -} - -// zpool is a helper function to wrap typical calls to zpool and ignores stdout. -func zpool(arg ...string) error { - _, err := zpoolOutput(arg...) - return err -} - -// zpool is a helper function to wrap typical calls to zpool. -func zpoolOutput(arg ...string) ([][]string, error) { - c := command{Command: "zpool"} - return c.Run(arg...) -} - -// GetZpool retrieves a single ZFS zpool by name. -func GetZpool(name string) (*Zpool, error) { - args := zpoolArgs - args = append(args, name) - out, err := zpoolOutput(args...) - if err != nil { - return nil, err - } - - z := &Zpool{Name: name} - for _, line := range out { - if err := z.parseLine(line); err != nil { - return nil, err - } - } - - return z, nil -} - -// Datasets returns a slice of all ZFS datasets in a zpool. -func (z *Zpool) Datasets() ([]*Dataset, error) { - return Datasets(z.Name) -} - -// Snapshots returns a slice of all ZFS snapshots in a zpool. -func (z *Zpool) Snapshots() ([]*Dataset, error) { - return Snapshots(z.Name) -} - -// CreateZpool creates a new ZFS zpool with the specified name, properties, and optional arguments. -// -// A full list of available ZFS properties and command-line arguments may be found in the ZFS manual: -// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. -// https://openzfs.github.io/openzfs-docs/man/8/zpool-create.8.html -func CreateZpool(name string, properties map[string]string, args ...string) (*Zpool, error) { - cli := make([]string, 1, 4) - cli[0] = "create" - if properties != nil { - cli = append(cli, propsSlice(properties)...) - } - cli = append(cli, name) - cli = append(cli, args...) - if err := zpool(cli...); err != nil { - return nil, err - } - - return &Zpool{Name: name}, nil -} - -// Destroy destroys a ZFS zpool by name. -func (z *Zpool) Destroy() error { - err := zpool("destroy", z.Name) - return err -} - -// ListZpools list all ZFS zpools accessible on the current system. -func ListZpools() ([]*Zpool, error) { - args := []string{"list", "-Ho", "name"} - out, err := zpoolOutput(args...) - if err != nil { - return nil, err - } - - var pools []*Zpool - - for _, line := range out { - z, err := GetZpool(line[0]) - if err != nil { - return nil, err - } - pools = append(pools, z) - } - return pools, nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index c668ada37..80aa54e99 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -151,10 +151,6 @@ github.com/containerd/typeurl # github.com/containerd/typeurl/v2 v2.1.1 ## explicit; go 1.13 github.com/containerd/typeurl/v2 -# github.com/containerd/zfs v1.2.0 -## explicit; go 1.19 -github.com/containerd/zfs -github.com/containerd/zfs/plugin # github.com/containernetworking/cni v1.1.2 ## explicit; go 1.14 github.com/containernetworking/cni/libcni @@ -307,9 +303,6 @@ github.com/miekg/pkcs11 # github.com/minio/sha256-simd v1.0.1 ## explicit; go 1.17 github.com/minio/sha256-simd -# github.com/mistifyio/go-zfs/v3 v3.0.1 -## explicit; go 1.14 -github.com/mistifyio/go-zfs/v3 # github.com/moby/locker v1.0.1 ## explicit; go 1.13 github.com/moby/locker