mirror of https://github.com/docker/compose.git
ACI Stop implementation
This commit is contained in:
parent
f3aeb318f6
commit
ee062e8333
15
aci/aci.go
15
aci/aci.go
|
@ -24,6 +24,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/docker/api/errdefs"
|
||||||
|
|
||||||
"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"
|
||||||
"github.com/Azure/go-autorest/autorest/to"
|
"github.com/Azure/go-autorest/autorest/to"
|
||||||
|
@ -139,6 +141,19 @@ func deleteACIContainerGroup(ctx context.Context, aciContext store.AciContext, c
|
||||||
return containerGroupsClient.Delete(ctx, aciContext.ResourceGroup, containerGroupName)
|
return containerGroupsClient.Delete(ctx, aciContext.ResourceGroup, containerGroupName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stopACIContainerGroup(ctx context.Context, aciContext store.AciContext, containerGroupName string) error {
|
||||||
|
containerGroupsClient, err := getContainerGroupsClient(aciContext.SubscriptionID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot get container group client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := containerGroupsClient.Stop(ctx, aciContext.ResourceGroup, containerGroupName)
|
||||||
|
if result.StatusCode == http.StatusNotFound {
|
||||||
|
return errdefs.ErrNotFound
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func execACIContainer(ctx context.Context, aciContext store.AciContext, command, containerGroup string, containerName string) (c containerinstance.ContainerExecResponse, err error) {
|
func execACIContainer(ctx context.Context, aciContext store.AciContext, command, containerGroup string, containerName string) (c containerinstance.ContainerExecResponse, err error) {
|
||||||
containerClient, err := getContainerClient(aciContext.SubscriptionID)
|
containerClient, err := getContainerClient(aciContext.SubscriptionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -221,8 +221,16 @@ func addTag(groupDefinition *containerinstance.ContainerGroup, tagName string) {
|
||||||
groupDefinition.Tags[tagName] = to.StringPtr(tagName)
|
groupDefinition.Tags[tagName] = to.StringPtr(tagName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *aciContainerService) Stop(ctx context.Context, containerName string, timeout *uint32) error {
|
func (cs *aciContainerService) Stop(ctx context.Context, containerID string, timeout *uint32) error {
|
||||||
return errdefs.ErrNotImplemented
|
if timeout != nil && *timeout != uint32(0) {
|
||||||
|
return errors.Errorf("ACI integration does not support setting a timeout to stop a container before killing it.")
|
||||||
|
}
|
||||||
|
groupName, containerName := getGroupAndContainerName(containerID)
|
||||||
|
if groupName != containerID {
|
||||||
|
msg := "cannot stop service %q from compose application %q, you can stop the entire compose app with docker stop %s"
|
||||||
|
return errors.New(fmt.Sprintf(msg, containerName, groupName, groupName))
|
||||||
|
}
|
||||||
|
return stopACIContainerGroup(ctx, cs.ctx, groupName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getGroupAndContainerName(containerID string) (string, string) {
|
func getGroupAndContainerName(containerID string) (string, string) {
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
type stopOpts struct {
|
||||||
|
timeout uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopCommand deletes containers
|
||||||
|
func StopCommand() *cobra.Command {
|
||||||
|
var opts stopOpts
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "stop",
|
||||||
|
Short: "Stop one or more running containers",
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return runStop(cmd.Context(), args, opts)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().Uint32Var(&opts.timeout, "timeout", 0, "Seconds to wait for stop before killing it (default 0, no timeout)")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func runStop(ctx context.Context, args []string, opts stopOpts) 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().Stop(ctx, id, &opts.timeout)
|
||||||
|
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()
|
||||||
|
}
|
|
@ -124,6 +124,7 @@ func main() {
|
||||||
login.Command(),
|
login.Command(),
|
||||||
logout.Command(),
|
logout.Command(),
|
||||||
cmd.VersionCommand(version),
|
cmd.VersionCommand(version),
|
||||||
|
cmd.StopCommand(),
|
||||||
)
|
)
|
||||||
|
|
||||||
helpFunc := root.HelpFunc()
|
helpFunc := root.HelpFunc()
|
||||||
|
|
|
@ -360,8 +360,21 @@ func TestContainerRunAttached(t *testing.T) {
|
||||||
poll.WaitOn(t, checkLog, poll.WithDelay(1*time.Second), poll.WithTimeout(20*time.Second))
|
poll.WaitOn(t, checkLog, poll.WithDelay(1*time.Second), poll.WithTimeout(20*time.Second))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("rm attached", func(t *testing.T) {
|
t.Run("stop wrong container", func(t *testing.T) {
|
||||||
res := c.RunDockerCmd("rm", "-f", container)
|
res := c.RunDockerCmd("stop", "unknown-container")
|
||||||
|
res.Assert(t, icmd.Expected{
|
||||||
|
Err: "Error: container unknown-container not found",
|
||||||
|
ExitCode: 1,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("stop container", func(t *testing.T) {
|
||||||
|
res := c.RunDockerCmd("stop", container)
|
||||||
|
res.Assert(t, icmd.Expected{Out: container})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("rm stopped container", func(t *testing.T) {
|
||||||
|
res := c.RunDockerCmd("rm", container)
|
||||||
res.Assert(t, icmd.Expected{Out: container})
|
res.Assert(t, icmd.Expected{Out: container})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue