From 42f31d31293ba36d7576851482d7d688ee96a237 Mon Sep 17 00:00:00 2001 From: Chris Crone Date: Mon, 2 Nov 2020 16:28:18 +0100 Subject: [PATCH] backend.local: Improve inspect * Add restart policy * Add environment * Add labels * Add auto remove Signed-off-by: Chris Crone --- local/backend.go | 75 ++++++++++++++++++++++++++++++++++++++++--- local/backend_test.go | 70 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 local/backend_test.go diff --git a/local/backend.go b/local/backend.go index 8ce4d4d30..96c8f6749 100644 --- a/local/backend.go +++ b/local/backend.go @@ -21,7 +21,9 @@ package local import ( "bufio" "context" + "fmt" "io" + "sort" "strconv" "strings" "time" @@ -100,15 +102,78 @@ func (ms *local) Inspect(ctx context.Context, id string) (containers.Container, command = strings.Join(c.Config.Cmd, " ") } + rc := containerJSONToRuntimeConfig(&c) + hc := containerJSONToHostConfig(&c) + return containers.Container{ - ID: stringid.TruncateID(c.ID), - Status: status, - Image: c.Image, - Command: command, - Platform: c.Platform, + ID: stringid.TruncateID(c.ID), + Status: status, + Image: c.Image, + Command: command, + Platform: c.Platform, + Config: rc, + HostConfig: hc, }, nil } +func containerJSONToRuntimeConfig(m *types.ContainerJSON) *containers.RuntimeConfig { + if m.Config == nil { + return nil + } + var env map[string]string + if m.Config.Env != nil { + env = make(map[string]string) + for _, e := range m.Config.Env { + tokens := strings.Split(e, "=") + if len(tokens) != 2 { + continue + } + env[tokens[0]] = tokens[1] + } + } + + var labels []string + if m.Config.Labels != nil { + for k, v := range m.Config.Labels { + labels = append(labels, fmt.Sprintf("%s=%s", k, v)) + } + } + sort.Strings(labels) + + if env == nil && + labels == nil { + return nil + } + + return &containers.RuntimeConfig{ + Env: env, + Labels: labels, + } +} + +func containerJSONToHostConfig(m *types.ContainerJSON) *containers.HostConfig { + if m.HostConfig == nil { + return nil + } + + var restartPolicy string + switch m.HostConfig.RestartPolicy.Name { + case "always": + restartPolicy = containers.RestartPolicyAny + case "on-failure": + restartPolicy = containers.RestartPolicyOnFailure + case "no", "": + fallthrough + default: + restartPolicy = containers.RestartPolicyNone + } + + return &containers.HostConfig{ + AutoRemove: m.HostConfig.AutoRemove, + RestartPolicy: restartPolicy, + } +} + func (ms *local) List(ctx context.Context, all bool) ([]containers.Container, error) { css, err := ms.apiClient.ContainerList(ctx, types.ContainerListOptions{ All: all, diff --git a/local/backend_test.go b/local/backend_test.go new file mode 100644 index 000000000..02a1b6dfb --- /dev/null +++ b/local/backend_test.go @@ -0,0 +1,70 @@ +// +build local + +/* + Copyright 2020 Docker Compose CLI authors + + 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 local + +import ( + "testing" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "gotest.tools/v3/assert" + + "github.com/docker/compose-cli/api/containers" +) + +func TestToRuntimeConfig(t *testing.T) { + t.Parallel() + m := &types.ContainerJSON{ + Config: &container.Config{ + Env: []string{"FOO1=BAR1", "FOO2=BAR2"}, + Labels: map[string]string{"foo1": "bar1", "foo2": "bar2"}, + }, + } + rc := containerJSONToRuntimeConfig(m) + res := &containers.RuntimeConfig{ + Env: map[string]string{"FOO1": "BAR1", "FOO2": "BAR2"}, + Labels: []string{"foo1=bar1", "foo2=bar2"}, + } + assert.DeepEqual(t, rc, res) +} + +func TestToHostConfig(t *testing.T) { + t.Parallel() + base := &types.ContainerJSONBase{ + HostConfig: &container.HostConfig{ + AutoRemove: true, + RestartPolicy: container.RestartPolicy{ + Name: "", + }, + }, + } + m := &types.ContainerJSON{ + Config: &container.Config{ + Env: []string{"FOO1=BAR1", "FOO2=BAR2"}, + Labels: map[string]string{"foo1": "bar1", "foo2": "bar2"}, + }, + ContainerJSONBase: base, + } + hc := containerJSONToHostConfig(m) + res := &containers.HostConfig{ + AutoRemove: true, + RestartPolicy: containers.RestartPolicyNone, + } + assert.DeepEqual(t, hc, res) +}