зеркало из https://github.com/microsoft/docker.git
Merge branch 'master' into 0.6.5-dm-plugin
This commit is contained in:
Коммит
a2c9d2da93
14
api.go
14
api.go
|
@ -539,19 +539,11 @@ func getImagesGet(srv *Server, version float64, w http.ResponseWriter, r *http.R
|
||||||
if version > 1.0 {
|
if version > 1.0 {
|
||||||
w.Header().Set("Content-Type", "application/x-tar")
|
w.Header().Set("Content-Type", "application/x-tar")
|
||||||
}
|
}
|
||||||
err := srv.ImageExport(name, w)
|
return srv.ImageExport(name, w)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func postImagesLoad(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postImagesLoad(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
err := srv.ImageLoad(r.Body)
|
return srv.ImageLoad(r.Body)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func postContainersCreate(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postContainersCreate(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
|
@ -987,7 +979,7 @@ func postContainersCopy(srv *Server, version float64, w http.ResponseWriter, r *
|
||||||
}
|
}
|
||||||
|
|
||||||
if copyData.Resource == "" {
|
if copyData.Resource == "" {
|
||||||
return fmt.Errorf("Resource cannot be empty")
|
return fmt.Errorf("Path cannot be empty")
|
||||||
}
|
}
|
||||||
if copyData.Resource[0] == '/' {
|
if copyData.Resource[0] == '/' {
|
||||||
copyData.Resource = copyData.Resource[1:]
|
copyData.Resource = copyData.Resource[1:]
|
||||||
|
|
19
commands.go
19
commands.go
|
@ -1085,7 +1085,7 @@ func (cli *DockerCli) CmdPull(args ...string) error {
|
||||||
func (cli *DockerCli) CmdImages(args ...string) error {
|
func (cli *DockerCli) CmdImages(args ...string) error {
|
||||||
cmd := Subcmd("images", "[OPTIONS] [NAME]", "List images")
|
cmd := Subcmd("images", "[OPTIONS] [NAME]", "List images")
|
||||||
quiet := cmd.Bool("q", false, "only show numeric IDs")
|
quiet := cmd.Bool("q", false, "only show numeric IDs")
|
||||||
all := cmd.Bool("a", false, "show all images")
|
all := cmd.Bool("a", false, "show all images (by default filter out the intermediate images used to build)")
|
||||||
noTrunc := cmd.Bool("notrunc", false, "Don't truncate output")
|
noTrunc := cmd.Bool("notrunc", false, "Don't truncate output")
|
||||||
flViz := cmd.Bool("viz", false, "output graph in graphviz format")
|
flViz := cmd.Bool("viz", false, "output graph in graphviz format")
|
||||||
flTree := cmd.Bool("tree", false, "output graph in tree format")
|
flTree := cmd.Bool("tree", false, "output graph in tree format")
|
||||||
|
@ -1938,7 +1938,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *DockerCli) CmdCp(args ...string) error {
|
func (cli *DockerCli) CmdCp(args ...string) error {
|
||||||
cmd := Subcmd("cp", "CONTAINER:RESOURCE HOSTPATH", "Copy files/folders from the RESOURCE to the HOSTPATH")
|
cmd := Subcmd("cp", "CONTAINER:PATH HOSTPATH", "Copy files/folders from the PATH to the HOSTPATH")
|
||||||
if err := cmd.Parse(args); err != nil {
|
if err := cmd.Parse(args); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1952,7 +1952,7 @@ func (cli *DockerCli) CmdCp(args ...string) error {
|
||||||
info := strings.Split(cmd.Arg(0), ":")
|
info := strings.Split(cmd.Arg(0), ":")
|
||||||
|
|
||||||
if len(info) != 2 {
|
if len(info) != 2 {
|
||||||
return fmt.Errorf("Error: Resource not specified")
|
return fmt.Errorf("Error: Path not specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
copyData.Resource = info[1]
|
copyData.Resource = info[1]
|
||||||
|
@ -1975,8 +1975,7 @@ func (cli *DockerCli) CmdCp(args ...string) error {
|
||||||
func (cli *DockerCli) CmdSave(args ...string) error {
|
func (cli *DockerCli) CmdSave(args ...string) error {
|
||||||
cmd := Subcmd("save", "IMAGE DESTINATION", "Save an image to a tar archive")
|
cmd := Subcmd("save", "IMAGE DESTINATION", "Save an image to a tar archive")
|
||||||
if err := cmd.Parse(args); err != nil {
|
if err := cmd.Parse(args); err != nil {
|
||||||
cmd.Usage()
|
return err
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.NArg() != 1 {
|
if cmd.NArg() != 1 {
|
||||||
|
@ -1985,7 +1984,6 @@ func (cli *DockerCli) CmdSave(args ...string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
image := cmd.Arg(0)
|
image := cmd.Arg(0)
|
||||||
|
|
||||||
if err := cli.stream("GET", "/images/"+image+"/get", nil, cli.out, nil); err != nil {
|
if err := cli.stream("GET", "/images/"+image+"/get", nil, cli.out, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1994,17 +1992,18 @@ func (cli *DockerCli) CmdSave(args ...string) error {
|
||||||
|
|
||||||
func (cli *DockerCli) CmdLoad(args ...string) error {
|
func (cli *DockerCli) CmdLoad(args ...string) error {
|
||||||
cmd := Subcmd("load", "SOURCE", "Load an image from a tar archive")
|
cmd := Subcmd("load", "SOURCE", "Load an image from a tar archive")
|
||||||
|
if err := cmd.Parse(args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if cmd.NArg() != 0 {
|
if cmd.NArg() != 0 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err := cli.stream("POST", "/images/load", cli.in, cli.out, nil)
|
if err := cli.stream("POST", "/images/load", cli.in, cli.out, nil); err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
fmt.Println("Send failed", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -219,10 +219,15 @@ Full -run example
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
Usage: docker cp CONTAINER:RESOURCE HOSTPATH
|
Usage: docker cp CONTAINER:PATH HOSTPATH
|
||||||
|
|
||||||
Copy files/folders from the containers filesystem to the host
|
Copy files/folders from the containers filesystem to the host
|
||||||
path. Paths are relative to the root of the filesystem.
|
path. Paths are relative to the root of the filesystem.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ sudo docker cp 7bb0e258aefe:/etc/debian_version .
|
||||||
|
$ sudo docker cp blue_frog:/etc/hosts .
|
||||||
|
|
||||||
.. _cli_diff:
|
.. _cli_diff:
|
||||||
|
|
||||||
|
@ -392,18 +397,52 @@ To see how the docker:latest image was built:
|
||||||
|
|
||||||
List images
|
List images
|
||||||
|
|
||||||
-a=false: show all images
|
-a=false: show all images (by default filter out the intermediate images used to build)
|
||||||
-notrunc=false: Don't truncate output
|
-notrunc=false: Don't truncate output
|
||||||
-q=false: only show numeric IDs
|
-q=false: only show numeric IDs
|
||||||
-tree=false: output graph in tree format
|
-tree=false: output graph in tree format
|
||||||
-viz=false: output graph in graphviz format
|
-viz=false: output graph in graphviz format
|
||||||
|
|
||||||
|
Listing the most recently created images
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ sudo docker images | head
|
||||||
|
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||||
|
<none> <none> 77af4d6b9913 19 hours ago 30.53 MB (virtual 1.089 GB)
|
||||||
|
committest latest b6fa739cedf5 19 hours ago 30.53 MB (virtual 1.089 GB)
|
||||||
|
<none> <none> 78a85c484f71 19 hours ago 30.53 MB (virtual 1.089 GB)
|
||||||
|
docker latest 30557a29d5ab 20 hours ago 30.53 MB (virtual 1.089 GB)
|
||||||
|
<none> <none> 0124422dd9f9 20 hours ago 30.53 MB (virtual 1.089 GB)
|
||||||
|
<none> <none> 18ad6fad3402 22 hours ago 23.68 MB (virtual 1.082 GB)
|
||||||
|
<none> <none> f9f1e26352f0 23 hours ago 30.46 MB (virtual 1.089 GB)
|
||||||
|
tryout latest 2629d1fa0b81 23 hours ago 16.4 kB (virtual 131.5 MB)
|
||||||
|
<none> <none> 5ed6274db6ce 24 hours ago 30.44 MB (virtual 1.089 GB)
|
||||||
|
|
||||||
|
Listing the full length image IDs
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ sudo docker images -notrunc | head
|
||||||
|
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||||
|
<none> <none> 77af4d6b9913e693e8d0b4b294fa62ade6054e6b2f1ffb617ac955dd63fb0182 19 hours ago 30.53 MB (virtual 1.089 GB)
|
||||||
|
committest latest b6fa739cedf5ea12a620a439402b6004d057da800f91c7524b5086a5e4749c9f 19 hours ago 30.53 MB (virtual 1.089 GB)
|
||||||
|
<none> <none> 78a85c484f71509adeaace20e72e941f6bdd2b25b4c75da8693efd9f61a37921 19 hours ago 30.53 MB (virtual 1.089 GB)
|
||||||
|
docker latest 30557a29d5abc51e5f1d5b472e79b7e296f595abcf19fe6b9199dbbc809c6ff4 20 hours ago 30.53 MB (virtual 1.089 GB)
|
||||||
|
<none> <none> 0124422dd9f9cf7ef15c0617cda3931ee68346455441d66ab8bdc5b05e9fdce5 20 hours ago 30.53 MB (virtual 1.089 GB)
|
||||||
|
<none> <none> 18ad6fad340262ac2a636efd98a6d1f0ea775ae3d45240d3418466495a19a81b 22 hours ago 23.68 MB (virtual 1.082 GB)
|
||||||
|
<none> <none> f9f1e26352f0a3ba6a0ff68167559f64f3e21ff7ada60366e2d44a04befd1d3a 23 hours ago 30.46 MB (virtual 1.089 GB)
|
||||||
|
tryout latest 2629d1fa0b81b222fca63371ca16cbf6a0772d07759ff80e8d1369b926940074 23 hours ago 16.4 kB (virtual 131.5 MB)
|
||||||
|
<none> <none> 5ed6274db6ceb2397844896966ea239290555e74ef307030ebb01ff91b1914df 24 hours ago 30.44 MB (virtual 1.089 GB)
|
||||||
|
|
||||||
Displaying images visually
|
Displaying images visually
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
::
|
.. code-block:: bash
|
||||||
|
|
||||||
sudo docker images -viz | dot -Tpng -o docker.png
|
$ sudo docker images -viz | dot -Tpng -o docker.png
|
||||||
|
|
||||||
.. image:: docker_images.gif
|
.. image:: docker_images.gif
|
||||||
:alt: Example inheritance graph of Docker images.
|
:alt: Example inheritance graph of Docker images.
|
||||||
|
@ -412,9 +451,9 @@ Displaying images visually
|
||||||
Displaying image hierarchy
|
Displaying image hierarchy
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
::
|
.. code-block:: bash
|
||||||
|
|
||||||
sudo docker images -tree
|
$ sudo docker images -tree
|
||||||
|
|
||||||
|─8dbd9e392a96 Size: 131.5 MB (virtual 131.5 MB) Tags: ubuntu:12.04,ubuntu:latest,ubuntu:precise
|
|─8dbd9e392a96 Size: 131.5 MB (virtual 131.5 MB) Tags: ubuntu:12.04,ubuntu:latest,ubuntu:precise
|
||||||
└─27cf78414709 Size: 180.1 MB (virtual 180.1 MB)
|
└─27cf78414709 Size: 180.1 MB (virtual 180.1 MB)
|
||||||
|
|
163
server.go
163
server.go
|
@ -212,67 +212,38 @@ func (srv *Server) ImageExport(name string, out io.Writer) error {
|
||||||
|
|
||||||
utils.Debugf("Serializing %s", name)
|
utils.Debugf("Serializing %s", name)
|
||||||
|
|
||||||
rootRepo := srv.runtime.repositories.Repositories[name]
|
rootRepo, err := srv.runtime.repositories.Get(name)
|
||||||
for _, rootImage := range rootRepo {
|
if err != nil {
|
||||||
image, _ := srv.ImageInspect(rootImage)
|
return err
|
||||||
for i := image; i != nil; {
|
}
|
||||||
// temporary directory
|
if rootRepo != nil {
|
||||||
tmpImageDir := path.Join(tempdir, i.ID)
|
for _, id := range rootRepo {
|
||||||
if err := os.Mkdir(tmpImageDir, os.ModeDir); err != nil {
|
image, err := srv.ImageInspect(id)
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpImageDir)
|
|
||||||
|
|
||||||
var version = "1.0"
|
|
||||||
var versionBuf = []byte(version)
|
|
||||||
|
|
||||||
if err := ioutil.WriteFile(path.Join(tmpImageDir, "VERSION"), versionBuf, os.ModeAppend); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// serialize json
|
|
||||||
b, err := json.Marshal(i)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := ioutil.WriteFile(path.Join(tmpImageDir, "json"), b, os.ModeAppend); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// serialize filesystem
|
|
||||||
fs, err := archive.Tar(path.Join(srv.runtime.graph.Root, i.ID, "layer"), archive.Uncompressed)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fsTar, err := os.Create(path.Join(tmpImageDir, "layer.tar"))
|
if err := srv.exportImage(image, tempdir); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err = io.Copy(fsTar, fs); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fsTar.Close()
|
|
||||||
|
|
||||||
// find parent
|
|
||||||
if i.Parent != "" {
|
|
||||||
i, err = srv.ImageInspect(i.Parent)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
i = nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// write repositories
|
// write repositories
|
||||||
rootRepoMap := map[string]Repository{}
|
rootRepoMap := map[string]Repository{}
|
||||||
rootRepoMap[name] = rootRepo
|
rootRepoMap[name] = rootRepo
|
||||||
rootRepoJson, _ := json.Marshal(rootRepoMap)
|
rootRepoJson, _ := json.Marshal(rootRepoMap)
|
||||||
|
|
||||||
if err := ioutil.WriteFile(path.Join(tempdir, "repositories"), rootRepoJson, os.ModeAppend); err != nil {
|
if err := ioutil.WriteFile(path.Join(tempdir, "repositories"), rootRepoJson, os.ModeAppend); err != nil {
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
image, err := srv.ImageInspect(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := srv.exportImage(image, tempdir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fs, err := archive.Tar(tempdir, archive.Uncompressed)
|
fs, err := archive.Tar(tempdir, archive.Uncompressed)
|
||||||
|
@ -286,6 +257,58 @@ func (srv *Server) ImageExport(name string, out io.Writer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (srv *Server) exportImage(image *Image, tempdir string) error {
|
||||||
|
for i := image; i != nil; {
|
||||||
|
// temporary directory
|
||||||
|
tmpImageDir := path.Join(tempdir, i.ID)
|
||||||
|
if err := os.Mkdir(tmpImageDir, os.ModeDir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var version = "1.0"
|
||||||
|
var versionBuf = []byte(version)
|
||||||
|
|
||||||
|
if err := ioutil.WriteFile(path.Join(tmpImageDir, "VERSION"), versionBuf, os.ModeAppend); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// serialize json
|
||||||
|
b, err := json.Marshal(i)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := ioutil.WriteFile(path.Join(tmpImageDir, "json"), b, os.ModeAppend); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// serialize filesystem
|
||||||
|
fs, err := archive.Tar(path.Join(srv.runtime.graph.Root, i.ID, "layer"), archive.Uncompressed)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fsTar, err := os.Create(path.Join(tmpImageDir, "layer.tar"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = io.Copy(fsTar, fs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fsTar.Close()
|
||||||
|
|
||||||
|
// find parent
|
||||||
|
if i.Parent != "" {
|
||||||
|
i, err = srv.ImageInspect(i.Parent)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Loads a set of images into the repository. This is the complementary of ImageExport.
|
// Loads a set of images into the repository. This is the complementary of ImageExport.
|
||||||
// The input stream is an uncompressed tar ball containing images and metadata.
|
// The input stream is an uncompressed tar ball containing images and metadata.
|
||||||
func (srv *Server) ImageLoad(in io.Reader) error {
|
func (srv *Server) ImageLoad(in io.Reader) error {
|
||||||
|
@ -319,25 +342,38 @@ func (srv *Server) ImageLoad(in io.Reader) error {
|
||||||
if err := archive.Untar(repoFile, repoDir, nil); err != nil {
|
if err := archive.Untar(repoFile, repoDir, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
repositoriesJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", "repositories"))
|
|
||||||
|
dirs, err := ioutil.ReadDir(repoDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
repositories := map[string]Repository{}
|
|
||||||
if err := json.Unmarshal(repositoriesJson, &repositories); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for imageName, tagMap := range repositories {
|
for _, d := range dirs {
|
||||||
for tag, address := range tagMap {
|
if d.IsDir() {
|
||||||
if err := srv.recursiveLoad(address, tmpImageDir); err != nil {
|
if err := srv.recursiveLoad(d.Name(), tmpImageDir); err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := srv.runtime.repositories.Set(imageName, tag, address, true); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repositoriesJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", "repositories"))
|
||||||
|
if err == nil {
|
||||||
|
repositories := map[string]Repository{}
|
||||||
|
if err := json.Unmarshal(repositoriesJson, &repositories); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for imageName, tagMap := range repositories {
|
||||||
|
for tag, address := range tagMap {
|
||||||
|
if err := srv.runtime.repositories.Set(imageName, tag, address, true); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,6 +409,7 @@ func (srv *Server) recursiveLoad(address, tmpImageDir string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
utils.Debugf("Completed processing %s", address)
|
utils.Debugf("Completed processing %s", address)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче