mirror of
https://gitee.com/rainbond/Rainbond.git
synced 2024-12-03 20:27:46 +08:00
112 lines
4.0 KiB
Go
112 lines
4.0 KiB
Go
// RAINBOND, Application Management Platform
|
|
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version. For any non-GPL usage of Rainbond,
|
|
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
|
|
// must be obtained first.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
package build
|
|
|
|
import (
|
|
"fmt"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
"github.com/docker/docker/api/types"
|
|
"github.com/goodrain/rainbond/builder"
|
|
"github.com/goodrain/rainbond/builder/sources"
|
|
"github.com/goodrain/rainbond/util"
|
|
)
|
|
|
|
func dockerfileBuilder() (Build, error) {
|
|
return &dockerfileBuild{}, nil
|
|
}
|
|
|
|
type dockerfileBuild struct {
|
|
}
|
|
|
|
func (d *dockerfileBuild) Build(re *Request) (*Response, error) {
|
|
filepath := path.Join(re.SourceDir, "Dockerfile")
|
|
re.Logger.Info("Start parse Dockerfile", map[string]string{"step": "builder-exector"})
|
|
_, err := sources.ParseFile(filepath)
|
|
if err != nil {
|
|
logrus.Error("parse dockerfile error.", err.Error())
|
|
re.Logger.Error(fmt.Sprintf("Parse dockerfile error"), map[string]string{"step": "builder-exector"})
|
|
return nil, err
|
|
}
|
|
buildImageName := CreateImageName(re.RepositoryURL, re.ServiceAlias, re.DeployVersion)
|
|
|
|
buildOptions := types.ImageBuildOptions{
|
|
Tags: []string{buildImageName},
|
|
Remove: true,
|
|
BuildArgs: GetARGs(re.BuildEnvs),
|
|
}
|
|
if _, ok := re.BuildEnvs["NO_CACHE"]; ok {
|
|
buildOptions.NoCache = true
|
|
} else {
|
|
buildOptions.NoCache = false
|
|
}
|
|
re.Logger.Info("Start build image from dockerfile", map[string]string{"step": "builder-exector"})
|
|
err = sources.ImageBuild(re.DockerClient, re.SourceDir, buildOptions, re.Logger, 30)
|
|
if err != nil {
|
|
re.Logger.Error(fmt.Sprintf("build image %s failure", buildImageName), map[string]string{"step": "builder-exector", "status": "failure"})
|
|
logrus.Errorf("build image error: %s", err.Error())
|
|
return nil, err
|
|
}
|
|
// check image exist
|
|
_, err = sources.ImageInspectWithRaw(re.DockerClient, buildImageName)
|
|
if err != nil {
|
|
re.Logger.Error(fmt.Sprintf("Build image %s failure,view build logs", buildImageName), map[string]string{"step": "builder-exector", "status": "failure"})
|
|
logrus.Errorf("get image inspect error: %s", err.Error())
|
|
return nil, err
|
|
}
|
|
re.Logger.Info("The image build is successful and starts pushing the image to the repository", map[string]string{"step": "builder-exector"})
|
|
err = sources.ImagePush(re.DockerClient, buildImageName, builder.REGISTRYUSER, builder.REGISTRYPASS, re.Logger, 20)
|
|
if err != nil {
|
|
re.Logger.Error("Push image failure", map[string]string{"step": "builder-exector"})
|
|
logrus.Errorf("push image error: %s", err.Error())
|
|
return nil, err
|
|
}
|
|
re.Logger.Info("The image is pushed to the warehouse successfully", map[string]string{"step": "builder-exector"})
|
|
if err := sources.ImageRemove(re.DockerClient, buildImageName); err != nil {
|
|
logrus.Errorf("remove image %s failure %s", buildImageName, err.Error())
|
|
}
|
|
return &Response{
|
|
MediumPath: buildImageName,
|
|
MediumType: ImageMediumType,
|
|
}, nil
|
|
}
|
|
|
|
//GetARGs get args and parse value
|
|
func GetARGs(buildEnvs map[string]string) map[string]*string {
|
|
args := make(map[string]*string)
|
|
argStr := make(map[string]string)
|
|
for k, v := range buildEnvs {
|
|
if strings.Replace(v, " ", "", -1) == "" {
|
|
continue
|
|
}
|
|
if ks := strings.Split(k, "ARG_"); len(ks) > 1 {
|
|
value := v
|
|
args[ks[1]] = &value
|
|
argStr[ks[1]] = value
|
|
}
|
|
}
|
|
for k, arg := range args {
|
|
value := util.ParseVariable(*arg, argStr)
|
|
args[k] = &value
|
|
}
|
|
return args
|
|
}
|