Skip to content

Commit

Permalink
support multi tags in build image
Browse files Browse the repository at this point in the history
  • Loading branch information
CMGS committed Aug 8, 2018
1 parent 8a7b027 commit 16abeb5
Show file tree
Hide file tree
Showing 8 changed files with 334 additions and 324 deletions.
102 changes: 56 additions & 46 deletions cluster/calcium/build_image.go
Expand Up @@ -182,7 +182,11 @@ func (c *Calcium) BuildImage(ctx context.Context, opts *types.BuildOptions) (cha
}

// tag of image, later this will be used to push image to hub
tag := createImageTag(c.config.Docker, opts.Name, opts.Tag)
tags := []string{}
for i := range opts.Tags {
tag := createImageTag(c.config.Docker, opts.Name, opts.Tags[i])
tags = append(tags, tag)
}

// create tar stream for Build API
buildContext, err := createTarStream(buildDir)
Expand All @@ -192,15 +196,15 @@ func (c *Calcium) BuildImage(ctx context.Context, opts *types.BuildOptions) (cha

// must be put here because of that `defer os.RemoveAll(buildDir)`
buildOptions := enginetypes.ImageBuildOptions{
Tags: []string{tag},
Tags: tags,
SuppressOutput: false,
NoCache: true,
Remove: true,
ForceRemove: true,
PullParent: true,
}

log.Infof("[BuildImage] Building image %v at %v:%v", tag, buildPodname, node.Name)
log.Infof("[BuildImage] Building image %v:%v", buildPodname, node.Name)
resp, err := node.Engine.ImageBuild(ctx, buildContext, buildOptions)
if err != nil {
return ch, err
Expand All @@ -210,7 +214,6 @@ func (c *Calcium) BuildImage(ctx context.Context, opts *types.BuildOptions) (cha
defer resp.Body.Close()
defer close(ch)
decoder := json.NewDecoder(resp.Body)
var err error
var lastMessage *types.BuildImageMessage
for {
message := &types.BuildImageMessage{}
Expand All @@ -237,56 +240,63 @@ func (c *Calcium) BuildImage(ctx context.Context, opts *types.BuildOptions) (cha
log.Errorf("[BuildImage] Build image failed %v", lastMessage.ErrorDetail.Message)
return
}
encodedAuth, err := makeEncodedAuthConfigFromRemote(c.config.Docker.AuthConfigs, tag)
if err != nil {
ch <- makeErrorBuildImageMessage(err)
return
}
pushOptions := enginetypes.ImagePushOptions{RegistryAuth: encodedAuth}
rc, err := node.Engine.ImagePush(ctx, tag, pushOptions)
if err != nil {
ch <- makeErrorBuildImageMessage(err)
return
}

defer rc.Close()
decoder2 := json.NewDecoder(rc)
for {
message := &types.BuildImageMessage{}
err := decoder2.Decode(message)
// push and clean
for i := range tags {
tag := tags[i]
log.Infof("[BuildImage] Push image %s", tag)
encodedAuth, err := makeEncodedAuthConfigFromRemote(c.config.Docker.AuthConfigs, tag)
if err != nil {
if err == io.EOF {
break
}
malformed := []byte{}
_, _ = decoder2.Buffered().Read(malformed)
log.Errorf("[BuildImage] Decode push image message failed %v, buffered: %v", err, malformed)
return
ch <- makeErrorBuildImageMessage(err)
continue
}
ch <- message
}
pushOptions := enginetypes.ImagePushOptions{RegistryAuth: encodedAuth}

// 无论如何都删掉build机器的
// 事实上他不会跟cached pod一样
// 一样就砍死
go func() {
//CONTEXT 这里的不应该受到 client 的影响
ctx := context.Background()
_, err := node.Engine.ImageRemove(ctx, tag, enginetypes.ImageRemoveOptions{
Force: false,
PruneChildren: true,
})
rc, err := node.Engine.ImagePush(ctx, tag, pushOptions)
if err != nil {
log.Errorf("[BuildImage] Remove image error: %s", err)
ch <- makeErrorBuildImageMessage(err)
continue
}
r, err := node.Engine.BuildCachePrune(ctx)
if err != nil {
log.Errorf("[BuildImage] Remove build image cache error: %s", err)

defer rc.Close()
decoder2 := json.NewDecoder(rc)
for {
message := &types.BuildImageMessage{}
err := decoder2.Decode(message)
if err != nil {
if err == io.EOF {
break
}
malformed := []byte{}
_, _ = decoder2.Buffered().Read(malformed)
log.Errorf("[BuildImage] Decode push image message failed %v, buffered: %v", err, malformed)
break
}
ch <- message
}
log.Debugf("[BuildImage] Clean cached image and release space %d", r.SpaceReclaimed)
}()

ch <- &types.BuildImageMessage{Stream: fmt.Sprintf("finished %s\n", tag), Status: "finished", Progress: tag}
// 无论如何都删掉build机器的
// 事实上他不会跟cached pod一样
// 一样就砍死
go func(tag string) {
//CONTEXT 这里的不应该受到 client 的影响
ctx := context.Background()
_, err := node.Engine.ImageRemove(ctx, tag, enginetypes.ImageRemoveOptions{
Force: false,
PruneChildren: true,
})
if err != nil {
log.Errorf("[BuildImage] Remove image error: %s", err)
}
r, err := node.Engine.BuildCachePrune(ctx)
if err != nil {
log.Errorf("[BuildImage] Remove build image cache error: %s", err)
}
log.Debugf("[BuildImage] Clean cached image and release space %d", r.SpaceReclaimed)
}(tag)

ch <- &types.BuildImageMessage{Stream: fmt.Sprintf("finished %s\n", tag), Status: "finished", Progress: tag}
}
}()

return ch, nil
Expand Down
4 changes: 2 additions & 2 deletions cluster/calcium/build_image_test.go
Expand Up @@ -20,7 +20,7 @@ func TestBuildDockerFile(t *testing.T) {
Name: appname,
User: "username",
UID: 999,
Tag: "tag",
Tags: []string{"tag"},
Builds: mockBuilds,
}

Expand All @@ -41,7 +41,7 @@ func TestBuildImageError(t *testing.T) {
Name: "appname",
User: "username",
UID: 998,
Tag: "tag",
Tags: []string{"tag"},
Builds: mockBuilds,
}
_, err := mockc.BuildImage(ctx, opts)
Expand Down

0 comments on commit 16abeb5

Please sign in to comment.