Signed-off-by: Victor Vieux <vieux@docker.com>
(cherry picked from commit 085895342c7f797f0eef7ec956438e33489f211f)
| ... | ... |
@@ -41,7 +41,8 @@ func runRestart(dockerCli *client.DockerCli, opts *restartOptions) error {
|
| 41 | 41 |
ctx := context.Background() |
| 42 | 42 |
var errs []string |
| 43 | 43 |
for _, name := range opts.containers {
|
| 44 |
- if err := dockerCli.Client().ContainerRestart(ctx, name, time.Duration(opts.nSeconds)*time.Second); err != nil {
|
|
| 44 |
+ timeout := time.Duration(opts.nSeconds) * time.Second |
|
| 45 |
+ if err := dockerCli.Client().ContainerRestart(ctx, name, &timeout); err != nil {
|
|
| 45 | 46 |
errs = append(errs, err.Error()) |
| 46 | 47 |
} else {
|
| 47 | 48 |
fmt.Fprintf(dockerCli.Out(), "%s\n", name) |
| ... | ... |
@@ -43,7 +43,8 @@ func runStop(dockerCli *client.DockerCli, opts *stopOptions) error {
|
| 43 | 43 |
|
| 44 | 44 |
var errs []string |
| 45 | 45 |
for _, container := range opts.containers {
|
| 46 |
- if err := dockerCli.Client().ContainerStop(ctx, container, time.Duration(opts.time)*time.Second); err != nil {
|
|
| 46 |
+ timeout := time.Duration(opts.time) * time.Second |
|
| 47 |
+ if err := dockerCli.Client().ContainerStop(ctx, container, &timeout); err != nil {
|
|
| 47 | 48 |
errs = append(errs, err.Error()) |
| 48 | 49 |
} else {
|
| 49 | 50 |
fmt.Fprintf(dockerCli.Out(), "%s\n", container) |
| ... | ... |
@@ -9,6 +9,7 @@ import ( |
| 9 | 9 |
"github.com/docker/docker/cli" |
| 10 | 10 |
"github.com/docker/engine-api/types/swarm" |
| 11 | 11 |
"github.com/spf13/cobra" |
| 12 |
+ "github.com/spf13/pflag" |
|
| 12 | 13 |
) |
| 13 | 14 |
|
| 14 | 15 |
type initOptions struct {
|
| ... | ... |
@@ -19,6 +20,7 @@ type initOptions struct {
|
| 19 | 19 |
} |
| 20 | 20 |
|
| 21 | 21 |
func newInitCommand(dockerCli *client.DockerCli) *cobra.Command {
|
| 22 |
+ var flags *pflag.FlagSet |
|
| 22 | 23 |
opts := initOptions{
|
| 23 | 24 |
listenAddr: NewNodeAddrOption(), |
| 24 | 25 |
autoAccept: NewAutoAcceptOption(), |
| ... | ... |
@@ -29,11 +31,11 @@ func newInitCommand(dockerCli *client.DockerCli) *cobra.Command {
|
| 29 | 29 |
Short: "Initialize a Swarm.", |
| 30 | 30 |
Args: cli.NoArgs, |
| 31 | 31 |
RunE: func(cmd *cobra.Command, args []string) error {
|
| 32 |
- return runInit(dockerCli, opts) |
|
| 32 |
+ return runInit(dockerCli, flags, opts) |
|
| 33 | 33 |
}, |
| 34 | 34 |
} |
| 35 | 35 |
|
| 36 |
- flags := cmd.Flags() |
|
| 36 |
+ flags = cmd.Flags() |
|
| 37 | 37 |
flags.Var(&opts.listenAddr, "listen-addr", "Listen address") |
| 38 | 38 |
flags.Var(&opts.autoAccept, "auto-accept", "Auto acceptance policy (worker, manager, or none)") |
| 39 | 39 |
flags.StringVar(&opts.secret, "secret", "", "Set secret value needed to accept nodes into cluster") |
| ... | ... |
@@ -41,7 +43,7 @@ func newInitCommand(dockerCli *client.DockerCli) *cobra.Command {
|
| 41 | 41 |
return cmd |
| 42 | 42 |
} |
| 43 | 43 |
|
| 44 |
-func runInit(dockerCli *client.DockerCli, opts initOptions) error {
|
|
| 44 |
+func runInit(dockerCli *client.DockerCli, flags *pflag.FlagSet, opts initOptions) error {
|
|
| 45 | 45 |
client := dockerCli.Client() |
| 46 | 46 |
ctx := context.Background() |
| 47 | 47 |
|
| ... | ... |
@@ -50,8 +52,11 @@ func runInit(dockerCli *client.DockerCli, opts initOptions) error {
|
| 50 | 50 |
ForceNewCluster: opts.forceNewCluster, |
| 51 | 51 |
} |
| 52 | 52 |
|
| 53 |
- req.Spec.AcceptancePolicy.Policies = opts.autoAccept.Policies(opts.secret) |
|
| 54 |
- |
|
| 53 |
+ if flags.Changed("secret") {
|
|
| 54 |
+ req.Spec.AcceptancePolicy.Policies = opts.autoAccept.Policies(&opts.secret) |
|
| 55 |
+ } else {
|
|
| 56 |
+ req.Spec.AcceptancePolicy.Policies = opts.autoAccept.Policies(nil) |
|
| 57 |
+ } |
|
| 55 | 58 |
nodeID, err := client.SwarmInit(ctx, req) |
| 56 | 59 |
if err != nil {
|
| 57 | 60 |
return err |
| ... | ... |
@@ -102,7 +102,7 @@ func (o *AutoAcceptOption) Type() string {
|
| 102 | 102 |
} |
| 103 | 103 |
|
| 104 | 104 |
// Policies returns a representation of this option for the api |
| 105 |
-func (o *AutoAcceptOption) Policies(secret string) []swarm.Policy {
|
|
| 105 |
+func (o *AutoAcceptOption) Policies(secret *string) []swarm.Policy {
|
|
| 106 | 106 |
policies := []swarm.Policy{}
|
| 107 | 107 |
for _, p := range defaultPolicies {
|
| 108 | 108 |
if len(o.values) != 0 {
|
| ... | ... |
@@ -54,6 +54,7 @@ func runUpdate(dockerCli *client.DockerCli, flags *pflag.FlagSet, opts updateOpt |
| 54 | 54 |
if err != nil {
|
| 55 | 55 |
return err |
| 56 | 56 |
} |
| 57 |
+ |
|
| 57 | 58 |
err = client.SwarmUpdate(ctx, swarm.Version, swarm.Spec) |
| 58 | 59 |
if err != nil {
|
| 59 | 60 |
return err |
| ... | ... |
@@ -68,18 +69,17 @@ func mergeSwarm(swarm *swarm.Swarm, flags *pflag.FlagSet) error {
|
| 68 | 68 |
|
| 69 | 69 |
if flags.Changed("auto-accept") {
|
| 70 | 70 |
value := flags.Lookup("auto-accept").Value.(*AutoAcceptOption)
|
| 71 |
- if len(spec.AcceptancePolicy.Policies) > 0 {
|
|
| 72 |
- spec.AcceptancePolicy.Policies = value.Policies(spec.AcceptancePolicy.Policies[0].Secret) |
|
| 73 |
- } else {
|
|
| 74 |
- spec.AcceptancePolicy.Policies = value.Policies("")
|
|
| 75 |
- } |
|
| 71 |
+ spec.AcceptancePolicy.Policies = value.Policies(nil) |
|
| 76 | 72 |
} |
| 77 | 73 |
|
| 74 |
+ var psecret *string |
|
| 78 | 75 |
if flags.Changed("secret") {
|
| 79 | 76 |
secret, _ := flags.GetString("secret")
|
| 80 |
- for _, policy := range spec.AcceptancePolicy.Policies {
|
|
| 81 |
- policy.Secret = secret |
|
| 82 |
- } |
|
| 77 |
+ psecret = &secret |
|
| 78 |
+ } |
|
| 79 |
+ |
|
| 80 |
+ for i := range spec.AcceptancePolicy.Policies {
|
|
| 81 |
+ spec.AcceptancePolicy.Policies[i].Secret = psecret |
|
| 83 | 82 |
} |
| 84 | 83 |
|
| 85 | 84 |
if flags.Changed("task-history-limit") {
|
| ... | ... |
@@ -444,12 +444,12 @@ func (c *Cluster) Update(version uint64, spec types.Spec) error {
|
| 444 | 444 |
return ErrNoManager |
| 445 | 445 |
} |
| 446 | 446 |
|
| 447 |
- swarmSpec, err := convert.SwarmSpecToGRPC(spec) |
|
| 447 |
+ swarm, err := getSwarm(c.getRequestContext(), c.client) |
|
| 448 | 448 |
if err != nil {
|
| 449 | 449 |
return err |
| 450 | 450 |
} |
| 451 | 451 |
|
| 452 |
- swarm, err := getSwarm(c.getRequestContext(), c.client) |
|
| 452 |
+ swarmSpec, err := convert.SwarmSpecToGRPCandMerge(spec, &swarm.Spec) |
|
| 453 | 453 |
if err != nil {
|
| 454 | 454 |
return err |
| 455 | 455 |
} |
| ... | ... |
@@ -1030,7 +1030,7 @@ func initAcceptancePolicy(node *swarmagent.Node, acceptancePolicy types.Acceptan |
| 1030 | 1030 |
} |
| 1031 | 1031 |
spec := &cluster.Spec |
| 1032 | 1032 |
|
| 1033 |
- if err := convert.SwarmSpecUpdateAcceptancePolicy(spec, acceptancePolicy); err != nil {
|
|
| 1033 |
+ if err := convert.SwarmSpecUpdateAcceptancePolicy(spec, acceptancePolicy, nil); err != nil {
|
|
| 1034 | 1034 |
return fmt.Errorf("error updating cluster settings: %v", err)
|
| 1035 | 1035 |
} |
| 1036 | 1036 |
_, err := client.UpdateCluster(ctx, &swarmapi.UpdateClusterRequest{
|
| ... | ... |
@@ -49,7 +49,8 @@ func SwarmFromGRPC(c swarmapi.Cluster) types.Swarm {
|
| 49 | 49 |
Autoaccept: policy.Autoaccept, |
| 50 | 50 |
} |
| 51 | 51 |
if policy.Secret != nil {
|
| 52 |
- p.Secret = string(policy.Secret.Data) |
|
| 52 |
+ secret := string(policy.Secret.Data) |
|
| 53 |
+ p.Secret = &secret |
|
| 53 | 54 |
} |
| 54 | 55 |
swarm.Spec.AcceptancePolicy.Policies = append(swarm.Spec.AcceptancePolicy.Policies, p) |
| 55 | 56 |
} |
| ... | ... |
@@ -57,8 +58,8 @@ func SwarmFromGRPC(c swarmapi.Cluster) types.Swarm {
|
| 57 | 57 |
return swarm |
| 58 | 58 |
} |
| 59 | 59 |
|
| 60 |
-// SwarmSpecToGRPC converts a Spec to a grpc ClusterSpec. |
|
| 61 |
-func SwarmSpecToGRPC(s types.Spec) (swarmapi.ClusterSpec, error) {
|
|
| 60 |
+// SwarmSpecToGRPCandMerge converts a Spec to a grpc ClusterSpec and merge AcceptancePolicy from an existing grpc ClusterSpec if provided. |
|
| 61 |
+func SwarmSpecToGRPCandMerge(s types.Spec, existingSpec *swarmapi.ClusterSpec) (swarmapi.ClusterSpec, error) {
|
|
| 62 | 62 |
spec := swarmapi.ClusterSpec{
|
| 63 | 63 |
Annotations: swarmapi.Annotations{
|
| 64 | 64 |
Name: s.Name, |
| ... | ... |
@@ -82,14 +83,15 @@ func SwarmSpecToGRPC(s types.Spec) (swarmapi.ClusterSpec, error) {
|
| 82 | 82 |
}, |
| 83 | 83 |
} |
| 84 | 84 |
|
| 85 |
- if err := SwarmSpecUpdateAcceptancePolicy(&spec, s.AcceptancePolicy); err != nil {
|
|
| 85 |
+ if err := SwarmSpecUpdateAcceptancePolicy(&spec, s.AcceptancePolicy, existingSpec); err != nil {
|
|
| 86 | 86 |
return swarmapi.ClusterSpec{}, err
|
| 87 | 87 |
} |
| 88 |
+ |
|
| 88 | 89 |
return spec, nil |
| 89 | 90 |
} |
| 90 | 91 |
|
| 91 | 92 |
// SwarmSpecUpdateAcceptancePolicy updates a grpc ClusterSpec using AcceptancePolicy. |
| 92 |
-func SwarmSpecUpdateAcceptancePolicy(spec *swarmapi.ClusterSpec, acceptancePolicy types.AcceptancePolicy) error {
|
|
| 93 |
+func SwarmSpecUpdateAcceptancePolicy(spec *swarmapi.ClusterSpec, acceptancePolicy types.AcceptancePolicy, oldSpec *swarmapi.ClusterSpec) error {
|
|
| 93 | 94 |
spec.AcceptancePolicy.Policies = nil |
| 94 | 95 |
for _, p := range acceptancePolicy.Policies {
|
| 95 | 96 |
role, ok := swarmapi.NodeRole_value[strings.ToUpper(string(p.Role))] |
| ... | ... |
@@ -102,11 +104,20 @@ func SwarmSpecUpdateAcceptancePolicy(spec *swarmapi.ClusterSpec, acceptancePolic |
| 102 | 102 |
Autoaccept: p.Autoaccept, |
| 103 | 103 |
} |
| 104 | 104 |
|
| 105 |
- if p.Secret != "" {
|
|
| 106 |
- hashPwd, _ := bcrypt.GenerateFromPassword([]byte(p.Secret), 0) |
|
| 105 |
+ if p.Secret != nil {
|
|
| 106 |
+ if *p.Secret == "" { // if provided secret is empty, it means erase previous secret.
|
|
| 107 |
+ policy.Secret = nil |
|
| 108 |
+ } else { // if provided secret is not empty, we generate a new one.
|
|
| 109 |
+ hashPwd, _ := bcrypt.GenerateFromPassword([]byte(*p.Secret), 0) |
|
| 110 |
+ policy.Secret = &swarmapi.AcceptancePolicy_RoleAdmissionPolicy_HashedSecret{
|
|
| 111 |
+ Data: hashPwd, |
|
| 112 |
+ Alg: "bcrypt", |
|
| 113 |
+ } |
|
| 114 |
+ } |
|
| 115 |
+ } else if oldSecret := getOldSecret(oldSpec, policy.Role); oldSecret != nil { // else use the old one.
|
|
| 107 | 116 |
policy.Secret = &swarmapi.AcceptancePolicy_RoleAdmissionPolicy_HashedSecret{
|
| 108 |
- Data: hashPwd, |
|
| 109 |
- Alg: "bcrypt", |
|
| 117 |
+ Data: oldSecret.Data, |
|
| 118 |
+ Alg: oldSecret.Alg, |
|
| 110 | 119 |
} |
| 111 | 120 |
} |
| 112 | 121 |
|
| ... | ... |
@@ -114,3 +125,15 @@ func SwarmSpecUpdateAcceptancePolicy(spec *swarmapi.ClusterSpec, acceptancePolic |
| 114 | 114 |
} |
| 115 | 115 |
return nil |
| 116 | 116 |
} |
| 117 |
+ |
|
| 118 |
+func getOldSecret(oldSpec *swarmapi.ClusterSpec, role swarmapi.NodeRole) *swarmapi.AcceptancePolicy_RoleAdmissionPolicy_HashedSecret {
|
|
| 119 |
+ if oldSpec == nil {
|
|
| 120 |
+ return nil |
|
| 121 |
+ } |
|
| 122 |
+ for _, p := range oldSpec.AcceptancePolicy.Policies {
|
|
| 123 |
+ if p.Role == role {
|
|
| 124 |
+ return p.Secret |
|
| 125 |
+ } |
|
| 126 |
+ } |
|
| 127 |
+ return nil |
|
| 128 |
+} |
| ... | ... |
@@ -60,7 +60,7 @@ clone git golang.org/x/net 2beffdc2e92c8a3027590f898fe88f69af48a3f8 https://gith |
| 60 | 60 |
clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://github.com/golang/sys.git |
| 61 | 61 |
clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3 |
| 62 | 62 |
clone git github.com/docker/go-connections fa2850ff103453a9ad190da0df0af134f0314b3d |
| 63 |
-clone git github.com/docker/engine-api f3b5ad20d4576de14c96603db522dec530d03f62 |
|
| 63 |
+clone git github.com/docker/engine-api f50fbe5f9c4c8eeed591549d2c8187f4076f3717 |
|
| 64 | 64 |
clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837 |
| 65 | 65 |
clone git github.com/imdario/mergo 0.2.1 |
| 66 | 66 |
|
| ... | ... |
@@ -26,11 +26,16 @@ func (d *SwarmDaemon) Init(autoAccept map[string]bool, secret string) error {
|
| 26 | 26 |
ListenAddr: d.listenAddr, |
| 27 | 27 |
} |
| 28 | 28 |
for _, role := range []swarm.NodeRole{swarm.NodeRoleManager, swarm.NodeRoleWorker} {
|
| 29 |
- req.Spec.AcceptancePolicy.Policies = append(req.Spec.AcceptancePolicy.Policies, swarm.Policy{
|
|
| 29 |
+ policy := swarm.Policy{
|
|
| 30 | 30 |
Role: role, |
| 31 | 31 |
Autoaccept: autoAccept[strings.ToLower(string(role))], |
| 32 |
- Secret: secret, |
|
| 33 |
- }) |
|
| 32 |
+ } |
|
| 33 |
+ |
|
| 34 |
+ if secret != "" {
|
|
| 35 |
+ policy.Secret = &secret |
|
| 36 |
+ } |
|
| 37 |
+ |
|
| 38 |
+ req.Spec.AcceptancePolicy.Policies = append(req.Spec.AcceptancePolicy.Policies, policy) |
|
| 34 | 39 |
} |
| 35 | 40 |
status, out, err := d.SockRequest("POST", "/swarm/init", req)
|
| 36 | 41 |
if status != http.StatusOK {
|
| ... | ... |
@@ -49,13 +54,17 @@ func (d *SwarmDaemon) Init(autoAccept map[string]bool, secret string) error {
|
| 49 | 49 |
|
| 50 | 50 |
// Join joins a current daemon with existing cluster. |
| 51 | 51 |
func (d *SwarmDaemon) Join(remoteAddr, secret, cahash string, manager bool) error {
|
| 52 |
- status, out, err := d.SockRequest("POST", "/swarm/join", swarm.JoinRequest{
|
|
| 52 |
+ req := swarm.JoinRequest{
|
|
| 53 | 53 |
ListenAddr: d.listenAddr, |
| 54 | 54 |
RemoteAddrs: []string{remoteAddr},
|
| 55 | 55 |
Manager: manager, |
| 56 |
- Secret: secret, |
|
| 57 | 56 |
CACertHash: cahash, |
| 58 |
- }) |
|
| 57 |
+ } |
|
| 58 |
+ |
|
| 59 |
+ if secret != "" {
|
|
| 60 |
+ req.Secret = secret |
|
| 61 |
+ } |
|
| 62 |
+ status, out, err := d.SockRequest("POST", "/swarm/join", req)
|
|
| 59 | 63 |
if status != http.StatusOK {
|
| 60 | 64 |
return fmt.Errorf("joining swarm: invalid statuscode %v, %q", status, out)
|
| 61 | 65 |
} |
| ... | ... |
@@ -11,9 +11,11 @@ import ( |
| 11 | 11 |
// ContainerRestart stops and starts a container again. |
| 12 | 12 |
// It makes the daemon to wait for the container to be up again for |
| 13 | 13 |
// a specific amount of time, given the timeout. |
| 14 |
-func (cli *Client) ContainerRestart(ctx context.Context, containerID string, timeout time.Duration) error {
|
|
| 14 |
+func (cli *Client) ContainerRestart(ctx context.Context, containerID string, timeout *time.Duration) error {
|
|
| 15 | 15 |
query := url.Values{}
|
| 16 |
- query.Set("t", timetypes.DurationToSecondsString(timeout))
|
|
| 16 |
+ if timeout != nil {
|
|
| 17 |
+ query.Set("t", timetypes.DurationToSecondsString(*timeout))
|
|
| 18 |
+ } |
|
| 17 | 19 |
resp, err := cli.post(ctx, "/containers/"+containerID+"/restart", query, nil, nil) |
| 18 | 20 |
ensureReaderClosed(resp) |
| 19 | 21 |
return err |
| ... | ... |
@@ -10,9 +10,11 @@ import ( |
| 10 | 10 |
|
| 11 | 11 |
// ContainerStop stops a container without terminating the process. |
| 12 | 12 |
// The process is blocked until the container stops or the timeout expires. |
| 13 |
-func (cli *Client) ContainerStop(ctx context.Context, containerID string, timeout time.Duration) error {
|
|
| 13 |
+func (cli *Client) ContainerStop(ctx context.Context, containerID string, timeout *time.Duration) error {
|
|
| 14 | 14 |
query := url.Values{}
|
| 15 |
- query.Set("t", timetypes.DurationToSecondsString(timeout))
|
|
| 15 |
+ if timeout != nil {
|
|
| 16 |
+ query.Set("t", timetypes.DurationToSecondsString(*timeout))
|
|
| 17 |
+ } |
|
| 16 | 18 |
resp, err := cli.post(ctx, "/containers/"+containerID+"/stop", query, nil, nil) |
| 17 | 19 |
ensureReaderClosed(resp) |
| 18 | 20 |
return err |
| ... | ... |
@@ -15,26 +15,21 @@ import ( |
| 15 | 15 |
|
| 16 | 16 |
// CommonAPIClient is the common methods between stable and experimental versions of APIClient. |
| 17 | 17 |
type CommonAPIClient interface {
|
| 18 |
+ ContainerAPIClient |
|
| 19 |
+ ImageAPIClient |
|
| 20 |
+ NodeAPIClient |
|
| 21 |
+ NetworkAPIClient |
|
| 22 |
+ ServiceAPIClient |
|
| 23 |
+ SwarmAPIClient |
|
| 24 |
+ SystemAPIClient |
|
| 25 |
+ VolumeAPIClient |
|
| 18 | 26 |
ClientVersion() string |
| 19 |
- CheckpointCreate(ctx context.Context, container string, options types.CheckpointCreateOptions) error |
|
| 20 |
- CheckpointDelete(ctx context.Context, container string, checkpointID string) error |
|
| 21 |
- CheckpointList(ctx context.Context, container string) ([]types.Checkpoint, error) |
|
| 22 |
- SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) |
|
| 23 |
- SwarmJoin(ctx context.Context, req swarm.JoinRequest) error |
|
| 24 |
- SwarmLeave(ctx context.Context, force bool) error |
|
| 25 |
- SwarmInspect(ctx context.Context) (swarm.Swarm, error) |
|
| 26 |
- SwarmUpdate(ctx context.Context, version swarm.Version, swarm swarm.Spec) error |
|
| 27 |
- NodeInspect(ctx context.Context, nodeID string) (swarm.Node, error) |
|
| 28 |
- NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) |
|
| 29 |
- NodeRemove(ctx context.Context, nodeID string) error |
|
| 30 |
- NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error |
|
| 31 |
- ServiceCreate(ctx context.Context, service swarm.ServiceSpec) (types.ServiceCreateResponse, error) |
|
| 32 |
- ServiceInspect(ctx context.Context, serviceID string) (swarm.Service, error) |
|
| 33 |
- ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) |
|
| 34 |
- ServiceRemove(ctx context.Context, serviceID string) error |
|
| 35 |
- ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec) error |
|
| 36 |
- TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) |
|
| 37 |
- TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) |
|
| 27 |
+ ServerVersion(ctx context.Context) (types.Version, error) |
|
| 28 |
+ UpdateClientVersion(v string) |
|
| 29 |
+} |
|
| 30 |
+ |
|
| 31 |
+// ContainerAPIClient defines API client methods for the containers |
|
| 32 |
+type ContainerAPIClient interface {
|
|
| 38 | 33 |
ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error) |
| 39 | 34 |
ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.ContainerCommitResponse, error) |
| 40 | 35 |
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (types.ContainerCreateResponse, error) |
| ... | ... |
@@ -54,18 +49,21 @@ type CommonAPIClient interface {
|
| 54 | 54 |
ContainerRemove(ctx context.Context, container string, options types.ContainerRemoveOptions) error |
| 55 | 55 |
ContainerRename(ctx context.Context, container, newContainerName string) error |
| 56 | 56 |
ContainerResize(ctx context.Context, container string, options types.ResizeOptions) error |
| 57 |
- ContainerRestart(ctx context.Context, container string, timeout time.Duration) error |
|
| 57 |
+ ContainerRestart(ctx context.Context, container string, timeout *time.Duration) error |
|
| 58 | 58 |
ContainerStatPath(ctx context.Context, container, path string) (types.ContainerPathStat, error) |
| 59 | 59 |
ContainerStats(ctx context.Context, container string, stream bool) (io.ReadCloser, error) |
| 60 | 60 |
ContainerStart(ctx context.Context, container string, options types.ContainerStartOptions) error |
| 61 |
- ContainerStop(ctx context.Context, container string, timeout time.Duration) error |
|
| 61 |
+ ContainerStop(ctx context.Context, container string, timeout *time.Duration) error |
|
| 62 | 62 |
ContainerTop(ctx context.Context, container string, arguments []string) (types.ContainerProcessList, error) |
| 63 | 63 |
ContainerUnpause(ctx context.Context, container string) error |
| 64 | 64 |
ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) error |
| 65 | 65 |
ContainerWait(ctx context.Context, container string) (int, error) |
| 66 | 66 |
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) |
| 67 | 67 |
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error |
| 68 |
- Events(ctx context.Context, options types.EventsOptions) (io.ReadCloser, error) |
|
| 68 |
+} |
|
| 69 |
+ |
|
| 70 |
+// ImageAPIClient defines API client methods for the images |
|
| 71 |
+type ImageAPIClient interface {
|
|
| 69 | 72 |
ImageBuild(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) |
| 70 | 73 |
ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) |
| 71 | 74 |
ImageHistory(ctx context.Context, image string) ([]types.ImageHistory, error) |
| ... | ... |
@@ -79,7 +77,10 @@ type CommonAPIClient interface {
|
| 79 | 79 |
ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) |
| 80 | 80 |
ImageSave(ctx context.Context, images []string) (io.ReadCloser, error) |
| 81 | 81 |
ImageTag(ctx context.Context, image, ref string) error |
| 82 |
- Info(ctx context.Context) (types.Info, error) |
|
| 82 |
+} |
|
| 83 |
+ |
|
| 84 |
+// NetworkAPIClient defines API client methods for the networks |
|
| 85 |
+type NetworkAPIClient interface {
|
|
| 83 | 86 |
NetworkConnect(ctx context.Context, networkID, container string, config *network.EndpointSettings) error |
| 84 | 87 |
NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) |
| 85 | 88 |
NetworkDisconnect(ctx context.Context, networkID, container string, force bool) error |
| ... | ... |
@@ -87,9 +88,45 @@ type CommonAPIClient interface {
|
| 87 | 87 |
NetworkInspectWithRaw(ctx context.Context, networkID string) (types.NetworkResource, []byte, error) |
| 88 | 88 |
NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) |
| 89 | 89 |
NetworkRemove(ctx context.Context, networkID string) error |
| 90 |
+} |
|
| 91 |
+ |
|
| 92 |
+// NodeAPIClient defines API client methods for the nodes |
|
| 93 |
+type NodeAPIClient interface {
|
|
| 94 |
+ NodeInspect(ctx context.Context, nodeID string) (swarm.Node, error) |
|
| 95 |
+ NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) |
|
| 96 |
+ NodeRemove(ctx context.Context, nodeID string) error |
|
| 97 |
+ NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error |
|
| 98 |
+} |
|
| 99 |
+ |
|
| 100 |
+// ServiceAPIClient defines API client methods for the services |
|
| 101 |
+type ServiceAPIClient interface {
|
|
| 102 |
+ ServiceCreate(ctx context.Context, service swarm.ServiceSpec) (types.ServiceCreateResponse, error) |
|
| 103 |
+ ServiceInspect(ctx context.Context, serviceID string) (swarm.Service, error) |
|
| 104 |
+ ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) |
|
| 105 |
+ ServiceRemove(ctx context.Context, serviceID string) error |
|
| 106 |
+ ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec) error |
|
| 107 |
+ TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) |
|
| 108 |
+ TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) |
|
| 109 |
+} |
|
| 110 |
+ |
|
| 111 |
+// SwarmAPIClient defines API client methods for the swarm |
|
| 112 |
+type SwarmAPIClient interface {
|
|
| 113 |
+ SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) |
|
| 114 |
+ SwarmJoin(ctx context.Context, req swarm.JoinRequest) error |
|
| 115 |
+ SwarmLeave(ctx context.Context, force bool) error |
|
| 116 |
+ SwarmInspect(ctx context.Context) (swarm.Swarm, error) |
|
| 117 |
+ SwarmUpdate(ctx context.Context, version swarm.Version, swarm swarm.Spec) error |
|
| 118 |
+} |
|
| 119 |
+ |
|
| 120 |
+// SystemAPIClient defines API client methods for the system |
|
| 121 |
+type SystemAPIClient interface {
|
|
| 122 |
+ Events(ctx context.Context, options types.EventsOptions) (io.ReadCloser, error) |
|
| 123 |
+ Info(ctx context.Context) (types.Info, error) |
|
| 90 | 124 |
RegistryLogin(ctx context.Context, auth types.AuthConfig) (types.AuthResponse, error) |
| 91 |
- ServerVersion(ctx context.Context) (types.Version, error) |
|
| 92 |
- UpdateClientVersion(v string) |
|
| 125 |
+} |
|
| 126 |
+ |
|
| 127 |
+// VolumeAPIClient defines API client methods for the volumes |
|
| 128 |
+type VolumeAPIClient interface {
|
|
| 93 | 129 |
VolumeCreate(ctx context.Context, options types.VolumeCreateRequest) (types.Volume, error) |
| 94 | 130 |
VolumeInspect(ctx context.Context, volumeID string) (types.Volume, error) |
| 95 | 131 |
VolumeInspectWithRaw(ctx context.Context, volumeID string) (types.Volume, []byte, error) |
| ... | ... |
@@ -12,6 +12,19 @@ import ( |
| 12 | 12 |
// APIClient is an interface that clients that talk with a docker server must implement. |
| 13 | 13 |
type APIClient interface {
|
| 14 | 14 |
CommonAPIClient |
| 15 |
+ CheckpointAPIClient |
|
| 16 |
+ PluginAPIClient |
|
| 17 |
+} |
|
| 18 |
+ |
|
| 19 |
+// CheckpointAPIClient defines API client methods for the checkpoints |
|
| 20 |
+type CheckpointAPIClient interface {
|
|
| 21 |
+ CheckpointCreate(ctx context.Context, container string, options types.CheckpointCreateOptions) error |
|
| 22 |
+ CheckpointDelete(ctx context.Context, container string, checkpointID string) error |
|
| 23 |
+ CheckpointList(ctx context.Context, container string) ([]types.Checkpoint, error) |
|
| 24 |
+} |
|
| 25 |
+ |
|
| 26 |
+// PluginAPIClient defines API client methods for the plugins |
|
| 27 |
+type PluginAPIClient interface {
|
|
| 15 | 28 |
PluginList(ctx context.Context) (types.PluginsListResponse, error) |
| 16 | 29 |
PluginRemove(ctx context.Context, name string) error |
| 17 | 30 |
PluginEnable(ctx context.Context, name string) error |
| ... | ... |
@@ -303,7 +303,7 @@ type HostConfig struct {
|
| 303 | 303 |
PublishAllPorts bool // Should docker publish all exposed port for the container |
| 304 | 304 |
ReadonlyRootfs bool // Is the container root filesystem in read-only |
| 305 | 305 |
SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux. |
| 306 |
- StorageOpt map[string]string // Storage driver options per container. |
|
| 306 |
+ StorageOpt map[string]string `json:",omitempty"` // Storage driver options per container. |
|
| 307 | 307 |
Tmpfs map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container |
| 308 | 308 |
UTSMode UTSMode // UTS namespace to use for the container |
| 309 | 309 |
UsernsMode UsernsMode // The user namespace to use for the container |