Merge pull request #44789 from jg-public/specspath-to-registry

plugins: Move SpecPaths into LocalRegistry
This commit is contained in:
Bjorn Neergaard 2023-01-14 15:09:12 -07:00 committed by GitHub
commit eb20ed1f69
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 41 additions and 46 deletions

View file

@ -19,15 +19,19 @@ var (
socketsPath = "/run/docker/plugins"
)
// localRegistry defines a registry that is local (using unix socket).
type localRegistry struct{}
// LocalRegistry defines a registry that is local (using unix socket).
type LocalRegistry struct {
SpecsPaths func() []string
}
func newLocalRegistry() localRegistry {
return localRegistry{}
func NewLocalRegistry() LocalRegistry {
return LocalRegistry{
SpecsPaths,
}
}
// Scan scans all the plugin paths and returns all the names it found
func Scan() ([]string, error) {
func (l *LocalRegistry) Scan() ([]string, error) {
var names []string
dirEntries, err := os.ReadDir(socketsPath)
if err != nil && !os.IsNotExist(err) {
@ -49,7 +53,7 @@ func Scan() ([]string, error) {
}
}
for _, p := range SpecsPaths() {
for _, p := range l.SpecsPaths() {
dirEntries, err := os.ReadDir(p)
if err != nil && !os.IsNotExist(err) {
return nil, errors.Wrap(err, "error reading dir entries")
@ -83,7 +87,7 @@ func Scan() ([]string, error) {
}
// Plugin returns the plugin registered with the given name (or returns an error).
func (l *localRegistry) Plugin(name string) (*Plugin, error) {
func (l *LocalRegistry) Plugin(name string) (*Plugin, error) {
socketpaths := pluginPaths(socketsPath, name, ".sock")
for _, p := range socketpaths {
@ -93,7 +97,7 @@ func (l *localRegistry) Plugin(name string) (*Plugin, error) {
}
var txtspecpaths []string
for _, p := range SpecsPaths() {
for _, p := range l.SpecsPaths() {
txtspecpaths = append(txtspecpaths, pluginPaths(p, name, ".spec")...)
txtspecpaths = append(txtspecpaths, pluginPaths(p, name, ".json")...)
}

View file

@ -6,23 +6,26 @@ import (
"testing"
)
func Setup(t *testing.T) (string, func()) {
func Setup(t *testing.T) (string, func(), LocalRegistry) {
tmpdir, err := os.MkdirTemp("", "docker-test")
if err != nil {
t.Fatal(err)
}
backup := socketsPath
socketsPath = tmpdir
globalSpecsPaths = []string{tmpdir}
return tmpdir, func() {
socketsPath = backup
os.RemoveAll(tmpdir)
}
socketsPath = backup
os.RemoveAll(tmpdir)
}, LocalRegistry{
func() []string {
return []string{tmpdir}
},
}
}
func TestFileSpecPlugin(t *testing.T) {
tmpdir, unregister := Setup(t)
tmpdir, unregister, r := Setup(t)
defer unregister()
cases := []struct {
@ -47,7 +50,6 @@ func TestFileSpecPlugin(t *testing.T) {
t.Fatal(err)
}
r := newLocalRegistry()
p, err := r.Plugin(c.name)
if c.fail && err == nil {
continue
@ -72,7 +74,7 @@ func TestFileSpecPlugin(t *testing.T) {
}
func TestFileJSONSpecPlugin(t *testing.T) {
tmpdir, unregister := Setup(t)
tmpdir, unregister, r := Setup(t)
defer unregister()
p := filepath.Join(tmpdir, "example.json")
@ -90,7 +92,6 @@ func TestFileJSONSpecPlugin(t *testing.T) {
t.Fatal(err)
}
r := newLocalRegistry()
plugin, err := r.Plugin("example")
if err != nil {
t.Fatal(err)
@ -118,7 +119,7 @@ func TestFileJSONSpecPlugin(t *testing.T) {
}
func TestFileJSONSpecPluginWithoutTLSConfig(t *testing.T) {
tmpdir, unregister := Setup(t)
tmpdir, unregister, r := Setup(t)
defer unregister()
p := filepath.Join(tmpdir, "example.json")
@ -131,7 +132,6 @@ func TestFileJSONSpecPluginWithoutTLSConfig(t *testing.T) {
t.Fatal(err)
}
r := newLocalRegistry()
plugin, err := r.Plugin("example")
if err != nil {
t.Fatal(err)

View file

@ -9,18 +9,13 @@ import (
"github.com/docker/docker/pkg/rootless"
)
const globalConfigPluginsPath = "/etc/docker/plugins"
const globalLibPluginsPath = "/usr/lib/docker/plugins"
var globalSpecsPaths = []string{globalConfigPluginsPath, globalLibPluginsPath}
func rootlessConfigPluginsPath() string {
configHome, err := homedir.GetConfigHome()
if err == nil {
return filepath.Join(configHome, "docker/plugins")
}
return globalConfigPluginsPath
return "/etc/docker/plugins"
}
func rootlessLibPluginsPath() string {
@ -29,7 +24,7 @@ func rootlessLibPluginsPath() string {
return filepath.Join(libHome, "docker/plugins")
}
return globalLibPluginsPath
return "/usr/lib/docker/plugins"
}
// SpecsPaths returns
@ -42,5 +37,5 @@ func SpecsPaths() []string {
return []string{rootlessConfigPluginsPath(), rootlessLibPluginsPath()}
}
return globalSpecsPaths
return []string{"/etc/docker/plugins", "/usr/lib/docker/plugins"}
}

View file

@ -16,7 +16,7 @@ import (
func TestLocalSocket(t *testing.T) {
// TODO Windows: Enable a similar version for Windows named pipes
tmpdir, unregister := Setup(t)
tmpdir, unregister, r := Setup(t)
defer unregister()
cases := []string{
@ -34,7 +34,6 @@ func TestLocalSocket(t *testing.T) {
t.Fatal(err)
}
r := newLocalRegistry()
p, err := r.Plugin("echo")
if err != nil {
t.Fatal(err)
@ -64,10 +63,10 @@ func TestLocalSocket(t *testing.T) {
}
func TestScan(t *testing.T) {
tmpdir, unregister := Setup(t)
tmpdir, unregister, r := Setup(t)
defer unregister()
pluginNames, err := Scan()
pluginNames, err := r.Scan()
if err != nil {
t.Fatal(err)
}
@ -89,11 +88,10 @@ func TestScan(t *testing.T) {
t.Fatal(err)
}
r := newLocalRegistry()
p, err := r.Plugin(name)
assert.NilError(t, err)
pluginNamesNotEmpty, err := Scan()
pluginNamesNotEmpty, err := r.Scan()
if err != nil {
t.Fatal(err)
}
@ -106,7 +104,7 @@ func TestScan(t *testing.T) {
}
func TestScanNotPlugins(t *testing.T) {
tmpdir, unregister := Setup(t)
tmpdir, unregister, localRegistry := Setup(t)
defer unregister()
// not that `Setup()` above sets the sockets path and spec path dirs, which
@ -131,7 +129,7 @@ func TestScanNotPlugins(t *testing.T) {
}
defer f.Close()
names, err := Scan()
names, err := localRegistry.Scan()
if err != nil {
t.Fatal(err)
}
@ -146,7 +144,7 @@ func TestScanNotPlugins(t *testing.T) {
}
defer f.Close()
names, err = Scan()
names, err = localRegistry.Scan()
if err != nil {
t.Fatal(err)
}

View file

@ -5,13 +5,11 @@ import (
"path/filepath"
)
var globalSpecsPaths = []string{filepath.Join(os.Getenv("programdata"), "docker", "plugins")}
// SpecsPaths returns
// { "%programdata%\docker\plugins" } on Windows,
// { "/etc/docker/plugins", "/usr/lib/docker/plugins" } on Unix in non-rootless mode,
// { "$XDG_CONFIG_HOME/docker/plugins", "$HOME/.local/lib/docker/plugins" } on Unix in rootless mode
// with fallback to the corresponding path in non-rootless mode if $XDG_CONFIG_HOME or $HOME is not set.
func SpecsPaths() []string {
return globalSpecsPaths
return []string{filepath.Join(os.Getenv("programdata"), "docker", "plugins")}
}

View file

@ -123,7 +123,7 @@ func TestPluginWithNoManifest(t *testing.T) {
}
func TestGetAll(t *testing.T) {
tmpdir, unregister := Setup(t)
tmpdir, unregister, r := Setup(t)
defer unregister()
p := filepath.Join(tmpdir, "example.json")
@ -136,7 +136,6 @@ func TestGetAll(t *testing.T) {
t.Fatal(err)
}
r := newLocalRegistry()
plugin, err := r.Plugin("example")
if err != nil {
t.Fatal(err)
@ -144,7 +143,7 @@ func TestGetAll(t *testing.T) {
plugin.Manifest = &Manifest{Implements: []string{"apple"}}
storage.plugins["example"] = plugin
fetchedPlugins, err := GetAll("apple")
fetchedPlugins, err := r.GetAll("apple")
if err != nil {
t.Fatal(err)
}

View file

@ -201,7 +201,7 @@ func load(name string) (*Plugin, error) {
}
func loadWithRetry(name string, retry bool) (*Plugin, error) {
registry := newLocalRegistry()
registry := NewLocalRegistry()
start := time.Now()
var retries int
@ -293,8 +293,8 @@ func Handle(iface string, fn func(string, *Client)) {
}
// GetAll returns all the plugins for the specified implementation
func GetAll(imp string) ([]*Plugin, error) {
pluginNames, err := Scan()
func (l *LocalRegistry) GetAll(imp string) ([]*Plugin, error) {
pluginNames, err := l.Scan()
if err != nil {
return nil, err
}

View file

@ -192,7 +192,8 @@ func (ps *Store) GetAllByCap(capability string) ([]plugingetter.CompatPlugin, er
// Lookup with legacy model
if allowV1PluginsFallback {
pl, err := plugins.GetAll(capability)
l := plugins.NewLocalRegistry()
pl, err := l.GetAll(capability)
if err != nil {
return nil, errors.Wrap(errdefs.System(err), "legacy plugin")
}