mirror of
https://github.com/docker/compose.git
synced 2025-07-01 19:04:34 +02:00
Merge pull request #99 from docker/feat-stop
Add `Stop` command on the gRPC side.
This commit is contained in:
commit
cf1be96833
@ -9,6 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/api/context/cloud"
|
"github.com/docker/api/context/cloud"
|
||||||
|
"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/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
@ -101,7 +102,7 @@ type aciContainerService struct {
|
|||||||
ctx store.AciContext
|
ctx store.AciContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *aciContainerService) List(ctx context.Context) ([]containers.Container, error) {
|
func (cs *aciContainerService) List(ctx context.Context, _ bool) ([]containers.Container, error) {
|
||||||
var containerGroups []containerinstance.ContainerGroup
|
var containerGroups []containerinstance.ContainerGroup
|
||||||
result, err := cs.containerGroupsClient.ListByResourceGroup(ctx, cs.ctx.ResourceGroup)
|
result, err := cs.containerGroupsClient.ListByResourceGroup(ctx, cs.ctx.ResourceGroup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -177,6 +178,10 @@ func (cs *aciContainerService) Run(ctx context.Context, r containers.ContainerCo
|
|||||||
return createACIContainers(ctx, cs.ctx, groupDefinition)
|
return createACIContainers(ctx, cs.ctx, groupDefinition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cs *aciContainerService) Stop(ctx context.Context, containerName string, timeout *uint32) error {
|
||||||
|
return errdefs.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
func getGroupAndContainerName(containerID string) (groupName string, containerName string) {
|
func getGroupAndContainerName(containerID string) (groupName string, containerName string) {
|
||||||
tokens := strings.Split(containerID, "_")
|
tokens := strings.Split(containerID, "_")
|
||||||
groupName = tokens[0]
|
groupName = tokens[0]
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type psOpts struct {
|
type psOpts struct {
|
||||||
|
all bool
|
||||||
quiet bool
|
quiet bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ func PsCommand() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().BoolVarP(&opts.quiet, "quiet", "q", false, "Only display IDs")
|
cmd.Flags().BoolVarP(&opts.quiet, "quiet", "q", false, "Only display IDs")
|
||||||
|
cmd.Flags().BoolVarP(&opts.all, "all", "a", false, "Show all containers (default shows just running)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@ -40,7 +42,7 @@ func runPs(ctx context.Context, opts psOpts) error {
|
|||||||
return errors.Wrap(err, "cannot connect to backend")
|
return errors.Wrap(err, "cannot connect to backend")
|
||||||
}
|
}
|
||||||
|
|
||||||
containers, err := c.ContainerService().List(ctx)
|
containers, err := c.ContainerService().List(ctx, opts.all)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "fetch containers")
|
return errors.Wrap(err, "fetch containers")
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,9 @@ type LogsRequest struct {
|
|||||||
// Service interacts with the underlying container backend
|
// Service interacts with the underlying container backend
|
||||||
type Service interface {
|
type Service interface {
|
||||||
// List returns all the containers
|
// List returns all the containers
|
||||||
List(ctx context.Context) ([]Container, error)
|
List(ctx context.Context, all bool) ([]Container, error)
|
||||||
|
// Stop stops the running container
|
||||||
|
Stop(ctx context.Context, containerID string, timeout *uint32) error
|
||||||
// Run creates and starts a container
|
// Run creates and starts a container
|
||||||
Run(ctx context.Context, config ContainerConfig) error
|
Run(ctx context.Context, config ContainerConfig) error
|
||||||
// Exec executes a command inside a running container
|
// Exec executes a command inside a running container
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -42,16 +42,25 @@ service Containers {
|
|||||||
rpc Exec(ExecRequest) returns (ExecResponse);
|
rpc Exec(ExecRequest) returns (ExecResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Port {
|
||||||
|
uint32 host_port = 1;
|
||||||
|
uint32 container_port = 2;
|
||||||
|
string protocol = 3;
|
||||||
|
string host_ip = 4;
|
||||||
|
}
|
||||||
|
|
||||||
message Container {
|
message Container {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
string image = 2;
|
string image = 2;
|
||||||
string status = 3;
|
string status = 3;
|
||||||
uint64 cpu_time = 4;
|
string command = 4;
|
||||||
uint64 memory_usage = 5;
|
uint64 cpu_time = 5;
|
||||||
uint64 memory_limit = 6;
|
uint64 memory_usage = 6;
|
||||||
uint64 pids_current = 7;
|
uint64 memory_limit = 7;
|
||||||
uint64 pids_limit = 8;
|
uint64 pids_current = 8;
|
||||||
map<string, string> labels = 9;
|
uint64 pids_limit = 9;
|
||||||
|
repeated string labels = 10;
|
||||||
|
repeated Port ports = 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateRequest {
|
message CreateRequest {
|
||||||
@ -110,7 +119,7 @@ message StartResponse {
|
|||||||
|
|
||||||
message StopRequest {
|
message StopRequest {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
int64 signal = 2;
|
uint32 timeout = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message StopResponse {
|
message StopResponse {
|
||||||
@ -139,7 +148,7 @@ message KillResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message ListRequest {
|
message ListRequest {
|
||||||
repeated string filters = 1;
|
bool all = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListResponse {
|
message ListResponse {
|
||||||
|
@ -42,6 +42,9 @@ var (
|
|||||||
ErrUnknown = errors.New("unknown")
|
ErrUnknown = errors.New("unknown")
|
||||||
// ErrLoginFailed is returned when login failed
|
// ErrLoginFailed is returned when login failed
|
||||||
ErrLoginFailed = errors.New("login failed")
|
ErrLoginFailed = errors.New("login failed")
|
||||||
|
// ErrNotImplemented is returned when a backend doesn't implement
|
||||||
|
// an action
|
||||||
|
ErrNotImplemented = errors.New("not implemented")
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsNotFoundError returns true if the unwrapped error is ErrNotFound
|
// IsNotFoundError returns true if the unwrapped error is ErrNotFound
|
||||||
@ -63,3 +66,8 @@ func IsForbiddenError(err error) bool {
|
|||||||
func IsUnknownError(err error) bool {
|
func IsUnknownError(err error) bool {
|
||||||
return errors.Is(err, ErrUnknown)
|
return errors.Is(err, ErrUnknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsErrNotImplemented returns true if the unwrapped error is ErrNotImplemented
|
||||||
|
func IsErrNotImplemented(err error) bool {
|
||||||
|
return errors.Is(err, ErrNotImplemented)
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@ package example
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
@ -37,8 +38,8 @@ func init() {
|
|||||||
|
|
||||||
type containerService struct{}
|
type containerService struct{}
|
||||||
|
|
||||||
func (cs *containerService) List(ctx context.Context) ([]containers.Container, error) {
|
func (cs *containerService) List(ctx context.Context, all bool) ([]containers.Container, error) {
|
||||||
return []containers.Container{
|
result := []containers.Container{
|
||||||
{
|
{
|
||||||
ID: "id",
|
ID: "id",
|
||||||
Image: "nginx",
|
Image: "nginx",
|
||||||
@ -47,7 +48,16 @@ func (cs *containerService) List(ctx context.Context) ([]containers.Container, e
|
|||||||
ID: "1234",
|
ID: "1234",
|
||||||
Image: "alpine",
|
Image: "alpine",
|
||||||
},
|
},
|
||||||
}, nil
|
}
|
||||||
|
|
||||||
|
if all {
|
||||||
|
result = append(result, containers.Container{
|
||||||
|
ID: "stopped",
|
||||||
|
Image: "nginx",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *containerService) Run(ctx context.Context, r containers.ContainerConfig) error {
|
func (cs *containerService) Run(ctx context.Context, r containers.ContainerConfig) error {
|
||||||
@ -55,6 +65,10 @@ func (cs *containerService) Run(ctx context.Context, r containers.ContainerConfi
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cs *containerService) Stop(ctx context.Context, containerName string, timeout *uint32) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
func (cs *containerService) Exec(ctx context.Context, name string, command string, reader io.Reader, writer io.Writer) error {
|
func (cs *containerService) Exec(ctx context.Context, name string, command string, reader io.Reader, writer io.Writer) error {
|
||||||
fmt.Printf("Executing command %q on container %q", command, name)
|
fmt.Printf("Executing command %q on container %q", command, name)
|
||||||
return nil
|
return nil
|
||||||
|
@ -3,6 +3,7 @@ package moby
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/docker/api/context/cloud"
|
"github.com/docker/api/context/cloud"
|
||||||
|
|
||||||
@ -51,10 +52,11 @@ func (ms *mobyService) CloudService() cloud.Service {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms *mobyService) List(ctx context.Context) ([]containers.Container, error) {
|
func (ms *mobyService) List(ctx context.Context, all bool) ([]containers.Container, error) {
|
||||||
css, err := ms.apiClient.ContainerList(ctx, types.ContainerListOptions{
|
css, err := ms.apiClient.ContainerList(ctx, types.ContainerListOptions{
|
||||||
All: false,
|
All: all,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []containers.Container{}, err
|
return []containers.Container{}, err
|
||||||
}
|
}
|
||||||
@ -62,8 +64,12 @@ func (ms *mobyService) List(ctx context.Context) ([]containers.Container, error)
|
|||||||
var result []containers.Container
|
var result []containers.Container
|
||||||
for _, container := range css {
|
for _, container := range css {
|
||||||
result = append(result, containers.Container{
|
result = append(result, containers.Container{
|
||||||
ID: container.ID,
|
ID: container.ID,
|
||||||
Image: container.Image,
|
Image: container.Image,
|
||||||
|
// TODO: `Status` is a human readable string ("Up 24 minutes"),
|
||||||
|
// we need to return the `State` instead but first we need to
|
||||||
|
// define an enum on the proto side with all the possible container
|
||||||
|
// statuses. We also need to add a `Created` property on the gRPC side.
|
||||||
Status: container.Status,
|
Status: container.Status,
|
||||||
Command: container.Command,
|
Command: container.Command,
|
||||||
Ports: getPorts(container.Ports),
|
Ports: getPorts(container.Ports),
|
||||||
@ -85,6 +91,15 @@ func (ms *mobyService) Run(ctx context.Context, r containers.ContainerConfig) er
|
|||||||
return ms.apiClient.ContainerStart(ctx, create.ID, types.ContainerStartOptions{})
|
return ms.apiClient.ContainerStart(ctx, create.ID, types.ContainerStartOptions{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ms *mobyService) Stop(ctx context.Context, containerID string, timeout *uint32) error {
|
||||||
|
var t *time.Duration
|
||||||
|
if timeout != nil {
|
||||||
|
timeoutValue := time.Duration(*timeout) * time.Second
|
||||||
|
t = &timeoutValue
|
||||||
|
}
|
||||||
|
return ms.apiClient.ContainerStop(ctx, containerID, t)
|
||||||
|
}
|
||||||
|
|
||||||
func (ms *mobyService) Exec(ctx context.Context, name string, command string, reader io.Reader, writer io.Writer) error {
|
func (ms *mobyService) Exec(ctx context.Context, name string, command string, reader io.Reader, writer io.Writer) error {
|
||||||
cec, err := ms.apiClient.ContainerExecCreate(ctx, name, types.ExecConfig{
|
cec, err := ms.apiClient.ContainerExecCreate(ctx, name, types.ExecConfig{
|
||||||
Cmd: []string{command},
|
Cmd: []string{command},
|
||||||
|
103
server/proxy/containers.go
Normal file
103
server/proxy/containers.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/docker/api/containers"
|
||||||
|
v1 "github.com/docker/api/containers/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewContainerAPI creates a proxy container server
|
||||||
|
func NewContainerAPI() v1.ContainersServer {
|
||||||
|
return &proxyContainerAPI{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type proxyContainerAPI struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func portsToGrpc(ports []containers.Port) []*v1.Port {
|
||||||
|
var result []*v1.Port
|
||||||
|
for _, port := range ports {
|
||||||
|
result = append(result, &v1.Port{
|
||||||
|
ContainerPort: port.ContainerPort,
|
||||||
|
HostPort: port.HostPort,
|
||||||
|
HostIp: port.HostIP,
|
||||||
|
Protocol: port.Protocol,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *proxyContainerAPI) List(ctx context.Context, request *v1.ListRequest) (*v1.ListResponse, error) {
|
||||||
|
client := Client(ctx)
|
||||||
|
|
||||||
|
c, err := client.ContainerService().List(ctx, request.GetAll())
|
||||||
|
if err != nil {
|
||||||
|
return &v1.ListResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &v1.ListResponse{
|
||||||
|
Containers: []*v1.Container{},
|
||||||
|
}
|
||||||
|
for _, container := range c {
|
||||||
|
response.Containers = append(response.Containers, &v1.Container{
|
||||||
|
Id: container.ID,
|
||||||
|
Image: container.Image,
|
||||||
|
Command: container.Command,
|
||||||
|
Status: container.Status,
|
||||||
|
CpuTime: container.CPUTime,
|
||||||
|
Labels: container.Labels,
|
||||||
|
MemoryLimit: container.MemoryLimit,
|
||||||
|
MemoryUsage: container.MemoryUsage,
|
||||||
|
PidsCurrent: container.PidsCurrent,
|
||||||
|
PidsLimit: container.PidsLimit,
|
||||||
|
Ports: portsToGrpc(container.Ports),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *proxyContainerAPI) Create(ctx context.Context, request *v1.CreateRequest) (*v1.CreateResponse, error) {
|
||||||
|
client := Client(ctx)
|
||||||
|
|
||||||
|
err := client.ContainerService().Run(ctx, containers.ContainerConfig{
|
||||||
|
ID: request.Id,
|
||||||
|
Image: request.Image,
|
||||||
|
})
|
||||||
|
|
||||||
|
return &v1.CreateResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *proxyContainerAPI) Start(_ context.Context, request *v1.StartRequest) (*v1.StartResponse, error) {
|
||||||
|
panic("not implemented") // TODO: Implement
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *proxyContainerAPI) Stop(ctx context.Context, request *v1.StopRequest) (*v1.StopResponse, error) {
|
||||||
|
c := Client(ctx)
|
||||||
|
timeoutValue := request.GetTimeout()
|
||||||
|
return &v1.StopResponse{}, c.ContainerService().Stop(ctx, request.Id, &timeoutValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *proxyContainerAPI) Kill(ctx context.Context, request *v1.KillRequest) (*v1.KillResponse, error) {
|
||||||
|
c := Client(ctx)
|
||||||
|
return &v1.KillResponse{}, c.ContainerService().Delete(ctx, request.Id, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
panic("not implemented") // TODO: Implement
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *proxyContainerAPI) Exec(_ context.Context, _ *v1.ExecRequest) (*v1.ExecResponse, error) {
|
||||||
|
panic("not implemented") // TODO: Implement
|
||||||
|
}
|
@ -4,8 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/docker/api/client"
|
"github.com/docker/api/client"
|
||||||
"github.com/docker/api/containers"
|
|
||||||
v1 "github.com/docker/api/containers/v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type clientKey struct{}
|
type clientKey struct{}
|
||||||
@ -20,71 +18,3 @@ func Client(ctx context.Context) *client.Client {
|
|||||||
c, _ := ctx.Value(clientKey{}).(*client.Client)
|
c, _ := ctx.Value(clientKey{}).(*client.Client)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContainerAPI creates a proxy container server
|
|
||||||
func NewContainerAPI() v1.ContainersServer {
|
|
||||||
return &proxyContainerAPI{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type proxyContainerAPI struct{}
|
|
||||||
|
|
||||||
func (p *proxyContainerAPI) List(ctx context.Context, _ *v1.ListRequest) (*v1.ListResponse, error) {
|
|
||||||
client := Client(ctx)
|
|
||||||
|
|
||||||
c, err := client.ContainerService().List(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return &v1.ListResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
response := &v1.ListResponse{
|
|
||||||
Containers: []*v1.Container{},
|
|
||||||
}
|
|
||||||
for _, container := range c {
|
|
||||||
response.Containers = append(response.Containers, &v1.Container{
|
|
||||||
Id: container.ID,
|
|
||||||
Image: container.Image,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *proxyContainerAPI) Create(ctx context.Context, request *v1.CreateRequest) (*v1.CreateResponse, error) {
|
|
||||||
client := Client(ctx)
|
|
||||||
|
|
||||||
err := client.ContainerService().Run(ctx, containers.ContainerConfig{
|
|
||||||
ID: request.Id,
|
|
||||||
Image: request.Image,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &v1.CreateResponse{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *proxyContainerAPI) Start(_ context.Context, _ *v1.StartRequest) (*v1.StartResponse, error) {
|
|
||||||
panic("not implemented") // TODO: Implement
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *proxyContainerAPI) Stop(_ context.Context, _ *v1.StopRequest) (*v1.StopResponse, error) {
|
|
||||||
panic("not implemented") // TODO: Implement
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *proxyContainerAPI) Kill(_ context.Context, _ *v1.KillRequest) (*v1.KillResponse, 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) {
|
|
||||||
panic("not implemented") // TODO: Implement
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *proxyContainerAPI) Exec(_ context.Context, _ *v1.ExecRequest) (*v1.ExecResponse, error) {
|
|
||||||
panic("not implemented") // TODO: Implement
|
|
||||||
}
|
|
||||||
|
@ -29,7 +29,6 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -78,29 +77,33 @@ func stream(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo,
|
|||||||
func unaryMeta(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
func unaryMeta(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||||
md, ok := metadata.FromIncomingContext(ctx)
|
md, ok := metadata.FromIncomingContext(ctx)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("missing metadata")
|
return handler(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
key := md[apicontext.Key]
|
key, ok := md[apicontext.Key]
|
||||||
|
if !ok {
|
||||||
|
return handler(ctx, req)
|
||||||
|
}
|
||||||
|
|
||||||
if len(key) == 1 {
|
if len(key) == 1 {
|
||||||
s, err := store.New()
|
s, err := store.New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ctx = store.WithContextStore(ctx, s)
|
|
||||||
|
|
||||||
|
ctx = store.WithContextStore(ctx, s)
|
||||||
ctx = apicontext.WithCurrentContext(ctx, key[0])
|
ctx = apicontext.WithCurrentContext(ctx, key[0])
|
||||||
|
|
||||||
c, err := client.New(ctx)
|
c, err := client.New(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, err = proxy.WithClient(ctx, c)
|
ctx, err = proxy.WithClient(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m, err := handler(ctx, req)
|
|
||||||
return m, err
|
return handler(ctx, req)
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,15 @@ func main() {
|
|||||||
Expect(lines[1]).To(Equal("1234"))
|
Expect(lines[1]).To(Equal("1234"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("can run ps command with all ", func() {
|
||||||
|
output := NewDockerCommand("ps", "-q", "--all").ExecOrDie()
|
||||||
|
lines := Lines(output)
|
||||||
|
Expect(len(lines)).To(Equal(3))
|
||||||
|
Expect(lines[0]).To(Equal("id"))
|
||||||
|
Expect(lines[1]).To(Equal("1234"))
|
||||||
|
Expect(lines[2]).To(Equal("stopped"))
|
||||||
|
})
|
||||||
|
|
||||||
It("can run 'run' command", func() {
|
It("can run 'run' command", func() {
|
||||||
output := NewDockerCommand("run", "nginx", "-p", "80:80").ExecOrDie()
|
output := NewDockerCommand("run", "nginx", "-p", "80:80").ExecOrDie()
|
||||||
Expect(output).To(ContainSubstring("Running container \"nginx\" with name"))
|
Expect(output).To(ContainSubstring("Running container \"nginx\" with name"))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user