// Instantiate returns new Build object based on a BuildRequest object
func (g *BuildGenerator) Instantiate(ctx kapi.Context, request *buildapi.BuildRequest) (*buildapi.Build, error) {
glog.V(4).Infof("Generating Build from %s", describeBuildRequest(request))
bc, err := g.Client.GetBuildConfig(ctx, request.Name)
if err != nil {
return nil, err
}
if buildutil.IsPaused(bc) {
return nil, &GeneratorFatalError{fmt.Sprintf("can't instantiate from BuildConfig %s/%s: BuildConfig is paused", bc.Namespace, bc.Name)}
}
if err := g.checkLastVersion(bc, request.LastVersion); err != nil {
return nil, err
}
if err := g.updateImageTriggers(ctx, bc, request.From, request.TriggeredByImage); err != nil {
return nil, err
}
newBuild, err := g.generateBuildFromConfig(ctx, bc, request.Revision, request.Binary)
if err != nil {
return nil, err
}
if len(request.Env) > 0 {
updateBuildEnv(&newBuild.Spec.Strategy, request.Env)
}
glog.V(4).Infof("Build %s/%s has been generated from %s/%s BuildConfig", newBuild.Namespace, newBuild.ObjectMeta.Name, bc.Namespace, bc.ObjectMeta.Name)
// need to update the BuildConfig because LastVersion and possibly LastTriggeredImageID changed
if err := g.Client.UpdateBuildConfig(ctx, bc); err != nil {
glog.V(4).Infof("Failed to update BuildConfig %s/%s so no Build will be created", bc.Namespace, bc.Name)
return nil, err
}
// Ideally we would create the build *before* updating the BC to ensure that we don't set the LastTriggeredImageID
// on the BC and then fail to create the corresponding build, however doing things in that order allows for a race
// condition in which two builds get kicked off. Doing it in this order ensures that we catch the race while
// updating the BC.
return g.createBuild(ctx, newBuild)
}
请发表评论