Skip to content

Commit

Permalink
Expose new mount points structs in inspect.
Browse files Browse the repository at this point in the history
Keep old hashes around for old api version calls.

Signed-off-by: David Calavera <[email protected]>
  • Loading branch information
calavera committed Jul 21, 2015
1 parent 48a01a3 commit 1c3cb2d
Show file tree
Hide file tree
Showing 14 changed files with 264 additions and 89 deletions.
4 changes: 2 additions & 2 deletions api/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1193,8 +1193,8 @@ func (s *Server) getContainersByName(version version.Version, w http.ResponseWri
return fmt.Errorf("Missing parameter")
}

if version.LessThan("1.19") {
containerJSONRaw, err := s.daemon.ContainerInspectRaw(vars["name"])
if version.LessThan("1.20") {
containerJSONRaw, err := s.daemon.ContainerInspectPre120(vars["name"])
if err != nil {
return err
}
Expand Down
19 changes: 15 additions & 4 deletions api/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,6 @@ type ContainerJSONBase struct {
ExecDriver string
MountLabel string
ProcessLabel string
Volumes map[string]string
VolumesRW map[string]bool
AppArmorProfile string
ExecIDs []string
HostConfig *runconfig.HostConfig
Expand All @@ -235,13 +233,16 @@ type ContainerJSONBase struct {

type ContainerJSON struct {
*ContainerJSONBase
Mounts []MountPoint
Config *runconfig.Config
}

// backcompatibility struct along with ContainerConfig
type ContainerJSONRaw struct {
type ContainerJSONPre120 struct {
*ContainerJSONBase
Config *ContainerConfig
Volumes map[string]string
VolumesRW map[string]bool
Config *ContainerConfig
}

type ContainerConfig struct {
Expand All @@ -253,3 +254,13 @@ type ContainerConfig struct {
CpuShares int64
Cpuset string
}

// MountPoint represents a mount point configuration inside the container.
type MountPoint struct {
Name string `json:",omitempty"`
Source string
Destination string
Driver string `json:",omitempty"`
Mode string // this is internally named `Relabel`
RW bool
}
35 changes: 22 additions & 13 deletions daemon/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,22 @@ func (daemon *Daemon) ContainerInspect(name string) (*types.ContainerJSON, error
return nil, err
}

return &types.ContainerJSON{base, container.Config}, nil
mountPoints := make([]types.MountPoint, 0, len(container.MountPoints))
for _, m := range container.MountPoints {
mountPoints = append(mountPoints, types.MountPoint{
Name: m.Name,
Source: m.Path(),
Destination: m.Destination,
Driver: m.Driver,
Mode: m.Relabel,
RW: m.RW,
})
}

return &types.ContainerJSON{base, mountPoints, container.Config}, nil
}

func (daemon *Daemon) ContainerInspectRaw(name string) (*types.ContainerJSONRaw, error) {
func (daemon *Daemon) ContainerInspectPre120(name string) (*types.ContainerJSONPre120, error) {
container, err := daemon.Get(name)
if err != nil {
return nil, err
Expand All @@ -37,6 +49,13 @@ func (daemon *Daemon) ContainerInspectRaw(name string) (*types.ContainerJSONRaw,
return nil, err
}

volumes := make(map[string]string)
volumesRW := make(map[string]bool)
for _, m := range container.MountPoints {
volumes[m.Destination] = m.Path()
volumesRW[m.Destination] = m.RW
}

config := &types.ContainerConfig{
container.Config,
container.hostConfig.Memory,
Expand All @@ -45,7 +64,7 @@ func (daemon *Daemon) ContainerInspectRaw(name string) (*types.ContainerJSONRaw,
container.hostConfig.CpusetCpus,
}

return &types.ContainerJSONRaw{base, config}, nil
return &types.ContainerJSONPre120{base, volumes, volumesRW, config}, nil
}

func (daemon *Daemon) getInspectData(container *Container) (*types.ContainerJSONBase, error) {
Expand Down Expand Up @@ -76,14 +95,6 @@ func (daemon *Daemon) getInspectData(container *Container) (*types.ContainerJSON
FinishedAt: container.State.FinishedAt,
}

volumes := make(map[string]string)
volumesRW := make(map[string]bool)

for _, m := range container.MountPoints {
volumes[m.Destination] = m.Path()
volumesRW[m.Destination] = m.RW
}

contJSONBase := &types.ContainerJSONBase{
Id: container.ID,
Created: container.Created,
Expand All @@ -102,8 +113,6 @@ func (daemon *Daemon) getInspectData(container *Container) (*types.ContainerJSON
ExecDriver: container.ExecDriver,
MountLabel: container.MountLabel,
ProcessLabel: container.ProcessLabel,
Volumes: volumes,
VolumesRW: volumesRW,
AppArmorProfile: container.AppArmorProfile,
ExecIDs: container.GetExecIDs(),
HostConfig: &hostConfig,
Expand Down
38 changes: 26 additions & 12 deletions docs/reference/api/docker_remote_api_v1.20.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,14 @@ Create a container
"com.example.license": "GPL",
"com.example.version": "1.0"
},
"Volumes": {
"/tmp": {}
},
"Mounts": [
{
"Source": "/data",
"Destination": "/data",
"Mode": "ro,Z",
"RW": false
}
],
"WorkingDir": "",
"NetworkDisabled": false,
"MacAddress": "12:34:56:78:9a:bc",
Expand Down Expand Up @@ -223,8 +228,7 @@ Json Parameters:
- **Entrypoint** - Set the entry point for the container as a string or an array
of strings.
- **Image** - A string specifying the image name to use for the container.
- **Volumes** – An object mapping mount point paths (strings) inside the
container to empty objects.
- **Mounts** - An array of mount points in the container.
- **WorkingDir** - A string specifying the working directory for commands to
run in.
- **NetworkDisabled** - Boolean value, when true disables networking for the
Expand Down Expand Up @@ -420,8 +424,14 @@ Return low-level information on the container `id`
"Running": false,
"StartedAt": "2015-01-06T15:47:32.072697474Z"
},
"Volumes": {},
"VolumesRW": {}
"Mounts": [
{
"Source": "/data",
"Destination": "/data",
"Mode": "ro,Z",
"RW": false
}
]
}

Status Codes:
Expand Down Expand Up @@ -1694,9 +1704,14 @@ Create a new image from a container's changes
"Cmd": [
"date"
],
"Volumes": {
"/tmp": {}
},
"Mounts": [
{
"Source": "/data",
"Destination": "/data",
"Mode": "ro,Z",
"RW": false
}
],
"Labels": {
"key1": "value1",
"key2": "value2"
Expand Down Expand Up @@ -2082,8 +2097,7 @@ Return low-level information about the `exec` command `id`.
"ProcessLabel" : "",
"AppArmorProfile" : "",
"RestartCount" : 0,
"Volumes" : {},
"VolumesRW" : {}
"Mounts" : [],
}
}

Expand Down
20 changes: 9 additions & 11 deletions integration-cli/docker_api_containers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func (s *DockerSuite) TestContainerApiStartVolumeBinds(c *check.C) {
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusNoContent)

pth, err := inspectFieldMap(name, "Volumes", "/tmp")
pth, err := inspectMountSourceField(name, "/tmp")
if err != nil {
c.Fatal(err)
}
Expand Down Expand Up @@ -233,7 +233,7 @@ func (s *DockerSuite) TestContainerApiStartVolumesFrom(c *check.C) {

dockerCmd(c, "run", "-d", "--name", volName, "-v", volPath, "busybox")

name := "TestContainerApiStartDupVolumeBinds"
name := "TestContainerApiStartVolumesFrom"
config := map[string]interface{}{
"Image": "busybox",
"Volumes": map[string]struct{}{volPath: {}},
Expand All @@ -250,11 +250,11 @@ func (s *DockerSuite) TestContainerApiStartVolumesFrom(c *check.C) {
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusNoContent)

pth, err := inspectFieldMap(name, "Volumes", volPath)
pth, err := inspectMountSourceField(name, volPath)
if err != nil {
c.Fatal(err)
}
pth2, err := inspectFieldMap(volName, "Volumes", volPath)
pth2, err := inspectMountSourceField(volName, volPath)
if err != nil {
c.Fatal(err)
}
Expand Down Expand Up @@ -705,7 +705,7 @@ func (s *DockerSuite) TestBuildApiDockerfileSymlink(c *check.C) {
func (s *DockerSuite) TestPostContainerBindNormalVolume(c *check.C) {
dockerCmd(c, "create", "-v", "/foo", "--name=one", "busybox")

fooDir, err := inspectFieldMap("one", "Volumes", "/foo")
fooDir, err := inspectMountSourceField("one", "/foo")
if err != nil {
c.Fatal(err)
}
Expand All @@ -717,7 +717,7 @@ func (s *DockerSuite) TestPostContainerBindNormalVolume(c *check.C) {
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusNoContent)

fooDir2, err := inspectFieldMap("two", "Volumes", "/foo")
fooDir2, err := inspectMountSourceField("two", "/foo")
if err != nil {
c.Fatal(err)
}
Expand Down Expand Up @@ -1467,17 +1467,15 @@ func (s *DockerSuite) TestContainerApiDeleteRemoveVolume(c *check.C) {
id := strings.TrimSpace(out)
c.Assert(waitRun(id), check.IsNil)

vol, err := inspectFieldMap(id, "Volumes", "/testvolume")
c.Assert(err, check.IsNil)

_, err = os.Stat(vol)
source, err := inspectMountSourceField(id, "/testvolume")
_, err = os.Stat(source)
c.Assert(err, check.IsNil)

status, _, err := sockRequest("DELETE", "/containers/"+id+"?v=1&force=1", nil)
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusNoContent)

if _, err := os.Stat(vol); !os.IsNotExist(err) {
if _, err := os.Stat(source); !os.IsNotExist(err) {
c.Fatalf("expected to get ErrNotExist error, got %v", err)
}
}
Expand Down
45 changes: 28 additions & 17 deletions integration-cli/docker_api_inspect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"encoding/json"
"fmt"
"net/http"
"strings"

Expand All @@ -12,28 +13,38 @@ func (s *DockerSuite) TestInspectApiContainerResponse(c *check.C) {
out, _ := dockerCmd(c, "run", "-d", "busybox", "true")

cleanedContainerID := strings.TrimSpace(out)
keysBase := []string{"Id", "State", "Created", "Path", "Args", "Config", "Image", "NetworkSettings",
"ResolvConfPath", "HostnamePath", "HostsPath", "LogPath", "Name", "Driver", "ExecDriver", "MountLabel", "ProcessLabel", "GraphDriver"}

cases := []struct {
version string
keys []string
}{
{"1.20", append(keysBase, "Mounts")},
{"1.19", append(keysBase, "Volumes", "VolumesRW")},
}

endpoint := "/containers/" + cleanedContainerID + "/json"
status, body, err := sockRequest("GET", endpoint, nil)
c.Assert(status, check.Equals, http.StatusOK)
c.Assert(err, check.IsNil)
for _, cs := range cases {
endpoint := fmt.Sprintf("/v%s/containers/%s/json", cs.version, cleanedContainerID)

var inspectJSON map[string]interface{}
if err = json.Unmarshal(body, &inspectJSON); err != nil {
c.Fatalf("unable to unmarshal body for latest version: %v", err)
}
status, body, err := sockRequest("GET", endpoint, nil)
c.Assert(status, check.Equals, http.StatusOK)
c.Assert(err, check.IsNil)

keys := []string{"State", "Created", "Path", "Args", "Config", "Image", "NetworkSettings", "ResolvConfPath", "HostnamePath", "HostsPath", "LogPath", "Name", "Driver", "ExecDriver", "MountLabel", "ProcessLabel", "Volumes", "VolumesRW", "GraphDriver"}
var inspectJSON map[string]interface{}
if err = json.Unmarshal(body, &inspectJSON); err != nil {
c.Fatalf("unable to unmarshal body for version %s: %v", cs.version, err)
}

keys = append(keys, "Id")
for _, key := range cs.keys {
if _, ok := inspectJSON[key]; !ok {
c.Fatalf("%s does not exist in response for version %s", key, cs.version)
}
}

for _, key := range keys {
if _, ok := inspectJSON[key]; !ok {
c.Fatalf("%s does not exist in response for latest version", key)
//Issue #6830: type not properly converted to JSON/back
if _, ok := inspectJSON["Path"].(bool); ok {
c.Fatalf("Path of `true` should not be converted to boolean `true` via JSON marshalling")
}
}
//Issue #6830: type not properly converted to JSON/back
if _, ok := inspectJSON["Path"].(bool); ok {
c.Fatalf("Path of `true` should not be converted to boolean `true` via JSON marshalling")
}
}
2 changes: 1 addition & 1 deletion integration-cli/docker_cli_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func (s *DockerSuite) TestCreateVolumesCreated(c *check.C) {
name := "test_create_volume"
dockerCmd(c, "create", "--name", name, "-v", "/foo", "busybox")

dir, err := inspectFieldMap(name, "Volumes", "/foo")
dir, err := inspectMountSourceField(name, "/foo")
if err != nil {
c.Fatalf("Error getting volume host path: %q", err)
}
Expand Down
16 changes: 8 additions & 8 deletions integration-cli/docker_cli_daemon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,23 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithVolumesRefs(c *check.C) {
if out, err := s.d.Cmd("run", "-d", "--name", "volrestarttest1", "-v", "/foo", "busybox"); err != nil {
c.Fatal(err, out)
}

if err := s.d.Restart(); err != nil {
c.Fatal(err)
}
if _, err := s.d.Cmd("run", "-d", "--volumes-from", "volrestarttest1", "--name", "volrestarttest2", "busybox", "top"); err != nil {
c.Fatal(err)
}

if out, err := s.d.Cmd("rm", "-fv", "volrestarttest2"); err != nil {
c.Fatal(err, out)
}
v, err := s.d.Cmd("inspect", "--format", "{{ json .Volumes }}", "volrestarttest1")
if err != nil {
c.Fatal(err)
}
volumes := make(map[string]string)
json.Unmarshal([]byte(v), &volumes)
if _, err := os.Stat(volumes["/foo"]); err != nil {
c.Fatalf("Expected volume to exist: %s - %s", volumes["/foo"], err)

out, err := s.d.Cmd("inspect", "-f", "{{json .Mounts}}", "volrestarttest1")
c.Assert(err, check.IsNil)

if _, err := inspectMountPointJSON(out, "/foo"); err != nil {
c.Fatalf("Expected volume to exist: /foo, error: %v\n", err)
}
}

Expand Down
Loading

0 comments on commit 1c3cb2d

Please sign in to comment.