mirror of
https://github.com/rancher/os.git
synced 2025-09-01 06:40:31 +00:00
Better rollback/restart/upgrade container
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
@@ -21,6 +22,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
LABEL = "label"
|
LABEL = "label"
|
||||||
HASH = "io.rancher.os.hash"
|
HASH = "io.rancher.os.hash"
|
||||||
|
ID = "io.rancher.os.id"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Container struct {
|
type Container struct {
|
||||||
@@ -31,10 +33,16 @@ type Container struct {
|
|||||||
Config *runconfig.Config
|
Config *runconfig.Config
|
||||||
HostConfig *runconfig.HostConfig
|
HostConfig *runconfig.HostConfig
|
||||||
dockerHost string
|
dockerHost string
|
||||||
container *dockerClient.Container
|
Container *dockerClient.Container
|
||||||
containerCfg *config.ContainerConfig
|
containerCfg *config.ContainerConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ByCreated []dockerClient.APIContainers
|
||||||
|
|
||||||
|
func (c ByCreated) Len() int { return len(c) }
|
||||||
|
func (c ByCreated) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
||||||
|
func (c ByCreated) Less(i, j int) bool { return c[j].Created < c[i].Created }
|
||||||
|
|
||||||
func getHash(containerCfg *config.ContainerConfig) (string, error) {
|
func getHash(containerCfg *config.ContainerConfig) (string, error) {
|
||||||
hash := sha1.New()
|
hash := sha1.New()
|
||||||
w := util.NewErrorWriter(hash)
|
w := util.NewErrorWriter(hash)
|
||||||
@@ -67,10 +75,30 @@ func (c *Container) returnErr(err error) *Container {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getByLabel(client *dockerClient.Client, key, value string) (*dockerClient.APIContainers, error) {
|
||||||
|
containers, err := client.ListContainers(dockerClient.ListContainersOptions{
|
||||||
|
All: true,
|
||||||
|
Filters: map[string][]string{
|
||||||
|
LABEL: []string{fmt.Sprintf("%s=%s", key, value)},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(containers) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(ByCreated(containers))
|
||||||
|
return &containers[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Container) Lookup() *Container {
|
func (c *Container) Lookup() *Container {
|
||||||
c.Parse()
|
c.Parse()
|
||||||
|
|
||||||
if c.Err != nil || (c.container != nil && c.container.HostConfig != nil) {
|
if c.Err != nil || (c.Container != nil && c.Container.HostConfig != nil) {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,20 +126,33 @@ func (c *Container) Lookup() *Container {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
c.container, c.Err = client.InspectContainer(containers[0].ID)
|
c.Container, c.Err = inspect(client, containers[0].ID)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func inspect(client *dockerClient.Client, id string) (*dockerClient.Container, error) {
|
||||||
|
c, err := client.InspectContainer(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(c.Name, "/") {
|
||||||
|
c.Name = c.Name[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Container) Exists() bool {
|
func (c *Container) Exists() bool {
|
||||||
c.Lookup()
|
c.Lookup()
|
||||||
return c.container != nil
|
return c.Container != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) Reset() *Container {
|
func (c *Container) Reset() *Container {
|
||||||
c.Config = nil
|
c.Config = nil
|
||||||
c.HostConfig = nil
|
c.HostConfig = nil
|
||||||
c.container = nil
|
c.Container = nil
|
||||||
c.Err = nil
|
c.Err = nil
|
||||||
|
|
||||||
return c
|
return c
|
||||||
@@ -200,7 +241,7 @@ func (c *Container) Delete() *Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = client.RemoveContainer(dockerClient.RemoveContainerOptions{
|
err = client.RemoveContainer(dockerClient.RemoveContainerOptions{
|
||||||
ID: c.container.ID,
|
ID: c.Container.ID,
|
||||||
Force: true,
|
Force: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -210,27 +251,112 @@ func (c *Container) Delete() *Container {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func renameOld(client *dockerClient.Client, opts *dockerClient.CreateContainerOptions) error {
|
func (c *Container) renameCurrent(client *dockerClient.Client) error {
|
||||||
|
if c.Name == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Name == c.Container.Name {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := client.RenameContainer(c.Container.ID, c.Name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Container, err = inspect(client, c.Container.ID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Container) renameOld(client *dockerClient.Client, opts *dockerClient.CreateContainerOptions) error {
|
||||||
if len(opts.Name) == 0 {
|
if len(opts.Name) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
existing, err := client.InspectContainer(opts.Name)
|
existing, err := inspect(client, opts.Name)
|
||||||
if _, ok := err.(dockerClient.NoSuchContainer); ok {
|
if _, ok := err.(dockerClient.NoSuchContainer); ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.Container != nil && existing.ID == c.Container.ID {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if label, ok := existing.Config.Labels[HASH]; ok {
|
if label, ok := existing.Config.Labels[HASH]; ok {
|
||||||
return client.RenameContainer(existing.ID, fmt.Sprintf("%s-%s", existing.Name, label))
|
newName := fmt.Sprintf("%s-%s", existing.Name, label)
|
||||||
|
|
||||||
|
if existing.State.Running {
|
||||||
|
err := client.StopContainer(existing.ID, 2)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = client.WaitContainer(existing.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Renaming %s to %s", existing.Name, newName)
|
||||||
|
return client.RenameContainer(existing.ID, newName)
|
||||||
} else {
|
} else {
|
||||||
//TODO: do something with containers with no hash
|
//TODO: do something with containers with no hash
|
||||||
return errors.New("Existing container doesn't have a hash")
|
return errors.New("Existing container doesn't have a hash")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Container) getCreateOpts(client *dockerClient.Client) (*dockerClient.CreateContainerOptions, error) {
|
||||||
|
bytes, err := json.Marshal(c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var opts dockerClient.CreateContainerOptions
|
||||||
|
|
||||||
|
err = json.Unmarshal(bytes, &opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.Config.Labels == nil {
|
||||||
|
opts.Config.Labels = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, err := getHash(c.containerCfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.Config.Labels[HASH] = hash
|
||||||
|
opts.Config.Labels[ID] = c.containerCfg.Id
|
||||||
|
|
||||||
|
return &opts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendVolumesFrom(client *dockerClient.Client, containerCfg *config.ContainerConfig, opts *dockerClient.CreateContainerOptions) error {
|
||||||
|
if !containerCfg.MigrateVolumes {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
container, err := getByLabel(client, ID, containerCfg.Id)
|
||||||
|
if err != nil || container == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.HostConfig.VolumesFrom == nil {
|
||||||
|
opts.HostConfig.VolumesFrom = []string{container.ID}
|
||||||
|
} else {
|
||||||
|
opts.HostConfig.VolumesFrom = append(opts.HostConfig.VolumesFrom, container.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Container) start(wait bool) *Container {
|
func (c *Container) start(wait bool) *Container {
|
||||||
c.Lookup()
|
c.Lookup()
|
||||||
c.Stage()
|
c.Stage()
|
||||||
@@ -239,63 +365,74 @@ func (c *Container) start(wait bool) *Container {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes, err := json.Marshal(c)
|
|
||||||
if err != nil {
|
|
||||||
return c.returnErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := NewClient(c.dockerHost)
|
client, err := NewClient(c.dockerHost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.returnErr(err)
|
return c.returnErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var opts dockerClient.CreateContainerOptions
|
container := c.Container
|
||||||
container := c.container
|
|
||||||
created := false
|
created := false
|
||||||
|
|
||||||
if !c.Exists() {
|
opts, err := c.getCreateOpts(client)
|
||||||
c.Err = json.Unmarshal(bytes, &opts)
|
if err != nil {
|
||||||
|
return c.returnErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Exists() && c.remove {
|
||||||
|
log.Debugf("Deleting container %s", c.Container.ID)
|
||||||
|
c.Delete().Reset().Lookup()
|
||||||
|
|
||||||
if c.Err != nil {
|
if c.Err != nil {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if opts.Config.Labels == nil {
|
if !c.Exists() {
|
||||||
opts.Config.Labels = make(map[string]string)
|
err = c.renameOld(client, opts)
|
||||||
}
|
|
||||||
|
|
||||||
hash, err := getHash(c.containerCfg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.returnErr(err)
|
return c.returnErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.Config.Labels[HASH] = hash
|
err := appendVolumesFrom(client, c.containerCfg, opts)
|
||||||
|
|
||||||
err = renameOld(client, &opts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.returnErr(err)
|
return c.returnErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
container, err = client.CreateContainer(opts)
|
container, err = client.CreateContainer(*opts)
|
||||||
created = true
|
created = true
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.returnErr(err)
|
return c.returnErr(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.container = container
|
c.Container = container
|
||||||
|
|
||||||
hostConfig := container.HostConfig
|
hostConfig := c.Container.HostConfig
|
||||||
if created {
|
if created {
|
||||||
hostConfig = opts.HostConfig
|
hostConfig = opts.HostConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
err = client.StartContainer(container.ID, hostConfig)
|
if !c.Container.State.Running {
|
||||||
if err != nil {
|
if !created {
|
||||||
return c.returnErr(err)
|
err = c.renameOld(client, opts)
|
||||||
|
if err != nil {
|
||||||
|
return c.returnErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.renameCurrent(client)
|
||||||
|
if err != nil {
|
||||||
|
return c.returnErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.StartContainer(c.Container.ID, hostConfig)
|
||||||
|
if err != nil {
|
||||||
|
return c.returnErr(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.detach && wait {
|
if !c.detach && wait {
|
||||||
_, c.Err = client.WaitContainer(container.ID)
|
_, c.Err = client.WaitContainer(c.Container.ID)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,10 +1,13 @@
|
|||||||
package docker
|
package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/rancherio/os/config"
|
"github.com/rancherio/os/config"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
dockerClient "github.com/fsouza/go-dockerclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHash(t *testing.T) {
|
func TestHash(t *testing.T) {
|
||||||
@@ -12,23 +15,23 @@ func TestHash(t *testing.T) {
|
|||||||
|
|
||||||
hash, err := getHash(&config.ContainerConfig{
|
hash, err := getHash(&config.ContainerConfig{
|
||||||
Id: "id",
|
Id: "id",
|
||||||
Cmd: []string{"1", "2", "3"},
|
Cmd: "1 2 3",
|
||||||
})
|
})
|
||||||
assert.NoError(err, "")
|
assert.NoError(err, "")
|
||||||
|
|
||||||
hash2, err := getHash(&config.ContainerConfig{
|
hash2, err := getHash(&config.ContainerConfig{
|
||||||
Id: "id2",
|
Id: "id2",
|
||||||
Cmd: []string{"1", "2", "3"},
|
Cmd: "1 2 3",
|
||||||
})
|
})
|
||||||
assert.NoError(err, "")
|
assert.NoError(err, "")
|
||||||
|
|
||||||
hash3, err := getHash(&config.ContainerConfig{
|
hash3, err := getHash(&config.ContainerConfig{
|
||||||
Id: "id3",
|
Id: "id3",
|
||||||
Cmd: []string{"1", "2", "3", "4"},
|
Cmd: "1 2 3 4",
|
||||||
})
|
})
|
||||||
assert.NoError(err, "")
|
assert.NoError(err, "")
|
||||||
|
|
||||||
assert.Equal("44096e94ed438ccda24e459412147441a376ea1c", hash, "")
|
assert.Equal("510b68938cba936876588b0143093a5850d4a142", hash, "")
|
||||||
assert.NotEqual(hash, hash2, "")
|
assert.NotEqual(hash, hash2, "")
|
||||||
assert.NotEqual(hash2, hash3, "")
|
assert.NotEqual(hash2, hash3, "")
|
||||||
assert.NotEqual(hash, hash3, "")
|
assert.NotEqual(hash, hash3, "")
|
||||||
@@ -38,18 +41,16 @@ func TestParse(t *testing.T) {
|
|||||||
assert := require.New(t)
|
assert := require.New(t)
|
||||||
|
|
||||||
cfg := &config.ContainerConfig{
|
cfg := &config.ContainerConfig{
|
||||||
Cmd: []string{
|
Cmd: "--name c1 " +
|
||||||
"--name", "c1",
|
"-d " +
|
||||||
"-d",
|
"--rm " +
|
||||||
"--rm",
|
"--privileged " +
|
||||||
"--privileged",
|
"test/image " +
|
||||||
"test/image",
|
"arg1 " +
|
||||||
"arg1",
|
"arg2 ",
|
||||||
"arg2",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c := NewContainer(nil, cfg).Parse()
|
c := NewContainer("", cfg).Parse()
|
||||||
|
|
||||||
assert.NoError(c.Err, "")
|
assert.NoError(c.Err, "")
|
||||||
assert.Equal(cfg.Id, "c1", "Id doesn't match")
|
assert.Equal(cfg.Id, "c1", "Id doesn't match")
|
||||||
@@ -62,18 +63,93 @@ func TestParse(t *testing.T) {
|
|||||||
assert.True(c.HostConfig.Privileged, "Privileged doesn't match")
|
assert.True(c.HostConfig.Privileged, "Privileged doesn't match")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIdFromName(t *testing.T) {
|
||||||
|
assert := require.New(t)
|
||||||
|
|
||||||
|
cfg := &config.ContainerConfig{
|
||||||
|
Cmd: "--name foo -v /test busybox echo hi",
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal("", cfg.Id)
|
||||||
|
NewContainer(config.DOCKER_HOST, cfg)
|
||||||
|
assert.Equal("foo", cfg.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMigrateVolumes(t *testing.T) {
|
||||||
|
assert := require.New(t)
|
||||||
|
|
||||||
|
c := NewContainer(config.DOCKER_HOST, &config.ContainerConfig{
|
||||||
|
Cmd: "--name foo -v /test busybox echo hi",
|
||||||
|
}).Parse().Start().Lookup()
|
||||||
|
|
||||||
|
assert.NoError(c.Err, "")
|
||||||
|
|
||||||
|
test_path, ok := c.Container.Volumes["/test"]
|
||||||
|
assert.True(ok, "")
|
||||||
|
|
||||||
|
c2 := NewContainer(config.DOCKER_HOST, &config.ContainerConfig{
|
||||||
|
MigrateVolumes: true,
|
||||||
|
Cmd: "--name foo -v /test2 busybox echo hi",
|
||||||
|
}).Parse().Start().Lookup()
|
||||||
|
|
||||||
|
assert.NoError(c2.Err, "")
|
||||||
|
|
||||||
|
assert.True(c2.Container != nil)
|
||||||
|
|
||||||
|
_, ok = c2.Container.Volumes["/test2"]
|
||||||
|
assert.True(ok, "")
|
||||||
|
assert.Equal(test_path, c2.Container.Volumes["/test"])
|
||||||
|
|
||||||
|
c.Delete()
|
||||||
|
c2.Delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRollback(t *testing.T) {
|
||||||
|
assert := require.New(t)
|
||||||
|
|
||||||
|
c := NewContainer(config.DOCKER_HOST, &config.ContainerConfig{
|
||||||
|
Cmd: "--name rollback busybox echo hi",
|
||||||
|
}).Parse().Start().Lookup()
|
||||||
|
|
||||||
|
assert.NoError(c.Err, "")
|
||||||
|
assert.Equal("rollback", c.Container.Name)
|
||||||
|
|
||||||
|
c2 := NewContainer(config.DOCKER_HOST, &config.ContainerConfig{
|
||||||
|
Cmd: "--name rollback busybox echo bye",
|
||||||
|
}).Parse().Start().Lookup()
|
||||||
|
|
||||||
|
assert.Equal("rollback", c2.Container.Name)
|
||||||
|
assert.NoError(c2.Err, "")
|
||||||
|
assert.NotEqual(c.Container.ID, c2.Container.ID)
|
||||||
|
|
||||||
|
c3 := NewContainer(config.DOCKER_HOST, &config.ContainerConfig{
|
||||||
|
Cmd: "--name rollback busybox echo hi",
|
||||||
|
}).Parse().Start().Lookup()
|
||||||
|
|
||||||
|
assert.NoError(c3.Err, "")
|
||||||
|
assert.Equal(c.Container.ID, c3.Container.ID)
|
||||||
|
assert.Equal("rollback", c3.Container.Name)
|
||||||
|
|
||||||
|
c2.Reset().Lookup()
|
||||||
|
assert.NoError(c2.Err, "")
|
||||||
|
assert.True(strings.HasPrefix(c2.Container.Name, "rollback-"))
|
||||||
|
|
||||||
|
c.Delete()
|
||||||
|
c2.Delete()
|
||||||
|
}
|
||||||
|
|
||||||
func TestStart(t *testing.T) {
|
func TestStart(t *testing.T) {
|
||||||
assert := require.New(t)
|
assert := require.New(t)
|
||||||
|
|
||||||
c := NewContainer(nil, &config.ContainerConfig{
|
c := NewContainer(config.DOCKER_HOST, &config.ContainerConfig{
|
||||||
Cmd: []string{"--pid=host", "--privileged", "--rm", "busybox", "echo", "hi"},
|
Cmd: "--pid=host --privileged --rm busybox echo hi",
|
||||||
}).Parse().Start().Lookup()
|
}).Parse().Start().Lookup()
|
||||||
|
|
||||||
assert.NoError(c.Err, "")
|
assert.NoError(c.Err, "")
|
||||||
|
|
||||||
assert.True(c.HostConfig.Privileged, "")
|
assert.True(c.HostConfig.Privileged, "")
|
||||||
assert.True(c.container.HostConfig.Privileged, "")
|
assert.True(c.Container.HostConfig.Privileged, "")
|
||||||
assert.Equal("host", c.container.HostConfig.PidMode, "")
|
assert.Equal("host", c.Container.HostConfig.PidMode, "")
|
||||||
|
|
||||||
c.Delete()
|
c.Delete()
|
||||||
}
|
}
|
||||||
@@ -82,26 +158,26 @@ func TestLookup(t *testing.T) {
|
|||||||
assert := require.New(t)
|
assert := require.New(t)
|
||||||
|
|
||||||
cfg := &config.ContainerConfig{
|
cfg := &config.ContainerConfig{
|
||||||
Cmd: []string{"--rm", "busybox", "echo", "hi"},
|
Cmd: "--rm busybox echo hi",
|
||||||
}
|
}
|
||||||
c := NewContainer(nil, cfg).Parse().Start()
|
c := NewContainer(config.DOCKER_HOST, cfg).Parse().Start()
|
||||||
|
|
||||||
cfg2 := &config.ContainerConfig{
|
cfg2 := &config.ContainerConfig{
|
||||||
Cmd: []string{"--rm", "busybox", "echo", "hi2"},
|
Cmd: "--rm busybox echo hi2",
|
||||||
}
|
}
|
||||||
c2 := NewContainer(nil, cfg2).Parse().Start()
|
c2 := NewContainer(config.DOCKER_HOST, cfg2).Parse().Start()
|
||||||
|
|
||||||
assert.NoError(c.Err, "")
|
assert.NoError(c.Err, "")
|
||||||
assert.NoError(c2.Err, "")
|
assert.NoError(c2.Err, "")
|
||||||
|
|
||||||
c1Lookup := NewContainer(nil, cfg).Lookup()
|
c1Lookup := NewContainer(config.DOCKER_HOST, cfg).Lookup()
|
||||||
c2Lookup := NewContainer(nil, cfg2).Lookup()
|
c2Lookup := NewContainer(config.DOCKER_HOST, cfg2).Lookup()
|
||||||
|
|
||||||
assert.NoError(c1Lookup.Err, "")
|
assert.NoError(c1Lookup.Err, "")
|
||||||
assert.NoError(c2Lookup.Err, "")
|
assert.NoError(c2Lookup.Err, "")
|
||||||
|
|
||||||
assert.Equal(c.container.ID, c1Lookup.container.ID, "")
|
assert.Equal(c.Container.ID, c1Lookup.Container.ID, "")
|
||||||
assert.Equal(c2.container.ID, c2Lookup.container.ID, "")
|
assert.Equal(c2.Container.ID, c2Lookup.Container.ID, "")
|
||||||
|
|
||||||
c.Delete()
|
c.Delete()
|
||||||
c2.Delete()
|
c2.Delete()
|
||||||
@@ -110,8 +186,8 @@ func TestLookup(t *testing.T) {
|
|||||||
func TestDelete(t *testing.T) {
|
func TestDelete(t *testing.T) {
|
||||||
assert := require.New(t)
|
assert := require.New(t)
|
||||||
|
|
||||||
c := NewContainer(nil, &config.ContainerConfig{
|
c := NewContainer(config.DOCKER_HOST, &config.ContainerConfig{
|
||||||
Cmd: []string{"--rm", "busybox", "echo", "hi"},
|
Cmd: "--rm busybox echo hi",
|
||||||
}).Parse()
|
}).Parse()
|
||||||
|
|
||||||
assert.False(c.Exists())
|
assert.False(c.Exists())
|
||||||
@@ -132,3 +208,35 @@ func TestDelete(t *testing.T) {
|
|||||||
assert.False(c.Exists())
|
assert.False(c.Exists())
|
||||||
assert.NoError(c.Err, "")
|
assert.NoError(c.Err, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDockerClientNames(t *testing.T) {
|
||||||
|
assert := require.New(t)
|
||||||
|
client, err := dockerClient.NewClient(config.DOCKER_HOST)
|
||||||
|
|
||||||
|
assert.NoError(err, "")
|
||||||
|
|
||||||
|
c, err := client.CreateContainer(dockerClient.CreateContainerOptions{
|
||||||
|
Name: "foo",
|
||||||
|
Config: &dockerClient.Config{
|
||||||
|
Image: "ubuntu",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.NoError(err, "")
|
||||||
|
assert.Equal("foo", c.Name)
|
||||||
|
|
||||||
|
c2, err := client.InspectContainer(c.ID)
|
||||||
|
|
||||||
|
assert.NoError(err, "")
|
||||||
|
assert.Equal("/foo", c2.Name)
|
||||||
|
|
||||||
|
c2, err = inspect(client, c.ID)
|
||||||
|
|
||||||
|
assert.NoError(err, "")
|
||||||
|
assert.Equal("foo", c2.Name)
|
||||||
|
|
||||||
|
client.RemoveContainer(dockerClient.RemoveContainerOptions{
|
||||||
|
ID: c2.ID,
|
||||||
|
Force: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user