فهرست منبع

merge graph in graph

creack 12 سال پیش
والد
کامیت
eef9659c95
7فایلهای تغییر یافته به همراه63 افزوده شده و 33 حذف شده
  1. 9 20
      commands.go
  2. 1 1
      container_test.go
  3. 6 2
      graph.go
  4. 5 5
      graph_test.go
  5. 7 5
      image.go
  6. 27 0
      runtime.go
  7. 8 0
      tags.go

+ 9 - 20
commands.go

@@ -387,7 +387,7 @@ func (srv *Server) CmdImport(stdin io.ReadCloser, stdout io.Writer, args ...stri
 		}
 		archive = ProgressReader(resp.Body, int(resp.ContentLength), stdout)
 	}
-	img, err := srv.runtime.graph.Create(archive, "", "Imported from "+src)
+	img, err := srv.runtime.graph.Create(archive, nil, "Imported from "+src)
 	if err != nil {
 		return err
 	}
@@ -737,33 +737,22 @@ func (srv *Server) CmdPs(stdin io.ReadCloser, stdout io.Writer, args ...string)
 
 func (srv *Server) CmdCommit(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
 	cmd := rcli.Subcmd(stdout,
-		"commit", "[OPTIONS] CONTAINER [DEST]",
+		"commit", "[OPTIONS] CONTAINER [REPOSITORY [TAG]]",
 		"Create a new image from a container's changes")
 	if err := cmd.Parse(args); err != nil {
 		return nil
 	}
-	containerName, imgName := cmd.Arg(0), cmd.Arg(1)
-	if containerName == "" || imgName == "" {
+	containerName, repository, tag := cmd.Arg(0), cmd.Arg(1), cmd.Arg(2)
+	if containerName == "" {
 		cmd.Usage()
 		return nil
 	}
-	if container := srv.runtime.Get(containerName); container != nil {
-		// FIXME: freeze the container before copying it to avoid data corruption?
-		// FIXME: this shouldn't be in commands.
-		rwTar, err := container.ExportRw()
-		if err != nil {
-			return err
-		}
-		// Create a new image from the container's base layers + a new layer from container changes
-		img, err := srv.runtime.graph.Create(rwTar, container.Image, "")
-		if err != nil {
-			return err
-		}
-
-		fmt.Fprintln(stdout, img.Id)
-		return nil
+	img, err := srv.runtime.Commit(containerName, repository, tag)
+	if err != nil {
+		return err
 	}
-	return errors.New("No such container: " + containerName)
+	fmt.Fprintln(stdout, img.Id)
+	return nil
 }
 
 func (srv *Server) CmdExport(stdin io.ReadCloser, stdout io.Writer, args ...string) error {

+ 1 - 1
container_test.go

@@ -46,7 +46,7 @@ func TestCommitRun(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-	img, err := runtime.graph.Create(rwTar, container1.Image, "unit test commited image")
+	img, err := runtime.graph.Create(rwTar, container1, "unit test commited image")
 	if err != nil {
 		t.Error(err)
 	}

+ 6 - 2
graph.go

@@ -47,13 +47,17 @@ func (graph *Graph) Get(id string) (*Image, error) {
 	return img, nil
 }
 
-func (graph *Graph) Create(layerData Archive, parent, comment string) (*Image, error) {
+func (graph *Graph) Create(layerData Archive, container *Container, comment string) (*Image, error) {
 	img := &Image{
 		Id:      GenerateId(),
-		Parent:  parent,
 		Comment: comment,
 		Created: time.Now(),
 	}
+	if container != nil {
+		img.Parent = container.Image
+		img.ParentContainer = container.Id
+		img.ParentCommand = append([]string{container.Path}, container.Args...)
+	}
 	if err := graph.Register(layerData, img); err != nil {
 		return nil, err
 	}

+ 5 - 5
graph_test.go

@@ -35,7 +35,7 @@ func TestGraphCreate(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	image, err := graph.Create(archive, "", "Testing")
+	image, err := graph.Create(archive, nil, "Testing")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -92,7 +92,7 @@ func TestMount(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	image, err := graph.Create(archive, "", "Testing")
+	image, err := graph.Create(archive, nil, "Testing")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -128,7 +128,7 @@ func TestDelete(t *testing.T) {
 		t.Fatal(err)
 	}
 	assertNImages(graph, t, 0)
-	img, err := graph.Create(archive, "", "Bla bla")
+	img, err := graph.Create(archive, nil, "Bla bla")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -139,11 +139,11 @@ func TestDelete(t *testing.T) {
 	assertNImages(graph, t, 0)
 
 	// Test 2 create (same name) / 1 delete
-	img1, err := graph.Create(archive, "foo", "Testing")
+	img1, err := graph.Create(archive, nil, "Testing")
 	if err != nil {
 		t.Fatal(err)
 	}
-	if _, err = graph.Create(archive, "foo", "Testing"); err != nil {
+	if _, err = graph.Create(archive, nil, "Testing"); err != nil {
 		t.Fatal(err)
 	}
 	assertNImages(graph, t, 2)

+ 7 - 5
image.go

@@ -15,11 +15,13 @@ import (
 )
 
 type Image struct {
-	Id      string    `json:"id"`
-	Parent  string    `json:"parent,omitempty"`
-	Comment string    `json:"comment,omitempty"`
-	Created time.Time `json:"created"`
-	graph   *Graph
+	Id              string    `json:"id"`
+	Parent          string    `json:"parent,omitempty"`
+	Comment         string    `json:"comment,omitempty"`
+	Created         time.Time `json:"created"`
+	ParentContainer string    `json:-`
+	ParentCommand   []string  `json:-`
+	graph           *Graph
 }
 
 func LoadImage(root string) (*Image, error) {

+ 27 - 0
runtime.go

@@ -200,6 +200,33 @@ func (runtime *Runtime) Destroy(container *Container) error {
 	return nil
 }
 
+// Commit creates a new filesystem image from the current state of a container.
+// The image can optionally be tagged into a repository
+func (runtime *Runtime) Commit(id, repository, tag string) (*Image, error) {
+	container := runtime.Get(id)
+	if container == nil {
+		return nil, fmt.Errorf("No such container: %s", id)
+	}
+	// FIXME: freeze the container before copying it to avoid data corruption?
+	// FIXME: this shouldn't be in commands.
+	rwTar, err := container.ExportRw()
+	if err != nil {
+		return nil, err
+	}
+	// Create a new image from the container's base layers + a new layer from container changes
+	img, err := runtime.graph.Create(rwTar, container, "")
+	if err != nil {
+		return nil, err
+	}
+	// Register the image if needed
+	if repository != "" {
+		if err := runtime.repositories.Set(repository, tag, img.Id); err != nil {
+			return img, err
+		}
+	}
+	return img, nil
+}
+
 func (runtime *Runtime) restore() error {
 	dir, err := ioutil.ReadDir(runtime.repository)
 	if err != nil {

+ 8 - 0
tags.go

@@ -2,9 +2,11 @@ package docker
 
 import (
 	"encoding/json"
+	"fmt"
 	"io/ioutil"
 	"os"
 	"path/filepath"
+	"strings"
 )
 
 type TagStore struct {
@@ -60,6 +62,12 @@ func (store *TagStore) Reload() error {
 }
 
 func (store *TagStore) Set(repoName, tag, revision string) error {
+	if strings.Contains(repoName, ":") {
+		return fmt.Errorf("Illegal repository name: %s", repoName)
+	}
+	if strings.Contains(repoName, ":") {
+		return fmt.Errorf("Illegal tag name: %s", tag)
+	}
 	if err := store.Reload(); err != nil {
 		return err
 	}