podman

Форк
0
461 строка · 14.6 Кб
1
// Copyright 2018 go-dockerclient authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4

5
package docker
6

7
import (
8
	"context"
9
	"encoding/json"
10
	"errors"
11
	"io"
12
	"net/http"
13
)
14

15
// PluginPrivilege represents a privilege for a plugin.
16
type PluginPrivilege struct {
17
	Name        string   `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"`
18
	Description string   `json:"Description,omitempty" yaml:"Description,omitempty" toml:"Description,omitempty"`
19
	Value       []string `json:"Value,omitempty" yaml:"Value,omitempty" toml:"Value,omitempty"`
20
}
21

22
// InstallPluginOptions specify parameters to the InstallPlugins function.
23
//
24
// See https://goo.gl/C4t7Tz for more details.
25
type InstallPluginOptions struct {
26
	Remote  string
27
	Name    string
28
	Plugins []PluginPrivilege `qs:"-"`
29

30
	Auth AuthConfiguration
31

32
	Context context.Context
33
}
34

35
// InstallPlugins installs a plugin or returns an error in case of failure.
36
//
37
// See https://goo.gl/C4t7Tz for more details.
38
func (c *Client) InstallPlugins(opts InstallPluginOptions) error {
39
	headers, err := headersWithAuth(opts.Auth)
40
	if err != nil {
41
		return err
42
	}
43

44
	path := "/plugins/pull?" + queryString(opts)
45
	resp, err := c.do(http.MethodPost, path, doOptions{
46
		data:    opts.Plugins,
47
		context: opts.Context,
48
		headers: headers,
49
	})
50
	if err != nil {
51
		return err
52
	}
53
	defer resp.Body.Close()
54
	// PullPlugin streams back the progress of the pull, we must consume the whole body
55
	// otherwise the pull will be canceled on the engine.
56
	if _, err := io.ReadAll(resp.Body); err != nil {
57
		return err
58
	}
59
	return nil
60
}
61

62
// PluginSettings stores plugin settings.
63
//
64
// See https://goo.gl/C4t7Tz for more details.
65
type PluginSettings struct {
66
	Env     []string `json:"Env,omitempty" yaml:"Env,omitempty" toml:"Env,omitempty"`
67
	Args    []string `json:"Args,omitempty" yaml:"Args,omitempty" toml:"Args,omitempty"`
68
	Devices []string `json:"Devices,omitempty" yaml:"Devices,omitempty" toml:"Devices,omitempty"`
69
}
70

71
// PluginInterface stores plugin interface.
72
//
73
// See https://goo.gl/C4t7Tz for more details.
74
type PluginInterface struct {
75
	Types  []string `json:"Types,omitempty" yaml:"Types,omitempty" toml:"Types,omitempty"`
76
	Socket string   `json:"Socket,omitempty" yaml:"Socket,omitempty" toml:"Socket,omitempty"`
77
}
78

79
// PluginNetwork stores plugin network type.
80
//
81
// See https://goo.gl/C4t7Tz for more details.
82
type PluginNetwork struct {
83
	Type string `json:"Type,omitempty" yaml:"Type,omitempty" toml:"Type,omitempty"`
84
}
85

86
// PluginLinux stores plugin linux setting.
87
//
88
// See https://goo.gl/C4t7Tz for more details.
89
type PluginLinux struct {
90
	Capabilities    []string             `json:"Capabilities,omitempty" yaml:"Capabilities,omitempty" toml:"Capabilities,omitempty"`
91
	AllowAllDevices bool                 `json:"AllowAllDevices,omitempty" yaml:"AllowAllDevices,omitempty" toml:"AllowAllDevices,omitempty"`
92
	Devices         []PluginLinuxDevices `json:"Devices,omitempty" yaml:"Devices,omitempty" toml:"Devices,omitempty"`
93
}
94

95
// PluginLinuxDevices stores plugin linux device setting.
96
//
97
// See https://goo.gl/C4t7Tz for more details.
98
type PluginLinuxDevices struct {
99
	Name        string   `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"`
100
	Description string   `json:"Documentation,omitempty" yaml:"Documentation,omitempty" toml:"Documentation,omitempty"`
101
	Settable    []string `json:"Settable,omitempty" yaml:"Settable,omitempty" toml:"Settable,omitempty"`
102
	Path        string   `json:"Path,omitempty" yaml:"Path,omitempty" toml:"Path,omitempty"`
103
}
104

105
// PluginEnv stores plugin environment.
106
//
107
// See https://goo.gl/C4t7Tz for more details.
108
type PluginEnv struct {
109
	Name        string   `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"`
110
	Description string   `json:"Description,omitempty" yaml:"Description,omitempty" toml:"Description,omitempty"`
111
	Settable    []string `json:"Settable,omitempty" yaml:"Settable,omitempty" toml:"Settable,omitempty"`
112
	Value       string   `json:"Value,omitempty" yaml:"Value,omitempty" toml:"Value,omitempty"`
113
}
114

115
// PluginArgs stores plugin arguments.
116
//
117
// See https://goo.gl/C4t7Tz for more details.
118
type PluginArgs struct {
119
	Name        string   `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"`
120
	Description string   `json:"Description,omitempty" yaml:"Description,omitempty" toml:"Description,omitempty"`
121
	Settable    []string `json:"Settable,omitempty" yaml:"Settable,omitempty" toml:"Settable,omitempty"`
122
	Value       []string `json:"Value,omitempty" yaml:"Value,omitempty" toml:"Value,omitempty"`
123
}
124

125
// PluginUser stores plugin user.
126
//
127
// See https://goo.gl/C4t7Tz for more details.
128
type PluginUser struct {
129
	UID int32 `json:"UID,omitempty" yaml:"UID,omitempty" toml:"UID,omitempty"`
130
	GID int32 `json:"GID,omitempty" yaml:"GID,omitempty" toml:"GID,omitempty"`
131
}
132

133
// PluginConfig stores plugin config.
134
//
135
// See https://goo.gl/C4t7Tz for more details.
136
type PluginConfig struct {
137
	Description     string `json:"Description,omitempty" yaml:"Description,omitempty" toml:"Description,omitempty"`
138
	Documentation   string
139
	Interface       PluginInterface `json:"Interface,omitempty" yaml:"Interface,omitempty" toml:"Interface,omitempty"`
140
	Entrypoint      []string        `json:"Entrypoint,omitempty" yaml:"Entrypoint,omitempty" toml:"Entrypoint,omitempty"`
141
	WorkDir         string          `json:"WorkDir,omitempty" yaml:"WorkDir,omitempty" toml:"WorkDir,omitempty"`
142
	User            PluginUser      `json:"User,omitempty" yaml:"User,omitempty" toml:"User,omitempty"`
143
	Network         PluginNetwork   `json:"Network,omitempty" yaml:"Network,omitempty" toml:"Network,omitempty"`
144
	Linux           PluginLinux     `json:"Linux,omitempty" yaml:"Linux,omitempty" toml:"Linux,omitempty"`
145
	PropagatedMount string          `json:"PropagatedMount,omitempty" yaml:"PropagatedMount,omitempty" toml:"PropagatedMount,omitempty"`
146
	Mounts          []Mount         `json:"Mounts,omitempty" yaml:"Mounts,omitempty" toml:"Mounts,omitempty"`
147
	Env             []PluginEnv     `json:"Env,omitempty" yaml:"Env,omitempty" toml:"Env,omitempty"`
148
	Args            PluginArgs      `json:"Args,omitempty" yaml:"Args,omitempty" toml:"Args,omitempty"`
149
}
150

151
// PluginDetail specify results from the ListPlugins function.
152
//
153
// See https://goo.gl/C4t7Tz for more details.
154
type PluginDetail struct {
155
	ID       string         `json:"Id,omitempty" yaml:"Id,omitempty" toml:"Id,omitempty"`
156
	Name     string         `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"`
157
	Tag      string         `json:"Tag,omitempty" yaml:"Tag,omitempty" toml:"Tag,omitempty"`
158
	Active   bool           `json:"Enabled,omitempty" yaml:"Active,omitempty" toml:"Active,omitempty"`
159
	Settings PluginSettings `json:"Settings,omitempty" yaml:"Settings,omitempty" toml:"Settings,omitempty"`
160
	Config   PluginConfig   `json:"Config,omitempty" yaml:"Config,omitempty" toml:"Config,omitempty"`
161
}
162

163
// ListPlugins returns pluginDetails or an error.
164
//
165
// See https://goo.gl/C4t7Tz for more details.
166
func (c *Client) ListPlugins(ctx context.Context) ([]PluginDetail, error) {
167
	resp, err := c.do(http.MethodGet, "/plugins", doOptions{
168
		context: ctx,
169
	})
170
	if err != nil {
171
		return nil, err
172
	}
173
	defer resp.Body.Close()
174
	pluginDetails := make([]PluginDetail, 0)
175
	if err := json.NewDecoder(resp.Body).Decode(&pluginDetails); err != nil {
176
		return nil, err
177
	}
178
	return pluginDetails, nil
179
}
180

181
// ListFilteredPluginsOptions specify parameters to the ListFilteredPlugins function.
182
//
183
// See https://goo.gl/C4t7Tz for more details.
184
type ListFilteredPluginsOptions struct {
185
	Filters map[string][]string
186
	Context context.Context
187
}
188

189
// ListFilteredPlugins returns pluginDetails or an error.
190
//
191
// See https://goo.gl/rmdmWg for more details.
192
func (c *Client) ListFilteredPlugins(opts ListFilteredPluginsOptions) ([]PluginDetail, error) {
193
	path := "/plugins/json?" + queryString(opts)
194
	resp, err := c.do(http.MethodGet, path, doOptions{
195
		context: opts.Context,
196
	})
197
	if err != nil {
198
		return nil, err
199
	}
200
	defer resp.Body.Close()
201
	pluginDetails := make([]PluginDetail, 0)
202
	if err := json.NewDecoder(resp.Body).Decode(&pluginDetails); err != nil {
203
		return nil, err
204
	}
205
	return pluginDetails, nil
206
}
207

208
// GetPluginPrivileges returns pluginPrivileges or an error.
209
//
210
// See https://goo.gl/C4t7Tz for more details.
211
func (c *Client) GetPluginPrivileges(remote string, ctx context.Context) ([]PluginPrivilege, error) {
212
	return c.GetPluginPrivilegesWithOptions(
213
		GetPluginPrivilegesOptions{
214
			Remote:  remote,
215
			Context: ctx,
216
		})
217
}
218

219
// GetPluginPrivilegesOptions specify parameters to the GetPluginPrivilegesWithOptions function.
220
//
221
// See https://goo.gl/C4t7Tz for more details.
222
type GetPluginPrivilegesOptions struct {
223
	Remote  string
224
	Auth    AuthConfiguration
225
	Context context.Context
226
}
227

228
// GetPluginPrivilegesWithOptions returns pluginPrivileges or an error.
229
//
230
// See https://goo.gl/C4t7Tz for more details.
231
func (c *Client) GetPluginPrivilegesWithOptions(opts GetPluginPrivilegesOptions) ([]PluginPrivilege, error) {
232
	headers, err := headersWithAuth(opts.Auth)
233
	if err != nil {
234
		return nil, err
235
	}
236

237
	path := "/plugins/privileges?" + queryString(opts)
238
	resp, err := c.do(http.MethodGet, path, doOptions{
239
		context: opts.Context,
240
		headers: headers,
241
	})
242
	if err != nil {
243
		return nil, err
244
	}
245
	defer resp.Body.Close()
246
	var pluginPrivileges []PluginPrivilege
247
	if err := json.NewDecoder(resp.Body).Decode(&pluginPrivileges); err != nil {
248
		return nil, err
249
	}
250
	return pluginPrivileges, nil
251
}
252

253
// InspectPlugins returns a pluginDetail or an error.
254
//
255
// See https://goo.gl/C4t7Tz for more details.
256
func (c *Client) InspectPlugins(name string, ctx context.Context) (*PluginDetail, error) {
257
	resp, err := c.do(http.MethodGet, "/plugins/"+name+"/json", doOptions{
258
		context: ctx,
259
	})
260
	if err != nil {
261
		var e *Error
262
		if errors.As(err, &e) && e.Status == http.StatusNotFound {
263
			return nil, &NoSuchPlugin{ID: name}
264
		}
265
		return nil, err
266
	}
267
	defer resp.Body.Close()
268
	var pluginDetail PluginDetail
269
	if err := json.NewDecoder(resp.Body).Decode(&pluginDetail); err != nil {
270
		return nil, err
271
	}
272
	return &pluginDetail, nil
273
}
274

275
// RemovePluginOptions specify parameters to the RemovePlugin function.
276
//
277
// See https://goo.gl/C4t7Tz for more details.
278
type RemovePluginOptions struct {
279
	// The Name of the plugin.
280
	Name string `qs:"-"`
281

282
	Force   bool `qs:"force"`
283
	Context context.Context
284
}
285

286
// RemovePlugin returns a PluginDetail or an error.
287
//
288
// See https://goo.gl/C4t7Tz for more details.
289
func (c *Client) RemovePlugin(opts RemovePluginOptions) (*PluginDetail, error) {
290
	path := "/plugins/" + opts.Name + "?" + queryString(opts)
291
	resp, err := c.do(http.MethodDelete, path, doOptions{context: opts.Context})
292
	if err != nil {
293
		var e *Error
294
		if errors.As(err, &e) && e.Status == http.StatusNotFound {
295
			return nil, &NoSuchPlugin{ID: opts.Name}
296
		}
297
		return nil, err
298
	}
299
	defer resp.Body.Close()
300
	body, err := io.ReadAll(resp.Body)
301
	if err != nil {
302
		return nil, err
303
	}
304

305
	if len(body) == 0 {
306
		// Seems like newer docker versions won't return the plugindetail after removal
307
		return nil, nil
308
	}
309

310
	var pluginDetail PluginDetail
311
	if err := json.Unmarshal(body, &pluginDetail); err != nil {
312
		return nil, err
313
	}
314
	return &pluginDetail, nil
315
}
316

317
// EnablePluginOptions specify parameters to the EnablePlugin function.
318
//
319
// See https://goo.gl/C4t7Tz for more details.
320
type EnablePluginOptions struct {
321
	// The Name of the plugin.
322
	Name    string `qs:"-"`
323
	Timeout int64  `qs:"timeout"`
324

325
	Context context.Context
326
}
327

328
// EnablePlugin enables plugin that opts point or returns an error.
329
//
330
// See https://goo.gl/C4t7Tz for more details.
331
func (c *Client) EnablePlugin(opts EnablePluginOptions) error {
332
	path := "/plugins/" + opts.Name + "/enable?" + queryString(opts)
333
	resp, err := c.do(http.MethodPost, path, doOptions{context: opts.Context})
334
	if err != nil {
335
		return err
336
	}
337
	resp.Body.Close()
338
	return nil
339
}
340

341
// DisablePluginOptions specify parameters to the DisablePlugin function.
342
//
343
// See https://goo.gl/C4t7Tz for more details.
344
type DisablePluginOptions struct {
345
	// The Name of the plugin.
346
	Name string `qs:"-"`
347

348
	Context context.Context
349
}
350

351
// DisablePlugin disables plugin that opts point or returns an error.
352
//
353
// See https://goo.gl/C4t7Tz for more details.
354
func (c *Client) DisablePlugin(opts DisablePluginOptions) error {
355
	path := "/plugins/" + opts.Name + "/disable"
356
	resp, err := c.do(http.MethodPost, path, doOptions{context: opts.Context})
357
	if err != nil {
358
		return err
359
	}
360
	resp.Body.Close()
361
	return nil
362
}
363

364
// CreatePluginOptions specify parameters to the CreatePlugin function.
365
//
366
// See https://goo.gl/C4t7Tz for more details.
367
type CreatePluginOptions struct {
368
	// The Name of the plugin.
369
	Name string `qs:"name"`
370
	// Path to tar containing plugin
371
	Path string `qs:"-"`
372

373
	Context context.Context
374
}
375

376
// CreatePlugin creates plugin that opts point or returns an error.
377
//
378
// See https://goo.gl/C4t7Tz for more details.
379
func (c *Client) CreatePlugin(opts CreatePluginOptions) (string, error) {
380
	path := "/plugins/create?" + queryString(opts)
381
	resp, err := c.do(http.MethodPost, path, doOptions{
382
		data:    opts.Path,
383
		context: opts.Context,
384
	})
385
	if err != nil {
386
		return "", err
387
	}
388
	defer resp.Body.Close()
389
	containerNameBytes, err := io.ReadAll(resp.Body)
390
	if err != nil {
391
		return "", err
392
	}
393
	return string(containerNameBytes), nil
394
}
395

396
// PushPluginOptions specify parameters to PushPlugin function.
397
//
398
// See https://goo.gl/C4t7Tz for more details.
399
type PushPluginOptions struct {
400
	// The Name of the plugin.
401
	Name string
402

403
	Context context.Context
404
}
405

406
// PushPlugin pushes plugin that opts point or returns an error.
407
//
408
// See https://goo.gl/C4t7Tz for more details.
409
func (c *Client) PushPlugin(opts PushPluginOptions) error {
410
	path := "/plugins/" + opts.Name + "/push"
411
	resp, err := c.do(http.MethodPost, path, doOptions{context: opts.Context})
412
	if err != nil {
413
		return err
414
	}
415
	resp.Body.Close()
416
	return nil
417
}
418

419
// ConfigurePluginOptions specify parameters to the ConfigurePlugin
420
//
421
// See https://goo.gl/C4t7Tz for more details.
422
type ConfigurePluginOptions struct {
423
	// The Name of the plugin.
424
	Name string `qs:"name"`
425
	Envs []string
426

427
	Context context.Context
428
}
429

430
// ConfigurePlugin configures plugin that opts point or returns an error.
431
//
432
// See https://goo.gl/C4t7Tz for more details.
433
func (c *Client) ConfigurePlugin(opts ConfigurePluginOptions) error {
434
	path := "/plugins/" + opts.Name + "/set"
435
	resp, err := c.do(http.MethodPost, path, doOptions{
436
		data:    opts.Envs,
437
		context: opts.Context,
438
	})
439
	if err != nil {
440
		var e *Error
441
		if errors.As(err, &e) && e.Status == http.StatusNotFound {
442
			return &NoSuchPlugin{ID: opts.Name}
443
		}
444
		return err
445
	}
446
	resp.Body.Close()
447
	return nil
448
}
449

450
// NoSuchPlugin is the error returned when a given plugin does not exist.
451
type NoSuchPlugin struct {
452
	ID  string
453
	Err error
454
}
455

456
func (err *NoSuchPlugin) Error() string {
457
	if err.Err != nil {
458
		return err.Err.Error()
459
	}
460
	return "No such plugin: " + err.ID
461
}
462

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.