Pārlūkot izejas kodu

Merge pull request #76 from ulyssessouza/add-rm

Add rm command
Djordje Lukic 5 gadi atpakaļ
vecāks
revīzija
53bc852e3e

+ 1 - 0
Makefile

@@ -32,6 +32,7 @@ all: cli
 
 protos: ## Generate go code from .proto files
 	@docker build . \
+	--output type=local,dest=. \
 	--target protos
 
 cli: ## Compile the cli

+ 5 - 4
azure/aci.go

@@ -98,11 +98,12 @@ func createACIContainers(ctx context.Context, aciContext store.AciContext, group
 	return err
 }
 
-func deleteACIContainerGroup(ctx context.Context, aciContext store.AciContext, containerGroupName string) (c containerinstance.ContainerGroup, err error) {
+func deleteACIContainerGroup(ctx context.Context, aciContext store.AciContext, containerGroupName string) (containerinstance.ContainerGroup, error) {
 	containerGroupsClient, err := getContainerGroupsClient(aciContext.SubscriptionID)
 	if err != nil {
-		return c, fmt.Errorf("cannot get container group client: %v", err)
+		return containerinstance.ContainerGroup{}, fmt.Errorf("cannot get container group client: %v", err)
 	}
+
 	return containerGroupsClient.Delete(ctx, aciContext.ResourceGroup, containerGroupName)
 }
 
@@ -271,7 +272,7 @@ func getSubscriptionsClient() subscription.SubscriptionsClient {
 	return subc
 }
 
-//GetGroupsClient ...
+// GetGroupsClient ...
 func GetGroupsClient(subscriptionID string) resources.GroupsClient {
 	groupsClient := resources.NewGroupsClient(subscriptionID)
 	authorizer, _ := auth.NewAuthorizerFromCLI()
@@ -279,7 +280,7 @@ func GetGroupsClient(subscriptionID string) resources.GroupsClient {
 	return groupsClient
 }
 
-//GetSubscriptionID ...
+// GetSubscriptionID ...
 func GetSubscriptionID(ctx context.Context) (string, error) {
 	c := getSubscriptionsClient()
 	res, err := c.List(ctx)

+ 25 - 1
azure/backend.go

@@ -4,6 +4,7 @@ import (
 	"context"
 	"fmt"
 	"io"
+	"net/http"
 	"strconv"
 	"strings"
 
@@ -23,6 +24,9 @@ import (
 
 const singleContainerName = "single--container--aci"
 
+// ErrNoSuchContainer is returned when the mentioned container does not exist
+var ErrNoSuchContainer = errors.New("no such container")
+
 func init() {
 	backend.Register("aci", "aci", func(ctx context.Context) (backend.Service, error) {
 		return New(ctx)
@@ -214,6 +218,18 @@ func (cs *aciContainerService) Logs(ctx context.Context, containerName string, r
 	return err
 }
 
+func (cs *aciContainerService) Delete(ctx context.Context, containerID string, _ bool) error {
+	cg, err := deleteACIContainerGroup(ctx, cs.ctx, containerID)
+	if err != nil {
+		return err
+	}
+	if cg.StatusCode == http.StatusNoContent {
+		return ErrNoSuchContainer
+	}
+
+	return err
+}
+
 type aciComposeService struct {
 	containerGroupsClient containerinstance.ContainerGroupsClient
 	ctx                   store.AciContext
@@ -239,6 +255,14 @@ func (cs *aciComposeService) Down(ctx context.Context, opts compose.ProjectOptio
 		return err
 	}
 	logrus.Debugf("Down on project with name %q\n", project.Name)
-	_, err = deleteACIContainerGroup(ctx, cs.ctx, project.Name)
+
+	cg, err := deleteACIContainerGroup(ctx, cs.ctx, project.Name)
+	if err != nil {
+		return err
+	}
+	if cg.StatusCode == http.StatusNoContent {
+		return ErrNoSuchContainer
+	}
+
 	return err
 }

+ 1 - 0
azure/convert/convert.go

@@ -10,6 +10,7 @@ import (
 	"github.com/Azure/azure-sdk-for-go/profiles/latest/containerinstance/mgmt/containerinstance"
 	"github.com/Azure/go-autorest/autorest/to"
 	"github.com/compose-spec/compose-go/types"
+
 	"github.com/docker/api/compose"
 	"github.com/docker/api/context/store"
 )

+ 1 - 1
backend/v1/backend.pb.go

@@ -26,7 +26,7 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.21.0-devel
+// 	protoc-gen-go v1.22.0
 // 	protoc        v3.6.1
 // source: backend/v1/backend.proto
 

+ 52 - 0
cli/cmd/rm.go

@@ -0,0 +1,52 @@
+package cmd
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/pkg/errors"
+	"github.com/spf13/cobra"
+
+	"github.com/docker/api/client"
+)
+
+type rmOpts struct {
+	force bool
+}
+
+// RmCommand deletes containers
+func RmCommand() *cobra.Command {
+	var opts rmOpts
+	cmd := &cobra.Command{
+		Use:     "rm",
+		Aliases: []string{"delete"},
+		Short:   "Remove containers",
+		Args:    cobra.MinimumNArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			var errs []string
+			c, err := client.New(cmd.Context())
+			if err != nil {
+				return errors.Wrap(err, "cannot connect to backend")
+			}
+
+			for _, id := range args {
+				err := c.ContainerService().Delete(cmd.Context(), id, opts.force)
+				if err != nil {
+					errs = append(errs, err.Error()+" "+id)
+					continue
+				}
+				fmt.Println(id)
+			}
+
+			if len(errs) > 0 {
+				return errors.New(strings.Join(errs, "\n"))
+			}
+
+			return nil
+		},
+	}
+
+	cmd.Flags().BoolVarP(&opts.force, "force", "f", false, "Force removal")
+
+	return cmd
+}

+ 1 - 0
cli/main.go

@@ -108,6 +108,7 @@ func main() {
 		run.Command(),
 		cmd.ExecCommand(),
 		cmd.LogsCommand(),
+		cmd.RmCommand(),
 		compose.Command(),
 	)
 

+ 1 - 1
cli/v1/cli.pb.go

@@ -26,7 +26,7 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.21.0-devel
+// 	protoc-gen-go v1.22.0
 // 	protoc        v3.6.1
 // source: cli/v1/cli.proto
 

+ 1 - 1
compose/v1/compose.pb.go

@@ -26,7 +26,7 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.21.0-devel
+// 	protoc-gen-go v1.22.0
 // 	protoc        v3.6.1
 // source: compose/v1/compose.proto
 

+ 2 - 0
containers/api.go

@@ -54,4 +54,6 @@ type Service interface {
 	Exec(ctx context.Context, containerName string, command string, reader io.Reader, writer io.Writer) error
 	// Logs returns all the logs of a container
 	Logs(ctx context.Context, containerName string, request LogsRequest) error
+	// Delete removes containers
+	Delete(ctx context.Context, id string, force bool) error
 }

+ 1 - 1
containers/v1/containers.pb.go

@@ -26,7 +26,7 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.21.0-devel
+// 	protoc-gen-go v1.22.0
 // 	protoc        v3.6.1
 // source: containers/v1/containers.proto
 

+ 5 - 0
example/backend.go

@@ -59,6 +59,11 @@ func (cs *containerService) Logs(ctx context.Context, containerName string, requ
 	return nil
 }
 
+func (cs *containerService) Delete(ctx context.Context, id string, force bool) error {
+	fmt.Printf("Deleting container %q with force = %t\n", id, force)
+	return nil
+}
+
 type composeService struct{}
 
 func (cs *composeService) Up(ctx context.Context, opts compose.ProjectOptions) error {

+ 6 - 0
moby/backend.go

@@ -125,3 +125,9 @@ func (ms *mobyService) Logs(ctx context.Context, containerName string, request c
 	_, err = io.Copy(request.Writer, r)
 	return err
 }
+
+func (ms *mobyService) Delete(ctx context.Context, containerID string, force bool) error {
+	return ms.apiClient.ContainerRemove(ctx, containerID, types.ContainerRemoveOptions{
+		Force: force,
+	})
+}

+ 7 - 2
server/proxy/proxy.go

@@ -72,8 +72,13 @@ func (p *proxyContainerAPI) Kill(_ context.Context, _ *v1.KillRequest) (*v1.Kill
 	panic("not implemented") // TODO: Implement
 }
 
-func (p *proxyContainerAPI) Delete(_ context.Context, _ *v1.DeleteRequest) (*v1.DeleteResponse, error) {
-	panic("not implemented") // TODO: Implement
+func (p *proxyContainerAPI) Delete(ctx context.Context, request *v1.DeleteRequest) (*v1.DeleteResponse, error) {
+	err := Client(ctx).ContainerService().Delete(ctx, request.Id, request.Force)
+	if err != nil {
+		return &v1.DeleteResponse{}, err
+	}
+
+	return &v1.DeleteResponse{}, nil
 }
 
 func (p *proxyContainerAPI) Update(_ context.Context, _ *v1.UpdateRequest) (*v1.UpdateResponse, error) {

+ 34 - 34
tests/aci-e2e/e2e-aci.go

@@ -5,16 +5,18 @@ import (
 	"log"
 
 	"github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/resources/mgmt/resources"
+	"github.com/Azure/go-autorest/autorest/to"
+	. "github.com/onsi/gomega"
+
 	"github.com/docker/api/azure"
 	. "github.com/docker/api/tests/framework"
-	. "github.com/onsi/gomega"
 )
 
-const resourceGroupName = "resourceGroupTest"
-
-var location = "westeurope"
-
-const contextName = "acitest"
+const (
+	resourceGroupName = "resourceGroupTest"
+	location          = "westeurope"
+	contextName       = "acitest"
+)
 
 func main() {
 	SetupTest()
@@ -45,7 +47,7 @@ func main() {
 		Expect(err).To(BeNil())
 
 		NewDockerCommand("context", "create", contextName, "aci", "--aci-subscription-id", subscriptionID, "--aci-resource-group", resourceGroupName, "--aci-location", location).ExecOrDie()
-		//Expect(output).To(ContainSubstring("ACI context acitest created"))
+		// Expect(output).To(ContainSubstring("ACI context acitest created"))
 	})
 
 	defer deleteResourceGroup(resourceGroupName)
@@ -62,35 +64,33 @@ func main() {
 		Expect(len(Lines(output))).To(Equal(1))
 	})
 
-	/*
-		var nginxID string
-		It("runs nginx on port 80", func() {
-			NewDockerCommand("run", "nginx", "-p", "80:80").ExecOrDie()
-			output := NewDockerCommand("ps").ExecOrDie()
-			Lines := Lines(output)
-			Expect(len(Lines)).To(Equal(2))
-
-			containerFields := Columns(Lines[1])
-			nginxID = containerFields[0]
-			Expect(containerFields[1]).To(Equal("nginx"))
-			Expect(containerFields[2]).To(Equal("Running"))
-			exposedIP := containerFields[3]
-			Expect(exposedIP).To(ContainSubstring(":80->80/TCP"))
-
-			url := strings.ReplaceAll(exposedIP, "->80/TCP", "")
-			output = NewCommand("curl", url).ExecOrDie()
-			Expect(output).To(ContainSubstring("Welcome to nginx!"))
-		})
-
-		It("removes container nginx", func() {
-			output := NewDockerCommand("rm", nginxID).ExecOrDie()
-			Expect(Lines(output)[0]).To(Equal(nginxID))
-		})
-	*/
+	var nginxID string
+	It("runs nginx on port 80 (PORT NOT CHECKED YET!!! REMOVE THAT WHEN IMPLEMENTED)", func() {
+		NewDockerCommand("run", "nginx", "-p", "80:80").ExecOrDie()
+		output := NewDockerCommand("ps").ExecOrDie()
+		lines := Lines(output)
+		Expect(len(lines)).To(Equal(2))
+
+		containerFields := Columns(lines[1])
+		nginxID = containerFields[0]
+		Expect(containerFields[1]).To(Equal("nginx"))
+		Expect(containerFields[2]).To(Equal("Running"))
+		// exposedIP := containerFields[3]
+		// Expect(exposedIP).To(ContainSubstring(":80->80/TCP"))
+
+		// url := strings.ReplaceAll(exposedIP, "->80/TCP", "")
+		// output = NewCommand("curl", url).ExecOrDie()
+		// Expect(output).To(ContainSubstring("Welcome to nginx!"))
+	})
+
+	It("removes container nginx", func() {
+		output := NewDockerCommand("rm", nginxID).ExecOrDie()
+		Expect(Lines(output)[0]).To(Equal(nginxID))
+	})
 
 	It("deploys a compose app", func() {
 		NewDockerCommand("compose", "up", "-f", "./tests/composefiles/aci-demo/aci_demo_port.yaml", "--name", "acidemo").ExecOrDie()
-		//Expect(output).To(ContainSubstring("Successfully deployed"))
+		// Expect(output).To(ContainSubstring("Successfully deployed"))
 		output := NewDockerCommand("ps").ExecOrDie()
 		Lines := Lines(output)
 		Expect(len(Lines)).To(Equal(4))
@@ -141,7 +141,7 @@ func setupTestResourecGroup(groupName string) {
 	Expect(err).To(BeNil())
 	gc := azure.GetGroupsClient(subscriptionID)
 	_, err = gc.CreateOrUpdate(ctx, groupName, resources.Group{
-		Location: &location,
+		Location: to.StringPtr(location),
 	})
 	Expect(err).To(BeNil())
 }

+ 2 - 1
tests/e2e/e2e.go

@@ -3,8 +3,9 @@ package main
 import (
 	"time"
 
-	. "github.com/docker/api/tests/framework"
 	. "github.com/onsi/gomega"
+
+	. "github.com/docker/api/tests/framework"
 )
 
 func main() {