Merge pull request #148 from rumpl/feat-moby-ports

Add ports to the moby backend
This commit is contained in:
Chris Crone 2020-05-25 11:25:51 +02:00 коммит произвёл GitHub
Родитель 7b83047dc2 1c3673c421
Коммит 5768ffd526
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 134 добавлений и 9 удалений

Просмотреть файл

@ -44,7 +44,7 @@ cli: ## Compile the cli
--target cli
e2e-local: ## Run End to end local tests
go test -v ./tests/e2e
go test -v ./tests/e2e ./moby/e2e
e2e-aci: ## Run End to end ACI tests (requires azure login)
go test -v ./tests/aci-e2e

2
go.mod
Просмотреть файл

@ -17,7 +17,7 @@ require (
github.com/compose-spec/compose-go v0.0.0-20200423124427-63dcf8c22cae
github.com/containerd/console v1.0.0
github.com/containerd/containerd v1.3.4 // indirect
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/distribution v2.7.1+incompatible
github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible
github.com/docker/go-connections v0.4.0
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee // indirect

Просмотреть файл

@ -1,10 +1,14 @@
package moby
import (
"bufio"
"context"
"io"
"strconv"
"time"
"github.com/docker/go-connections/nat"
"github.com/docker/api/context/cloud"
"github.com/docker/docker/api/types"
@ -72,7 +76,7 @@ func (ms *mobyService) List(ctx context.Context, all bool) ([]containers.Contain
// statuses. We also need to add a `Created` property on the gRPC side.
Status: container.Status,
Command: container.Command,
Ports: getPorts(container.Ports),
Ports: toPorts(container.Ports),
})
}
@ -80,15 +84,50 @@ func (ms *mobyService) List(ctx context.Context, all bool) ([]containers.Contain
}
func (ms *mobyService) Run(ctx context.Context, r containers.ContainerConfig) error {
create, err := ms.apiClient.ContainerCreate(ctx, &container.Config{
Image: r.Image,
Labels: r.Labels,
}, nil, nil, r.ID)
exposedPorts, hostBindings, err := fromPorts(r.Ports)
if err != nil {
return err
}
return ms.apiClient.ContainerStart(ctx, create.ID, types.ContainerStartOptions{})
containerConfig := &container.Config{
Image: r.Image,
Labels: r.Labels,
ExposedPorts: exposedPorts,
}
hostConfig := &container.HostConfig{
PortBindings: hostBindings,
}
created, err := ms.apiClient.ContainerCreate(ctx, containerConfig, hostConfig, nil, r.ID)
if err != nil {
if client.IsErrNotFound(err) {
io, err := ms.apiClient.ImagePull(ctx, r.Image, types.ImagePullOptions{})
if err != nil {
return err
}
scanner := bufio.NewScanner(io)
// Read the whole body, otherwise the pulling stops
for scanner.Scan() {
}
if err = scanner.Err(); err != nil {
return err
}
if err = io.Close(); err != nil {
return err
}
created, err = ms.apiClient.ContainerCreate(ctx, containerConfig, hostConfig, nil, r.ID)
if err != nil {
return err
}
} else {
return err
}
}
return ms.apiClient.ContainerStart(ctx, created.ID, types.ContainerStartOptions{})
}
func (ms *mobyService) Stop(ctx context.Context, containerID string, timeout *uint32) error {
@ -162,7 +201,7 @@ func (ms *mobyService) Delete(ctx context.Context, containerID string, force boo
return err
}
func getPorts(ports []types.Port) []containers.Port {
func toPorts(ports []types.Port) []containers.Port {
result := []containers.Port{}
for _, port := range ports {
result = append(result, containers.Port{
@ -175,3 +214,33 @@ func getPorts(ports []types.Port) []containers.Port {
return result
}
func fromPorts(ports []containers.Port) (map[nat.Port]struct{}, map[nat.Port][]nat.PortBinding, error) {
var (
exposedPorts = make(map[nat.Port]struct{}, len(ports))
bindings = make(map[nat.Port][]nat.PortBinding)
)
for _, port := range ports {
p, err := nat.NewPort(port.Protocol, strconv.Itoa(int(port.ContainerPort)))
if err != nil {
return nil, nil, err
}
if _, exists := exposedPorts[p]; !exists {
exposedPorts[p] = struct{}{}
}
portBinding := nat.PortBinding{
HostIP: port.HostIP,
HostPort: strconv.Itoa(int(port.HostPort)),
}
bslice, exists := bindings[p]
if !exists {
bslice = []nat.PortBinding{}
}
bindings[p] = append(bslice, portBinding)
}
return exposedPorts, bindings, nil
}

56
moby/e2e/backend_test.go Normal file
Просмотреть файл

@ -0,0 +1,56 @@
package e2e
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/docker/api/tests/framework"
)
type MobyBackendTestSuite struct {
framework.Suite
}
func (m *MobyBackendTestSuite) BeforeTest(suiteName string, testName string) {
m.NewDockerCommand("context", "create", "test-context", "moby").ExecOrDie()
m.NewDockerCommand("context", "use", "test-context").ExecOrDie()
}
func (m *MobyBackendTestSuite) AfterTest(suiteName string, testName string) {
m.NewDockerCommand("context", "rm", "test-context").ExecOrDie()
m.NewDockerCommand("context", "use", "default").ExecOrDie()
}
func (m *MobyBackendTestSuite) TestPs() {
out := m.NewDockerCommand("ps").ExecOrDie()
require.Equal(m.T(), "CONTAINER ID IMAGE COMMAND STATUS PORTS\n", out)
}
func (m *MobyBackendTestSuite) TestRun() {
_, err := m.NewDockerCommand("run", "--name", "nginx", "nginx").Exec()
require.Nil(m.T(), err)
out := m.NewDockerCommand("ps").ExecOrDie()
defer func() {
m.NewDockerCommand("rm", "-f", "nginx").ExecOrDie()
}()
lines := strings.Split(out, "\n")
assert.Equal(m.T(), 3, len(lines))
}
func (m *MobyBackendTestSuite) TestRunWithPorts() {
_, err := m.NewDockerCommand("run", "--name", "nginx", "-p", "8080:80", "nginx").Exec()
require.Nil(m.T(), err)
out := m.NewDockerCommand("ps").ExecOrDie()
defer func() {
m.NewDockerCommand("rm", "-f", "nginx").ExecOrDie()
}()
assert.Contains(m.T(), out, "8080")
}
func TestMobyBackendTestSuite(t *testing.T) {
suite.Run(t, new(MobyBackendTestSuite))
}