-
Notifications
You must be signed in to change notification settings - Fork 18.6k
/
service.go
134 lines (126 loc) · 4.01 KB
/
service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package graph
import (
"fmt"
"io"
log "github.com/Sirupsen/logrus"
"github.com/docker/docker/engine"
)
func (s *TagStore) Install(eng *engine.Engine) error {
for name, handler := range map[string]engine.Handler{
"image_tag": s.CmdTag,
"tag": s.CmdTagLegacy, // FIXME merge with "image_tag"
"image_get": s.CmdGet,
"image_inspect": s.CmdLookup,
"image_tarlayer": s.CmdTarLayer,
"image_export": s.CmdImageExport,
"history": s.CmdHistory,
"images": s.CmdImages,
"viz": s.CmdViz,
"load": s.CmdLoad,
"import": s.CmdImport,
"pull": s.CmdPull,
"push": s.CmdPush,
} {
if err := eng.Register(name, handler); err != nil {
return fmt.Errorf("Could not register %q: %v", name, err)
}
}
return nil
}
// CmdGet returns information about an image.
// If the image doesn't exist, an empty object is returned, to allow
// checking for an image's existence.
func (s *TagStore) CmdGet(job *engine.Job) engine.Status {
if len(job.Args) != 1 {
return job.Errorf("usage: %s NAME", job.Name)
}
name := job.Args[0]
res := &engine.Env{}
img, err := s.LookupImage(name)
// Note: if the image doesn't exist, LookupImage returns
// nil, nil.
if err != nil {
return job.Error(err)
}
if img != nil {
// We don't directly expose all fields of the Image objects,
// to maintain a clean public API which we can maintain over
// time even if the underlying structure changes.
// We should have done this with the Image object to begin with...
// but we didn't, so now we're doing it here.
//
// Fields that we're probably better off not including:
// - Config/ContainerConfig. Those structs have the same sprawl problem,
// so we shouldn't include them wholesale either.
// - Comment: initially created to fulfill the "every image is a git commit"
// metaphor, in practice people either ignore it or use it as a
// generic description field which it isn't. On deprecation shortlist.
res.SetAuto("Created", img.Created)
res.Set("Author", img.Author)
res.Set("Os", img.OS)
res.Set("Architecture", img.Architecture)
res.Set("DockerVersion", img.DockerVersion)
res.Set("Id", img.ID)
res.Set("Parent", img.Parent)
}
res.WriteTo(job.Stdout)
return engine.StatusOK
}
// CmdLookup return an image encoded in JSON
func (s *TagStore) CmdLookup(job *engine.Job) engine.Status {
if len(job.Args) != 1 {
return job.Errorf("usage: %s NAME", job.Name)
}
name := job.Args[0]
if image, err := s.LookupImage(name); err == nil && image != nil {
if job.GetenvBool("raw") {
b, err := image.RawJson()
if err != nil {
return job.Error(err)
}
job.Stdout.Write(b)
return engine.StatusOK
}
out := &engine.Env{}
out.Set("Id", image.ID)
out.Set("Parent", image.Parent)
out.Set("Comment", image.Comment)
out.SetAuto("Created", image.Created)
out.Set("Container", image.Container)
out.SetJson("ContainerConfig", image.ContainerConfig)
out.Set("DockerVersion", image.DockerVersion)
out.Set("Author", image.Author)
out.SetJson("Config", image.Config)
out.Set("Architecture", image.Architecture)
out.Set("Os", image.OS)
out.SetInt64("Size", image.Size)
out.SetInt64("VirtualSize", image.GetParentsSize(0)+image.Size)
out.Set("Checksum", image.Checksum)
if _, err = out.WriteTo(job.Stdout); err != nil {
return job.Error(err)
}
return engine.StatusOK
}
return job.Errorf("No such image: %s", name)
}
// CmdTarLayer return the tarLayer of the image
func (s *TagStore) CmdTarLayer(job *engine.Job) engine.Status {
if len(job.Args) != 1 {
return job.Errorf("usage: %s NAME", job.Name)
}
name := job.Args[0]
if image, err := s.LookupImage(name); err == nil && image != nil {
fs, err := image.TarLayer()
if err != nil {
return job.Error(err)
}
defer fs.Close()
written, err := io.Copy(job.Stdout, fs)
if err != nil {
return job.Error(err)
}
log.Debugf("rendered layer for %s of [%d] size", image.ID, written)
return engine.StatusOK
}
return job.Errorf("No such image: %s", name)
}