|
@@ -1,83 +1,92 @@
|
|
package daemon
|
|
package daemon
|
|
|
|
|
|
import (
|
|
import (
|
|
- "encoding/json"
|
|
|
|
"fmt"
|
|
"fmt"
|
|
|
|
|
|
- "github.com/docker/docker/engine"
|
|
|
|
|
|
+ "github.com/docker/docker/api/types"
|
|
"github.com/docker/docker/runconfig"
|
|
"github.com/docker/docker/runconfig"
|
|
)
|
|
)
|
|
|
|
|
|
-func (daemon *Daemon) ContainerInspect(job *engine.Job) error {
|
|
|
|
- if len(job.Args) != 1 {
|
|
|
|
- return fmt.Errorf("usage: %s NAME", job.Name)
|
|
|
|
- }
|
|
|
|
- name := job.Args[0]
|
|
|
|
|
|
+type ContainerJSONRaw struct {
|
|
|
|
+ *Container
|
|
|
|
+ HostConfig *runconfig.HostConfig
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (daemon *Daemon) ContainerInspectRaw(name string) (*ContainerJSONRaw, error) {
|
|
container, err := daemon.Get(name)
|
|
container, err := daemon.Get(name)
|
|
if err != nil {
|
|
if err != nil {
|
|
- return err
|
|
|
|
|
|
+ return nil, err
|
|
}
|
|
}
|
|
|
|
|
|
container.Lock()
|
|
container.Lock()
|
|
defer container.Unlock()
|
|
defer container.Unlock()
|
|
- if job.GetenvBool("raw") {
|
|
|
|
- b, err := json.Marshal(&struct {
|
|
|
|
- *Container
|
|
|
|
- HostConfig *runconfig.HostConfig
|
|
|
|
- }{container, container.hostConfig})
|
|
|
|
- if err != nil {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
- job.Stdout.Write(b)
|
|
|
|
- return nil
|
|
|
|
|
|
+
|
|
|
|
+ return &ContainerJSONRaw{container, container.hostConfig}, nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (daemon *Daemon) ContainerInspect(name string) (*types.ContainerJSON, error) {
|
|
|
|
+ container, err := daemon.Get(name)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, err
|
|
}
|
|
}
|
|
|
|
|
|
- out := &engine.Env{}
|
|
|
|
- out.SetJson("Id", container.ID)
|
|
|
|
- out.SetAuto("Created", container.Created)
|
|
|
|
- out.SetJson("Path", container.Path)
|
|
|
|
- out.SetList("Args", container.Args)
|
|
|
|
- out.SetJson("Config", container.Config)
|
|
|
|
- out.SetJson("State", container.State)
|
|
|
|
- out.Set("Image", container.ImageID)
|
|
|
|
- out.SetJson("NetworkSettings", container.NetworkSettings)
|
|
|
|
- out.Set("ResolvConfPath", container.ResolvConfPath)
|
|
|
|
- out.Set("HostnamePath", container.HostnamePath)
|
|
|
|
- out.Set("HostsPath", container.HostsPath)
|
|
|
|
- out.Set("LogPath", container.LogPath)
|
|
|
|
- out.SetJson("Name", container.Name)
|
|
|
|
- out.SetInt("RestartCount", container.RestartCount)
|
|
|
|
- out.Set("Driver", container.Driver)
|
|
|
|
- out.Set("ExecDriver", container.ExecDriver)
|
|
|
|
- out.Set("MountLabel", container.MountLabel)
|
|
|
|
- out.Set("ProcessLabel", container.ProcessLabel)
|
|
|
|
- out.SetJson("Volumes", container.Volumes)
|
|
|
|
- out.SetJson("VolumesRW", container.VolumesRW)
|
|
|
|
- out.SetJson("AppArmorProfile", container.AppArmorProfile)
|
|
|
|
|
|
+ container.Lock()
|
|
|
|
+ defer container.Unlock()
|
|
|
|
|
|
- out.SetList("ExecIDs", container.GetExecIDs())
|
|
|
|
|
|
+ // make a copy to play with
|
|
|
|
+ hostConfig := *container.hostConfig
|
|
|
|
|
|
if children, err := daemon.Children(container.Name); err == nil {
|
|
if children, err := daemon.Children(container.Name); err == nil {
|
|
for linkAlias, child := range children {
|
|
for linkAlias, child := range children {
|
|
- container.hostConfig.Links = append(container.hostConfig.Links, fmt.Sprintf("%s:%s", child.Name, linkAlias))
|
|
|
|
|
|
+ hostConfig.Links = append(hostConfig.Links, fmt.Sprintf("%s:%s", child.Name, linkAlias))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// we need this trick to preserve empty log driver, so
|
|
// we need this trick to preserve empty log driver, so
|
|
// container will use daemon defaults even if daemon change them
|
|
// container will use daemon defaults even if daemon change them
|
|
- if container.hostConfig.LogConfig.Type == "" {
|
|
|
|
- container.hostConfig.LogConfig = daemon.defaultLogConfig
|
|
|
|
- defer func() {
|
|
|
|
- container.hostConfig.LogConfig = runconfig.LogConfig{}
|
|
|
|
- }()
|
|
|
|
|
|
+ if hostConfig.LogConfig.Type == "" {
|
|
|
|
+ hostConfig.LogConfig = daemon.defaultLogConfig
|
|
}
|
|
}
|
|
|
|
|
|
- out.SetJson("HostConfig", container.hostConfig)
|
|
|
|
|
|
+ containerState := &types.ContainerState{
|
|
|
|
+ Running: container.State.Running,
|
|
|
|
+ Paused: container.State.Paused,
|
|
|
|
+ Restarting: container.State.Restarting,
|
|
|
|
+ OOMKilled: container.State.OOMKilled,
|
|
|
|
+ Dead: container.State.Dead,
|
|
|
|
+ Pid: container.State.Pid,
|
|
|
|
+ ExitCode: container.State.ExitCode,
|
|
|
|
+ Error: container.State.Error,
|
|
|
|
+ StartedAt: container.State.StartedAt,
|
|
|
|
+ FinishedAt: container.State.FinishedAt,
|
|
|
|
+ }
|
|
|
|
|
|
- container.hostConfig.Links = nil
|
|
|
|
- if _, err := out.WriteTo(job.Stdout); err != nil {
|
|
|
|
- return err
|
|
|
|
|
|
+ contJSON := &types.ContainerJSON{
|
|
|
|
+ Id: container.ID,
|
|
|
|
+ Created: container.Created,
|
|
|
|
+ Path: container.Path,
|
|
|
|
+ Args: container.Args,
|
|
|
|
+ Config: container.Config,
|
|
|
|
+ State: containerState,
|
|
|
|
+ Image: container.ImageID,
|
|
|
|
+ NetworkSettings: container.NetworkSettings,
|
|
|
|
+ ResolvConfPath: container.ResolvConfPath,
|
|
|
|
+ HostnamePath: container.HostnamePath,
|
|
|
|
+ HostsPath: container.HostsPath,
|
|
|
|
+ LogPath: container.LogPath,
|
|
|
|
+ Name: container.Name,
|
|
|
|
+ RestartCount: container.RestartCount,
|
|
|
|
+ Driver: container.Driver,
|
|
|
|
+ ExecDriver: container.ExecDriver,
|
|
|
|
+ MountLabel: container.MountLabel,
|
|
|
|
+ ProcessLabel: container.ProcessLabel,
|
|
|
|
+ Volumes: container.Volumes,
|
|
|
|
+ VolumesRW: container.VolumesRW,
|
|
|
|
+ AppArmorProfile: container.AppArmorProfile,
|
|
|
|
+ ExecIDs: container.GetExecIDs(),
|
|
|
|
+ HostConfig: &hostConfig,
|
|
}
|
|
}
|
|
- return nil
|
|
|
|
|
|
+
|
|
|
|
+ return contJSON, nil
|
|
}
|
|
}
|
|
|
|
|
|
func (daemon *Daemon) ContainerExecInspect(id string) (*execConfig, error) {
|
|
func (daemon *Daemon) ContainerExecInspect(id string) (*execConfig, error) {
|