Sfoglia il codice sorgente

Merge branch 'graph' of github.com:dotcloud/docker into graph

Guillaume J. Charmes 12 anni fa
parent
commit
c57727fd65
5 ha cambiato i file con 178 aggiunte e 189 eliminazioni
  1. 12 30
      commands.go
  2. 34 0
      container.go
  3. 100 120
      container_test.go
  4. 8 9
      runtime.go
  5. 24 30
      runtime_test.go

+ 12 - 30
commands.go

@@ -803,45 +803,27 @@ func (srv *Server) CmdTag(stdin io.ReadCloser, stdout io.Writer, args ...string)
 }
 }
 
 
 func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
 func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
-	cmd := rcli.Subcmd(stdout, "run", "[OPTIONS] IMAGE COMMAND [ARG...]", "Run a command in a new container")
-	fl_user := cmd.String("u", "", "Username or UID")
-	fl_detach := cmd.Bool("d", false, "Detached mode: leave the container running in the background")
-	fl_stdin := cmd.Bool("i", false, "Keep stdin open even if not attached")
-	fl_tty := cmd.Bool("t", false, "Allocate a pseudo-tty")
-	fl_memory := cmd.Int64("m", 0, "Memory limit (in bytes)")
-	var fl_ports ports
-
-	cmd.Var(&fl_ports, "p", "Map a network port to the container")
-	var fl_env ListOpts
-	cmd.Var(&fl_env, "e", "Set environment variables")
-	if err := cmd.Parse(args); err != nil {
-		return nil
+	config, err := ParseRun(args)
+	if err != nil {
+		return err
 	}
 	}
-	if cmd.NArg() < 2 {
-		cmd.Usage()
-		return nil
+	if config.Image == "" {
+		return fmt.Errorf("Image not specified")
+	}
+	if len(config.Cmd) == 0 {
+		return fmt.Errorf("Command not specified")
 	}
 	}
-	name := cmd.Arg(0)
-	cmdline := cmd.Args()[1:]
 	// Create new container
 	// Create new container
-	container, err := srv.runtime.Create(cmdline[0], cmdline[1:], name,
-		&Config{
-			Ports:     fl_ports,
-			User:      *fl_user,
-			Tty:       *fl_tty,
-			OpenStdin: *fl_stdin,
-			Memory:    *fl_memory,
-			Env:       fl_env,
-		})
+	container, err := srv.runtime.Create(config)
 	if err != nil {
 	if err != nil {
 		return errors.New("Error creating container: " + err.Error())
 		return errors.New("Error creating container: " + err.Error())
 	}
 	}
-	if *fl_stdin {
+	if config.OpenStdin {
 		cmd_stdin, err := container.StdinPipe()
 		cmd_stdin, err := container.StdinPipe()
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-		if !*fl_detach {
+		if !config.Detach {
 			Go(func() error {
 			Go(func() error {
 				_, err := io.Copy(cmd_stdin, stdin)
 				_, err := io.Copy(cmd_stdin, stdin)
 				cmd_stdin.Close()
 				cmd_stdin.Close()
@@ -850,7 +832,7 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string)
 		}
 		}
 	}
 	}
 	// Run the container
 	// Run the container
-	if !*fl_detach {
+	if !config.Detach {
 		cmd_stderr, err := container.StderrPipe()
 		cmd_stderr, err := container.StderrPipe()
 		if err != nil {
 		if err != nil {
 			return err
 			return err

+ 34 - 0
container.go

@@ -3,6 +3,7 @@ package docker
 import (
 import (
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
+	"flag"
 	"fmt"
 	"fmt"
 	"github.com/kr/pty"
 	"github.com/kr/pty"
 	"io"
 	"io"
@@ -50,10 +51,43 @@ type Config struct {
 	User       string
 	User       string
 	Memory     int64 // Memory limit (in bytes)
 	Memory     int64 // Memory limit (in bytes)
 	MemorySwap int64 // Total memory usage (memory + swap); set `-1' to disable swap
 	MemorySwap int64 // Total memory usage (memory + swap); set `-1' to disable swap
+	Detach     bool
 	Ports      []int
 	Ports      []int
 	Tty        bool // Attach standard streams to a tty, including stdin if it is not closed.
 	Tty        bool // Attach standard streams to a tty, including stdin if it is not closed.
 	OpenStdin  bool // Open stdin
 	OpenStdin  bool // Open stdin
 	Env        []string
 	Env        []string
+	Cmd        []string
+	Image      string // Name of the image as it was passed by the operator (eg. could be symbolic)
+}
+
+func ParseRun(args []string) (*Config, error) {
+	cmd := flag.NewFlagSet("", flag.ContinueOnError)
+	cmd.SetOutput(ioutil.Discard)
+	fl_user := cmd.String("u", "", "Username or UID")
+	fl_detach := cmd.Bool("d", false, "Detached mode: leave the container running in the background")
+	fl_stdin := cmd.Bool("i", false, "Keep stdin open even if not attached")
+	fl_tty := cmd.Bool("t", false, "Allocate a pseudo-tty")
+	fl_memory := cmd.Int64("m", 0, "Memory limit (in bytes)")
+	var fl_ports ports
+
+	cmd.Var(&fl_ports, "p", "Map a network port to the container")
+	var fl_env ListOpts
+	cmd.Var(&fl_env, "e", "Set environment variables")
+	if err := cmd.Parse(args); err != nil {
+		return nil, err
+	}
+	config := &Config{
+		Ports:     fl_ports,
+		User:      *fl_user,
+		Tty:       *fl_tty,
+		OpenStdin: *fl_stdin,
+		Memory:    *fl_memory,
+		Detach:    *fl_detach,
+		Env:       fl_env,
+		Cmd:       cmd.Args()[1:],
+		Image:     cmd.Arg(0),
+	}
+	return config, nil
 }
 }
 
 
 type NetworkSettings struct {
 type NetworkSettings struct {

+ 100 - 120
container_test.go

@@ -20,10 +20,9 @@ func TestCommitRun(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container1, err := runtime.Create(
 	container1, err := runtime.Create(
-		"/bin/sh",
-		[]string{"-c", "echo hello > /world"},
-		GetTestImage(runtime).Id,
 		&Config{
 		&Config{
+			Image:  GetTestImage(runtime).Id,
+			Cmd:    []string{"/bin/sh", "-c", "echo hello > /world"},
 			Memory: 33554432,
 			Memory: 33554432,
 		},
 		},
 	)
 	)
@@ -54,11 +53,10 @@ func TestCommitRun(t *testing.T) {
 	// FIXME: Make a TestCommit that stops here and check docker.root/layers/img.id/world
 	// FIXME: Make a TestCommit that stops here and check docker.root/layers/img.id/world
 
 
 	container2, err := runtime.Create(
 	container2, err := runtime.Create(
-		"cat",
-		[]string{"/world"},
-		img.Id,
 		&Config{
 		&Config{
+			Image:  img.Id,
 			Memory: 33554432,
 			Memory: 33554432,
+			Cmd:    []string{"cat", "/world"},
 		},
 		},
 	)
 	)
 	if err != nil {
 	if err != nil {
@@ -88,11 +86,10 @@ func TestRun(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := runtime.Create(
 	container, err := runtime.Create(
-		"ls",
-		[]string{"-al"},
-		GetTestImage(runtime).Id,
 		&Config{
 		&Config{
+			Image:  GetTestImage(runtime).Id,
 			Memory: 33554432,
 			Memory: 33554432,
+			Cmd:    []string{"ls", "-al"},
 		},
 		},
 	)
 	)
 	if err != nil {
 	if err != nil {
@@ -118,10 +115,10 @@ func TestOutput(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := runtime.Create(
 	container, err := runtime.Create(
-		"echo",
-		[]string{"-n", "foobar"},
-		GetTestImage(runtime).Id,
-		&Config{},
+		&Config{
+			Image: GetTestImage(runtime).Id,
+			Cmd:   []string{"echo", "-n", "foobar"},
+		},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -142,11 +139,10 @@ func TestKill(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
-	container, err := runtime.Create(
-		"cat",
-		[]string{"/dev/zero"},
-		GetTestImage(runtime).Id,
-		&Config{},
+	container, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"cat", "/dev/zero"},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -185,11 +181,11 @@ func TestExitCode(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 
 
-	trueContainer, err := runtime.Create(
-		"/bin/true",
-		[]string{""},
-		GetTestImage(runtime).Id,
-		&Config{},
+	trueContainer, err := runtime.Create(&Config{
+
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"/bin/true", ""},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -199,11 +195,10 @@ func TestExitCode(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	falseContainer, err := runtime.Create(
-		"/bin/false",
-		[]string{""},
-		GetTestImage(runtime).Id,
-		&Config{},
+	falseContainer, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"/bin/false", ""},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -228,11 +223,10 @@ func TestRestart(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
-	container, err := runtime.Create(
-		"echo",
-		[]string{"-n", "foobar"},
-		GetTestImage(runtime).Id,
-		&Config{},
+	container, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"echo", "-n", "foobar"},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -262,13 +256,12 @@ func TestRestartStdin(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
-	container, err := runtime.Create(
-		"cat",
-		[]string{},
-		GetTestImage(runtime).Id,
-		&Config{
-			OpenStdin: true,
-		},
+	container, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"cat"},
+
+		OpenStdin: true,
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -313,11 +306,10 @@ func TestUser(t *testing.T) {
 	defer nuke(runtime)
 	defer nuke(runtime)
 
 
 	// Default user must be root
 	// Default user must be root
-	container, err := runtime.Create(
-		"id",
-		[]string{},
-		GetTestImage(runtime).Id,
-		&Config{},
+	container, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"id"},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -332,13 +324,12 @@ func TestUser(t *testing.T) {
 	}
 	}
 
 
 	// Set a username
 	// Set a username
-	container, err = runtime.Create(
-		"id",
-		[]string{},
-		GetTestImage(runtime).Id,
-		&Config{
-			User: "root",
-		},
+	container, err = runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"id"},
+
+		User: "root",
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -353,13 +344,12 @@ func TestUser(t *testing.T) {
 	}
 	}
 
 
 	// Set a UID
 	// Set a UID
-	container, err = runtime.Create(
-		"id",
-		[]string{},
-		GetTestImage(runtime).Id,
-		&Config{
-			User: "0",
-		},
+	container, err = runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"id"},
+
+		User: "0",
+	},
 	)
 	)
 	if err != nil || container.State.ExitCode != 0 {
 	if err != nil || container.State.ExitCode != 0 {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -374,13 +364,12 @@ func TestUser(t *testing.T) {
 	}
 	}
 
 
 	// Set a different user by uid
 	// Set a different user by uid
-	container, err = runtime.Create(
-		"id",
-		[]string{},
-		GetTestImage(runtime).Id,
-		&Config{
-			User: "1",
-		},
+	container, err = runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"id"},
+
+		User: "1",
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -397,13 +386,12 @@ func TestUser(t *testing.T) {
 	}
 	}
 
 
 	// Set a different user by username
 	// Set a different user by username
-	container, err = runtime.Create(
-		"id",
-		[]string{},
-		GetTestImage(runtime).Id,
-		&Config{
-			User: "daemon",
-		},
+	container, err = runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"id"},
+
+		User: "daemon",
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -425,22 +413,20 @@ func TestMultipleContainers(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 
 
-	container1, err := runtime.Create(
-		"cat",
-		[]string{"/dev/zero"},
-		GetTestImage(runtime).Id,
-		&Config{},
+	container1, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"cat", "/dev/zero"},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	defer runtime.Destroy(container1)
 	defer runtime.Destroy(container1)
 
 
-	container2, err := runtime.Create(
-		"cat",
-		[]string{"/dev/zero"},
-		GetTestImage(runtime).Id,
-		&Config{},
+	container2, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"cat", "/dev/zero"},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -479,13 +465,12 @@ func TestStdin(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
-	container, err := runtime.Create(
-		"cat",
-		[]string{},
-		GetTestImage(runtime).Id,
-		&Config{
-			OpenStdin: true,
-		},
+	container, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"cat"},
+
+		OpenStdin: true,
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -514,13 +499,12 @@ func TestTty(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
-	container, err := runtime.Create(
-		"cat",
-		[]string{},
-		GetTestImage(runtime).Id,
-		&Config{
-			OpenStdin: true,
-		},
+	container, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"cat"},
+
+		OpenStdin: true,
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -549,11 +533,10 @@ func TestEnv(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
-	container, err := runtime.Create(
-		"/usr/bin/env",
-		[]string{},
-		GetTestImage(runtime).Id,
-		&Config{},
+	container, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"/usr/bin/env"},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -623,14 +606,13 @@ func TestLXCConfig(t *testing.T) {
 	memMin := 33554432
 	memMin := 33554432
 	memMax := 536870912
 	memMax := 536870912
 	mem := memMin + rand.Intn(memMax-memMin)
 	mem := memMin + rand.Intn(memMax-memMin)
-	container, err := runtime.Create(
-		"/bin/true",
-		[]string{},
-		GetTestImage(runtime).Id,
-		&Config{
-			Hostname: "foobar",
-			Memory:   int64(mem),
-		},
+	container, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"/bin/true"},
+
+		Hostname: "foobar",
+		Memory:   int64(mem),
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -651,11 +633,10 @@ func BenchmarkRunSequencial(b *testing.B) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 	for i := 0; i < b.N; i++ {
 	for i := 0; i < b.N; i++ {
-		container, err := runtime.Create(
-			"echo",
-			[]string{"-n", "foo"},
-			GetTestImage(runtime).Id,
-			&Config{},
+		container, err := runtime.Create(&Config{
+			Image: GetTestImage(runtime).Id,
+			Cmd:   []string{"echo", "-n", "foo"},
+		},
 		)
 		)
 		if err != nil {
 		if err != nil {
 			b.Fatal(err)
 			b.Fatal(err)
@@ -687,11 +668,10 @@ func BenchmarkRunParallel(b *testing.B) {
 		complete := make(chan error)
 		complete := make(chan error)
 		tasks = append(tasks, complete)
 		tasks = append(tasks, complete)
 		go func(i int, complete chan error) {
 		go func(i int, complete chan error) {
-			container, err := runtime.Create(
-				"echo",
-				[]string{"-n", "foo"},
-				GetTestImage(runtime).Id,
-				&Config{},
+			container, err := runtime.Create(&Config{
+				Image: GetTestImage(runtime).Id,
+				Cmd:   []string{"echo", "-n", "foo"},
+			},
 			)
 			)
 			if err != nil {
 			if err != nil {
 				complete <- err
 				complete <- err

+ 8 - 9
runtime.go

@@ -64,21 +64,20 @@ func (runtime *Runtime) containerRoot(id string) string {
 	return path.Join(runtime.repository, id)
 	return path.Join(runtime.repository, id)
 }
 }
 
 
-func (runtime *Runtime) Create(command string, args []string, image string, config *Config) (*Container, error) {
+func (runtime *Runtime) Create(config *Config) (*Container, error) {
 	// Lookup image
 	// Lookup image
-	img, err := runtime.repositories.LookupImage(image)
+	img, err := runtime.repositories.LookupImage(config.Image)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 	container := &Container{
 	container := &Container{
 		// FIXME: we should generate the ID here instead of receiving it as an argument
 		// FIXME: we should generate the ID here instead of receiving it as an argument
-		Id:      GenerateId(),
-		Created: time.Now(),
-		Path:    command,
-		Args:    args,
-		Config:  config,
-		Image:   img.Id, // Always use the resolved image id
-		//FIXME: store the name under which the image was given, for reference
+		Id:              GenerateId(),
+		Created:         time.Now(),
+		Path:            config.Cmd[0],
+		Args:            config.Cmd[1:], //FIXME: de-duplicate from config
+		Config:          config,
+		Image:           img.Id, // Always use the resolved image id
 		NetworkSettings: &NetworkSettings{},
 		NetworkSettings: &NetworkSettings{},
 		// FIXME: do we need to store this in the container?
 		// FIXME: do we need to store this in the container?
 		SysInitPath: sysInitPath,
 		SysInitPath: sysInitPath,

+ 24 - 30
runtime_test.go

@@ -112,11 +112,10 @@ func TestRuntimeCreate(t *testing.T) {
 	if len(runtime.List()) != 0 {
 	if len(runtime.List()) != 0 {
 		t.Errorf("Expected 0 containers, %v found", len(runtime.List()))
 		t.Errorf("Expected 0 containers, %v found", len(runtime.List()))
 	}
 	}
-	container, err := runtime.Create(
-		"ls",
-		[]string{"-al"},
-		GetTestImage(runtime).Id,
-		&Config{},
+	container, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"ls", "-al"},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -160,11 +159,10 @@ func TestDestroy(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
-	container, err := runtime.Create(
-		"ls",
-		[]string{"-al"},
-		GetTestImage(runtime).Id,
-		&Config{},
+	container, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"ls", "-al"},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -208,33 +206,30 @@ func TestGet(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
-	container1, err := runtime.Create(
-		"ls",
-		[]string{"-al"},
-		GetTestImage(runtime).Id,
-		&Config{},
+	container1, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"ls", "-al"},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	defer runtime.Destroy(container1)
 	defer runtime.Destroy(container1)
 
 
-	container2, err := runtime.Create(
-		"ls",
-		[]string{"-al"},
-		GetTestImage(runtime).Id,
-		&Config{},
+	container2, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"ls", "-al"},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	defer runtime.Destroy(container2)
 	defer runtime.Destroy(container2)
 
 
-	container3, err := runtime.Create(
-		"ls",
-		[]string{"-al"},
-		GetTestImage(runtime).Id,
-		&Config{},
+	container3, err := runtime.Create(&Config{
+		Image: GetTestImage(runtime).Id,
+		Cmd:   []string{"ls", "-al"},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -274,11 +269,10 @@ func TestRestore(t *testing.T) {
 	}
 	}
 
 
 	// Create a container with one instance of docker
 	// Create a container with one instance of docker
-	container1, err := runtime1.Create(
-		"ls",
-		[]string{"-al"},
-		GetTestImage(runtime1).Id,
-		&Config{},
+	container1, err := runtime1.Create(&Config{
+		Image: GetTestImage(runtime1).Id,
+		Cmd:   []string{"ls", "-al"},
+	},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)