Browse code

Cleanup fallback to V1 plugins logic.

handleLegacy is a flag to indicate whether daemon is supporting legacy
plugins. When the time comes to remove support for legacy plugins,
flipping this bool is all that will be needed to remove legacy plugin
support. This can be a global variable rather than be embedded in the
manager, thereby cleaning up code.

Also rename to allowV1PluginsFallback for clarity.

Signed-off-by: Anusha Ragunathan <anusha@docker.com>

Anusha Ragunathan authored on 2016/08/25 04:42:37
Showing 1 changed files
... ...
@@ -24,7 +24,15 @@ import (
24 24
 
25 25
 const defaultPluginRuntimeDestination = "/run/docker/plugins"
26 26
 
27
-var manager *Manager
27
+var (
28
+	manager *Manager
29
+
30
+	/* allowV1PluginsFallback determines daemon's support for V1 plugins.
31
+	 * When the time comes to remove support for V1 plugins, flipping
32
+	 * this bool is all that will be needed.
33
+	 */
34
+	allowV1PluginsFallback = true
35
+)
28 36
 
29 37
 // ErrNotFound indicates that a plugin was not found locally.
30 38
 type ErrNotFound string
... ...
@@ -103,7 +111,6 @@ type Manager struct {
103 103
 	handlers          map[string]func(string, *plugins.Client)
104 104
 	containerdClient  libcontainerd.Client
105 105
 	registryService   registry.Service
106
-	handleLegacy      bool
107 106
 	liveRestore       bool
108 107
 	shutdown          bool
109 108
 	pluginEventLogger eventLogger
... ...
@@ -129,7 +136,6 @@ func Init(root string, remote libcontainerd.Remote, rs registry.Service, liveRes
129 129
 		nameToID:          make(map[string]string),
130 130
 		handlers:          make(map[string]func(string, *plugins.Client)),
131 131
 		registryService:   rs,
132
-		handleLegacy:      true,
133 132
 		liveRestore:       liveRestore,
134 133
 		pluginEventLogger: evL,
135 134
 	}
... ...
@@ -151,7 +157,7 @@ func Init(root string, remote libcontainerd.Remote, rs registry.Service, liveRes
151 151
 func Handle(capability string, callback func(string, *plugins.Client)) {
152 152
 	pluginType := fmt.Sprintf("docker.%s/1", strings.ToLower(capability))
153 153
 	manager.handlers[pluginType] = callback
154
-	if manager.handleLegacy {
154
+	if allowV1PluginsFallback {
155 155
 		plugins.Handle(capability, callback)
156 156
 	}
157 157
 }
... ...
@@ -175,12 +181,15 @@ func (pm *Manager) get(name string) (*plugin, error) {
175 175
 
176 176
 // FindWithCapability returns a list of plugins matching the given capability.
177 177
 func FindWithCapability(capability string) ([]Plugin, error) {
178
-	handleLegacy := true
179 178
 	result := make([]Plugin, 0, 1)
179
+
180
+	/* Daemon start always calls plugin.Init thereby initializing a manager.
181
+	 * So manager on experimental builds can never be nil, even while
182
+	 * handling legacy plugins. However, there are legacy plugin unit
183
+	 * tests where volume subsystem directly talks with the plugin,
184
+	 * bypassing the daemon. For such tests, this check is necessary.*/
180 185
 	if manager != nil {
181
-		handleLegacy = manager.handleLegacy
182 186
 		manager.RLock()
183
-		defer manager.RUnlock()
184 187
 		for _, p := range manager.plugins {
185 188
 			for _, typ := range p.PluginObj.Manifest.Interface.Types {
186 189
 				if strings.EqualFold(typ.Capability, capability) && typ.Prefix == "docker" {
... ...
@@ -189,16 +198,17 @@ func FindWithCapability(capability string) ([]Plugin, error) {
189 189
 				}
190 190
 			}
191 191
 		}
192
+		manager.RUnlock()
192 193
 	}
193
-	if handleLegacy {
194
+
195
+	// Lookup with legacy model.
196
+	if allowV1PluginsFallback {
194 197
 		pl, err := plugins.GetAll(capability)
195 198
 		if err != nil {
196 199
 			return nil, fmt.Errorf("legacy plugin: %v", err)
197 200
 		}
198 201
 		for _, p := range pl {
199
-			if _, ok := manager.nameToID[p.Name()]; !ok {
200
-				result = append(result, p)
201
-			}
202
+			result = append(result, p)
202 203
 		}
203 204
 	}
204 205
 	return result, nil
... ...
@@ -210,7 +220,8 @@ func LookupWithCapability(name, capability string) (Plugin, error) {
210 210
 		p   *plugin
211 211
 		err error
212 212
 	)
213
-	handleLegacy := true
213
+
214
+	// Lookup using new model.
214 215
 	if manager != nil {
215 216
 		fullName := name
216 217
 		if named, err := reference.ParseNamed(fullName); err == nil { // FIXME: validate
... ...
@@ -224,31 +235,30 @@ func LookupWithCapability(name, capability string) (Plugin, error) {
224 224
 			fullName = ref.String()
225 225
 		}
226 226
 		p, err = manager.get(fullName)
227
-		if err != nil {
228
-			if _, ok := err.(ErrNotFound); !ok {
229
-				return nil, err
227
+		if err == nil {
228
+			capability = strings.ToLower(capability)
229
+			for _, typ := range p.PluginObj.Manifest.Interface.Types {
230
+				if typ.Capability == capability && typ.Prefix == "docker" {
231
+					return p, nil
232
+				}
230 233
 			}
231
-			handleLegacy = manager.handleLegacy
232
-		} else {
233
-			handleLegacy = false
234
+			return nil, ErrInadequateCapability{name, capability}
235
+		}
236
+		if _, ok := err.(ErrNotFound); !ok {
237
+			return nil, err
234 238
 		}
235 239
 	}
236
-	if handleLegacy {
240
+
241
+	// Lookup using legacy model
242
+	if allowV1PluginsFallback {
237 243
 		p, err := plugins.Get(name, capability)
238 244
 		if err != nil {
239 245
 			return nil, fmt.Errorf("legacy plugin: %v", err)
240 246
 		}
241 247
 		return p, nil
242
-	} else if err != nil {
243
-		return nil, err
244 248
 	}
245 249
 
246
-	for _, typ := range p.PluginObj.Manifest.Interface.Types {
247
-		if strings.EqualFold(typ.Capability, capability) && typ.Prefix == "docker" {
248
-			return p, nil
249
-		}
250
-	}
251
-	return nil, ErrInadequateCapability{name, capability}
250
+	return nil, err
252 251
 }
253 252
 
254 253
 // StateChanged updates plugin internals using libcontainerd events.