@@ -3,62 +3,65 @@ package calcium
3
3
import (
4
4
"context"
5
5
"encoding/json"
6
- "errors"
7
6
"fmt"
8
7
"io"
9
8
"io/ioutil"
10
9
"os"
11
10
"time"
12
11
12
+ "github.com/pkg/errors"
13
13
enginetypes "github.com/projecteru2/core/engine/types"
14
14
"github.com/projecteru2/core/log"
15
15
"github.com/projecteru2/core/types"
16
16
)
17
17
18
18
// BuildImage will build image
19
- func (c * Calcium ) BuildImage (ctx context.Context , opts * types.BuildOptions ) (chan * types.BuildImageMessage , error ) {
19
+ func (c * Calcium ) BuildImage (ctx context.Context , opts * types.BuildOptions ) (ch chan * types.BuildImageMessage , err error ) {
20
+ logger := log .WithField ("Calcium" , "BuildImage" ).WithField ("opts" , opts )
20
21
// Disable build API if scm not set
21
22
if c .source == nil {
22
- return nil , types .ErrSCMNotSet
23
+ return nil , logger . Err ( errors . WithStack ( types .ErrSCMNotSet ))
23
24
}
24
25
// select nodes
25
26
node , err := c .selectBuildNode (ctx )
26
27
if err != nil {
27
- return nil , err
28
+ return nil , logger . Err ( errors . WithStack ( err ))
28
29
}
29
30
log .Infof ("[BuildImage] Building image at pod %s node %s" , node .Podname , node .Name )
30
31
// get refs
31
32
refs := node .Engine .BuildRefs (ctx , opts .Name , opts .Tags )
32
33
33
34
switch opts .BuildMethod {
34
35
case types .BuildFromSCM :
35
- return c .buildFromSCM (ctx , node , refs , opts )
36
+ ch , err = c .buildFromSCM (ctx , node , refs , opts )
36
37
case types .BuildFromRaw :
37
- return c .buildFromContent (ctx , node , refs , opts .Tar )
38
+ ch , err = c .buildFromContent (ctx , node , refs , opts .Tar )
38
39
case types .BuildFromExist :
39
- return c .buildFromExist (ctx , refs [0 ], opts .ExistID )
40
+ ch , err = c .buildFromExist (ctx , refs [0 ], opts .ExistID )
40
41
default :
41
- return nil , errors .New ("unknown build type" )
42
+ return nil , logger . Err ( errors .WithStack ( errors . New ("unknown build type" )) )
42
43
}
44
+ return ch , logger .Err (errors .WithStack (err ))
43
45
}
44
46
45
47
func (c * Calcium ) selectBuildNode (ctx context.Context ) (* types.Node , error ) {
46
48
// get pod from config
47
49
// TODO can choose multiple pod here for other engine support
48
50
if c .config .Docker .BuildPod == "" {
49
- return nil , types .ErrNoBuildPod
51
+ return nil , errors . WithStack ( types .ErrNoBuildPod )
50
52
}
51
53
52
54
// get node by scheduler
53
55
nodes , err := c .ListPodNodes (ctx , c .config .Docker .BuildPod , nil , false )
54
56
if err != nil {
55
- return nil , err
57
+ return nil , errors . WithStack ( err )
56
58
}
57
59
if len (nodes ) == 0 {
58
- return nil , types .ErrInsufficientNodes
60
+ return nil , errors . WithStack ( types .ErrInsufficientNodes )
59
61
}
60
62
// get idle max node
61
- return c .scheduler .MaxIdleNode (nodes )
63
+ node , err := c .scheduler .MaxIdleNode (nodes )
64
+ return node , errors .WithStack (err )
62
65
}
63
66
64
67
func (c * Calcium ) buildFromSCM (ctx context.Context , node * types.Node , refs []string , opts * types.BuildOptions ) (chan * types.BuildImageMessage , error ) {
@@ -70,30 +73,33 @@ func (c *Calcium) buildFromSCM(ctx context.Context, node *types.Node, refs []str
70
73
path , content , err := node .Engine .BuildContent (ctx , c .source , buildContentOpts )
71
74
defer os .RemoveAll (path )
72
75
if err != nil {
73
- return nil , err
76
+ return nil , errors . WithStack ( err )
74
77
}
75
- return c .buildFromContent (ctx , node , refs , content )
78
+ ch , err := c .buildFromContent (ctx , node , refs , content )
79
+ return ch , errors .WithStack (err )
76
80
}
77
81
78
82
func (c * Calcium ) buildFromContent (ctx context.Context , node * types.Node , refs []string , content io.Reader ) (chan * types.BuildImageMessage , error ) {
79
83
resp , err := node .Engine .ImageBuild (ctx , content , refs )
80
84
if err != nil {
81
- return nil , err
85
+ return nil , errors . WithStack ( err )
82
86
}
83
- return c .pushImage (ctx , resp , node , refs )
87
+ ch , err := c .pushImage (ctx , resp , node , refs )
88
+ return ch , errors .WithStack (err )
84
89
}
85
90
86
91
func (c * Calcium ) buildFromExist (ctx context.Context , ref , existID string ) (chan * types.BuildImageMessage , error ) {
92
+ logger := log .WithField ("Calcium" , "buildFromExist" ).WithField ("ref" , ref ).WithField ("existID" , existID )
87
93
return withImageBuiltChannel (func (ch chan * types.BuildImageMessage ) {
88
94
node , err := c .getWorkloadNode (ctx , existID )
89
95
if err != nil {
90
- ch <- buildErrMsg (err )
96
+ ch <- buildErrMsg (logger . Err ( err ) )
91
97
return
92
98
}
93
99
94
100
imageID , err := node .Engine .ImageBuildFromExist (ctx , existID , ref )
95
101
if err != nil {
96
- ch <- buildErrMsg (err )
102
+ ch <- buildErrMsg (logger . Err ( err ) )
97
103
return
98
104
}
99
105
go cleanupNodeImages (node , []string {imageID }, c .config .GlobalTimeout )
@@ -102,6 +108,7 @@ func (c *Calcium) buildFromExist(ctx context.Context, ref, existID string) (chan
102
108
}
103
109
104
110
func (c * Calcium ) pushImage (ctx context.Context , resp io.ReadCloser , node * types.Node , tags []string ) (chan * types.BuildImageMessage , error ) {
111
+ logger := log .WithField ("Calcium" , "pushImage" ).WithField ("node" , node ).WithField ("tags" , tags )
105
112
return withImageBuiltChannel (func (ch chan * types.BuildImageMessage ) {
106
113
defer resp .Close ()
107
114
decoder := json .NewDecoder (resp )
@@ -119,7 +126,7 @@ func (c *Calcium) pushImage(ctx context.Context, resp io.ReadCloser, node *types
119
126
break
120
127
}
121
128
malformed , _ := ioutil .ReadAll (decoder .Buffered ()) // TODO err check
122
- log .Errorf ("[BuildImage] Decode build image message failed %v, buffered: %v" , err , malformed )
129
+ logger .Errorf ("[BuildImage] Decode build image message failed %+ v, buffered: %v" , err , malformed )
123
130
return
124
131
}
125
132
ch <- message
@@ -137,7 +144,7 @@ func (c *Calcium) pushImage(ctx context.Context, resp io.ReadCloser, node *types
137
144
log .Infof ("[BuildImage] Push image %s" , tag )
138
145
rc , err := node .Engine .ImagePush (ctx , tag )
139
146
if err != nil {
140
- ch <- & types.BuildImageMessage {Error : err .Error ()}
147
+ ch <- & types.BuildImageMessage {Error : logger . Err ( err ) .Error ()}
141
148
continue
142
149
}
143
150
@@ -165,15 +172,16 @@ func withImageBuiltChannel(f func(chan *types.BuildImageMessage)) chan *types.Bu
165
172
}
166
173
167
174
func cleanupNodeImages (node * types.Node , ids []string , ttl time.Duration ) {
175
+ logger := log .WithField ("Calcium" , "cleanupNodeImages" ).WithField ("node" , node ).WithField ("ids" , ids ).WithField ("ttl" , ttl )
168
176
ctx , cancel := context .WithTimeout (context .Background (), ttl )
169
177
defer cancel ()
170
178
for _ , id := range ids {
171
179
if _ , err := node .Engine .ImageRemove (ctx , id , false , true ); err != nil {
172
- log .Errorf ("[BuildImage] Remove image error: %s" , err )
180
+ logger .Errorf ("[BuildImage] Remove image error: %s" , errors . WithStack ( err ) )
173
181
}
174
182
}
175
183
if spaceReclaimed , err := node .Engine .ImageBuildCachePrune (ctx , true ); err != nil {
176
- log .Errorf ("[BuildImage] Remove build image cache error: %s" , err )
184
+ logger .Errorf ("[BuildImage] Remove build image cache error: %s" , errors . WithStack ( err ) )
177
185
} else {
178
186
log .Infof ("[BuildImage] Clean cached image and release space %d" , spaceReclaimed )
179
187
}
0 commit comments