浏览代码

Implement `docker start` for ACI

Djordje Lukic 5 年之前
父节点
当前提交
1a3182fb7f
共有 6 个文件被更改,包括 114 次插入5 次删除
  1. 32 5
      aci/backend.go
  2. 71 0
      cli/cmd/start.go
  3. 1 0
      cli/main.go
  4. 2 0
      containers/api.go
  5. 4 0
      example/backend.go
  6. 4 0
      local/backend.go

+ 32 - 5
aci/backend.go

@@ -24,6 +24,7 @@ import (
 	"strings"
 	"strings"
 
 
 	"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
 	"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
+	"github.com/Azure/go-autorest/autorest"
 	"github.com/Azure/go-autorest/autorest/to"
 	"github.com/Azure/go-autorest/autorest/to"
 	"github.com/compose-spec/compose-go/cli"
 	"github.com/compose-spec/compose-go/cli"
 	"github.com/compose-spec/compose-go/types"
 	"github.com/compose-spec/compose-go/types"
@@ -224,6 +225,32 @@ func addTag(groupDefinition *containerinstance.ContainerGroup, tagName string) {
 	groupDefinition.Tags[tagName] = to.StringPtr(tagName)
 	groupDefinition.Tags[tagName] = to.StringPtr(tagName)
 }
 }
 
 
+func (cs *aciContainerService) Start(ctx context.Context, containerID string) error {
+	groupName, containerName := getGroupAndContainerName(containerID)
+	if groupName != containerID {
+		msg := "cannot delete service %q from compose application %q, you can delete the entire compose app with docker compose down --project-name %s"
+		return errors.New(fmt.Sprintf(msg, containerName, groupName, groupName))
+	}
+
+	containerGroupsClient, err := getContainerGroupsClient(cs.ctx.SubscriptionID)
+	if err != nil {
+		return err
+	}
+
+	future, err := containerGroupsClient.Start(ctx, cs.ctx.ResourceGroup, containerName)
+	if err != nil {
+		var aerr autorest.DetailedError
+		if ok := errors.As(err, &aerr); ok {
+			if aerr.StatusCode == http.StatusNotFound {
+				return errdefs.ErrNotFound
+			}
+		}
+		return err
+	}
+
+	return future.WaitForCompletionRef(ctx, containerGroupsClient.Client)
+}
+
 func (cs *aciContainerService) Stop(ctx context.Context, containerID string, timeout *uint32) error {
 func (cs *aciContainerService) Stop(ctx context.Context, containerID string, timeout *uint32) error {
 	if timeout != nil && *timeout != uint32(0) {
 	if timeout != nil && *timeout != uint32(0) {
 		return errors.Errorf("ACI integration does not support setting a timeout to stop a container before killing it.")
 		return errors.Errorf("ACI integration does not support setting a timeout to stop a container before killing it.")
@@ -308,12 +335,12 @@ func (cs *aciContainerService) Delete(ctx context.Context, containerID string, r
 		return errors.New(fmt.Sprintf(msg, containerName, groupName, groupName))
 		return errors.New(fmt.Sprintf(msg, containerName, groupName, groupName))
 	}
 	}
 
 
-	containerGroupsClient, err := getContainerGroupsClient(cs.ctx.SubscriptionID)
-	if err != nil {
-		return err
-	}
-
 	if !request.Force {
 	if !request.Force {
+		containerGroupsClient, err := getContainerGroupsClient(cs.ctx.SubscriptionID)
+		if err != nil {
+			return err
+		}
+
 		cg, err := containerGroupsClient.Get(ctx, cs.ctx.ResourceGroup, groupName)
 		cg, err := containerGroupsClient.Get(ctx, cs.ctx.ResourceGroup, groupName)
 		if err != nil {
 		if err != nil {
 			if cg.StatusCode == http.StatusNotFound {
 			if cg.StatusCode == http.StatusNotFound {

+ 71 - 0
cli/cmd/start.go

@@ -0,0 +1,71 @@
+/*
+   Copyright 2020 Docker, 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.
+*/
+
+package cmd
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/docker/api/errdefs"
+
+	"github.com/pkg/errors"
+	"github.com/spf13/cobra"
+
+	"github.com/hashicorp/go-multierror"
+
+	"github.com/docker/api/client"
+)
+
+// StartCommand deletes containers
+func StartCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "start",
+		Short: "Start one or more stopped containers",
+		Args:  cobra.MinimumNArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return runStart(cmd.Context(), args)
+		},
+	}
+
+	return cmd
+}
+
+func runStart(ctx context.Context, args []string) error {
+	c, err := client.New(ctx)
+	if err != nil {
+		return errors.Wrap(err, "cannot connect to backend")
+	}
+
+	var errs *multierror.Error
+	for _, id := range args {
+		err := c.ContainerService().Start(ctx, id)
+		if err != nil {
+			if errdefs.IsNotFoundError(err) {
+				errs = multierror.Append(errs, fmt.Errorf("container %s not found", id))
+			} else {
+				errs = multierror.Append(errs, err)
+			}
+			continue
+		}
+		fmt.Println(id)
+	}
+	if errs != nil {
+		errs.ErrorFormat = formatErrors
+	}
+
+	return errs.ErrorOrNil()
+}

+ 1 - 0
cli/main.go

@@ -119,6 +119,7 @@ func main() {
 		cmd.ExecCommand(),
 		cmd.ExecCommand(),
 		cmd.LogsCommand(),
 		cmd.LogsCommand(),
 		cmd.RmCommand(),
 		cmd.RmCommand(),
+		cmd.StartCommand(),
 		cmd.InspectCommand(),
 		cmd.InspectCommand(),
 		compose.Command(),
 		compose.Command(),
 		login.Command(),
 		login.Command(),

+ 2 - 0
containers/api.go

@@ -114,6 +114,8 @@ type DeleteRequest struct {
 type Service interface {
 type Service interface {
 	// List returns all the containers
 	// List returns all the containers
 	List(ctx context.Context, all bool) ([]Container, error)
 	List(ctx context.Context, all bool) ([]Container, error)
+	// Start starts a stopped container
+	Start(ctx context.Context, containerID string) error
 	// Stop stops the running container
 	// Stop stops the running container
 	Stop(ctx context.Context, containerID string, timeout *uint32) error
 	Stop(ctx context.Context, containerID string, timeout *uint32) error
 	// Run creates and starts a container
 	// Run creates and starts a container

+ 4 - 0
example/backend.go

@@ -92,6 +92,10 @@ func (cs *containerService) Run(ctx context.Context, r containers.ContainerConfi
 	return nil
 	return nil
 }
 }
 
 
+func (cs *containerService) Start(ctx context.Context, containerID string) error {
+	return errors.New("not implemented")
+}
+
 func (cs *containerService) Stop(ctx context.Context, containerName string, timeout *uint32) error {
 func (cs *containerService) Stop(ctx context.Context, containerName string, timeout *uint32) error {
 	return errors.New("not implemented")
 	return errors.New("not implemented")
 }
 }

+ 4 - 0
local/backend.go

@@ -170,6 +170,10 @@ func (ms *local) Run(ctx context.Context, r containers.ContainerConfig) error {
 	return ms.apiClient.ContainerStart(ctx, created.ID, types.ContainerStartOptions{})
 	return ms.apiClient.ContainerStart(ctx, created.ID, types.ContainerStartOptions{})
 }
 }
 
 
+func (ms *local) Start(ctx context.Context, containerID string) error {
+	return ms.apiClient.ContainerStart(ctx, containerID, types.ContainerStartOptions{})
+}
+
 func (ms *local) Stop(ctx context.Context, containerID string, timeout *uint32) error {
 func (ms *local) Stop(ctx context.Context, containerID string, timeout *uint32) error {
 	var t *time.Duration
 	var t *time.Duration
 	if timeout != nil {
 	if timeout != nil {