@@ -17,49 +17,39 @@ import (
17
17
18
18
// Image initializes the given image, and attempts to pull the container from docker hub.
19
19
// If the Build() Option is provided then the given DockerFile tarball is built and returned.
20
- func (c * Client ) Image (ctx context.Context , image string , options ... ImageOption ) (* Image , error ) {
21
- _image : = & Image {
20
+ func (c * Client ) Image (ctx context.Context , name string , options ... ImageOption ) (image * Image , err error ) {
21
+ image = & Image {
22
22
client : c ,
23
- image : image ,
23
+ image : name ,
24
24
}
25
25
26
26
for _ , opt := range options {
27
- err := opt (_image )
28
- if err != nil {
29
- return nil , fmt .Errorf ("running image options for image `%s` failed with: %s" , image , err )
27
+ if err := opt (image ); err != nil {
28
+ return nil , errorImageOptions (name , err )
30
29
}
31
30
}
32
31
33
- imageExists := _image .checkImageExists (ctx )
34
- if _image .buildTarball != nil {
35
- if ForceRebuild || ! imageExists {
36
- err := _image .buildImage (ctx )
37
- if err != nil {
38
- return nil , fmt .Errorf ("building image `%s` failed with %s" , image , err )
39
- }
32
+ imageExists := image .checkImageExists (ctx )
33
+ if image .buildTarball != nil && (ForceRebuild || ! imageExists ) {
34
+ if err := image .buildImage (ctx ); err != nil {
35
+ return nil , errorImageBuild (name , err )
36
+ }
37
+ } else {
38
+ if image , err = image .Pull (ctx ); err != nil {
39
+ return nil , errorImagePull (name , err )
40
40
}
41
-
42
- return _image , nil
43
- }
44
-
45
- _image , err := _image .Pull (ctx )
46
- if err != nil && ! imageExists {
47
- return nil , fmt .Errorf ("pulling image `%s` failed with %s" , image , err )
48
41
}
49
42
50
- return _image , nil
43
+ return
51
44
}
52
45
53
46
// checkImage checks the docker host client if the image is known.
54
47
func (i * Image ) checkImageExists (ctx context.Context ) bool {
55
48
res , err := i .client .ImageList (ctx , types.ImageListOptions {
56
49
Filters : NewFilter ("reference" , i .image ),
57
50
})
58
- if err != nil || len (res ) < 1 {
59
- return false
60
- }
61
51
62
- return true
52
+ return err == nil && len ( res ) > 0
63
53
}
64
54
65
55
// buildImage builds a DockerFile tarball as a docker image.
@@ -71,16 +61,16 @@ func (i *Image) buildImage(ctx context.Context) error {
71
61
Context : i .buildTarball ,
72
62
Dockerfile : "Dockerfile" ,
73
63
Tags : []string {i .image },
74
- Remove : true })
64
+ Remove : true ,
65
+ },
66
+ )
75
67
if err != nil {
76
- return fmt . Errorf ( "building Dockerfile for image `%s` failed with: %s" , i . image , err )
68
+ return errorImageBuildDockerFile ( err )
77
69
}
78
-
79
70
defer imageBuildResponse .Body .Close ()
80
71
81
- _ , err = io .Copy (os .Stdout , imageBuildResponse .Body )
82
- if err != nil {
83
- return fmt .Errorf ("copying response from image `%s` build failed with :%s" , i .image , err )
72
+ if _ , err = io .Copy (os .Stdout , imageBuildResponse .Body ); err != nil {
73
+ return errorImageBuildResCopy (err )
84
74
}
85
75
86
76
return nil
@@ -90,14 +80,12 @@ func (i *Image) buildImage(ctx context.Context) error {
90
80
func (i * Image ) Pull (ctx context.Context ) (* Image , error ) {
91
81
reader , err := i .client .ImagePull (ctx , i .image , types.ImagePullOptions {})
92
82
if err != nil {
93
- return i , fmt . Errorf ( "pulling image `%s`, failed with %s" , i . image , err )
83
+ return i , errorClientPull ( err )
94
84
}
95
-
96
85
defer reader .Close ()
97
- fileScanner := bufio .NewScanner (reader )
98
86
87
+ fileScanner := bufio .NewScanner (reader )
99
88
fileScanner .Split (bufio .ScanLines )
100
-
101
89
for fileScanner .Scan () {
102
90
var line = fileScanner .Bytes ()
103
91
var status struct {
@@ -108,9 +96,9 @@ func (i *Image) Pull(ctx context.Context) (*Image, error) {
108
96
}
109
97
Id string
110
98
}
111
- err = json . Unmarshal ( line , & status )
112
- if err != nil {
113
- return i , fmt . Errorf ( "unmarshaling status from docker pull on image `%s` failed with: %s" , i . image , err )
99
+
100
+ if err = json . Unmarshal ( line , & status ); err != nil {
101
+ return i , errorImagePullStatus ( err )
114
102
}
115
103
}
116
104
@@ -125,18 +113,17 @@ func (i *Image) Instantiate(ctx context.Context, options ...ContainerOption) (*C
125
113
for _ , opt := range options {
126
114
err := opt (c )
127
115
if err != nil {
128
- return nil , fmt . Errorf ( "running image options for image `%s` failed with: %s" , i .image , err )
116
+ return nil , errorContainerOptions ( i .image , err )
129
117
}
130
118
}
131
119
132
- var mounts []mount.Mount
133
- _volume := mount.Mount {
134
- Type : mount .TypeBind ,
135
- }
136
- for _ , volume := range c .volumes {
137
- _volume .Source = volume .source
138
- _volume .Target = volume .target
139
- mounts = append (mounts , _volume )
120
+ mounts := make ([]mount.Mount , len (c .volumes ))
121
+ for idx , volume := range c .volumes {
122
+ mounts [idx ] = mount.Mount {
123
+ Type : mount .TypeBind ,
124
+ Source : volume .source ,
125
+ Target : volume .target ,
126
+ }
140
127
}
141
128
142
129
config := & container.Config {
@@ -146,14 +133,13 @@ func (i *Image) Instantiate(ctx context.Context, options ...ContainerOption) (*C
146
133
Tty : false ,
147
134
Env : c .env ,
148
135
}
149
-
150
- if len (c .workDir ) != 0 {
136
+ if len (c .workDir ) > 0 {
151
137
config .WorkingDir = c .workDir
152
138
}
153
139
154
140
resp , err := c .image .client .ContainerCreate (ctx , config , & container.HostConfig {Mounts : mounts }, nil , nil , "" )
155
141
if err != nil {
156
- return nil , fmt . Errorf ( "creating container for image `%s` failed with: %s" , c .image .image , err )
142
+ return nil , errorContainerCreate ( c .image .Name () , err )
157
143
}
158
144
c .id = resp .ID
159
145
@@ -162,21 +148,26 @@ func (i *Image) Instantiate(ctx context.Context, options ...ContainerOption) (*C
162
148
163
149
// Clean removes all docker images that match the given filter, and max age.
164
150
func (c * Client ) Clean (ctx context.Context , age time.Duration , filter filters.Args ) error {
165
- images , _ := c .ImageList (context . Background () , types.ImageListOptions {Filters : filter })
151
+ images , _ := c .ImageList (ctx , types.ImageListOptions {Filters : filter })
166
152
timeNow := time .Now ()
153
+
154
+ var err error
167
155
for _ , image := range images {
168
156
if time .Unix (image .Created , 0 ).Add (age ).Before (timeNow ) {
169
- _ , err := c .ImageRemove (ctx , image .ID , types.ImageRemoveOptions {
157
+ if _ , _err := c .ImageRemove (ctx , image .ID , types.ImageRemoveOptions {
170
158
Force : true ,
171
159
PruneChildren : true ,
172
- })
173
- if err != nil {
174
- return fmt .Errorf ("cleaning image `%s` from docker host failed with %s" , image .ID , err )
160
+ }); _err != nil {
161
+ if err != nil {
162
+ err = fmt .Errorf ("%s:%w" , err , _err )
163
+ } else {
164
+ err = _err
165
+ }
175
166
}
176
167
}
177
168
}
178
169
179
- return nil
170
+ return err
180
171
}
181
172
182
173
// Name returns the name of the image
0 commit comments