// Clone returns clone of a Build func (g *BuildGenerator) Clone(ctx kapi.Context, request *buildapi.BuildRequest) (*buildapi.Build, error) { glog.V(4).Infof("Generating build from build %s/%s", request.Namespace, request.Name) build, err := g.Client.GetBuild(ctx, request.Name) if err != nil { return nil, err } var buildConfig *buildapi.BuildConfig if build.Status.Config != nil { buildConfig, err = g.Client.GetBuildConfig(ctx, build.Status.Config.Name) if err != nil && !errors.IsNotFound(err) { return nil, err } if buildutil.IsPaused(buildConfig) { return nil, errors.NewInternalError(&GeneratorFatalError{fmt.Sprintf("can't instantiate from BuildConfig %s/%s: BuildConfig is paused", buildConfig.Namespace, buildConfig.Name)}) } } newBuild := generateBuildFromBuild(build, buildConfig) glog.V(4).Infof("Build %s/%s has been generated from Build %s/%s", newBuild.Namespace, newBuild.ObjectMeta.Name, build.Namespace, build.ObjectMeta.Name) // Copy build trigger information to the build object. newBuild.Spec.TriggeredBy = request.TriggeredBy // need to update the BuildConfig because LastVersion changed if buildConfig != nil { if err := g.Client.UpdateBuildConfig(ctx, buildConfig); err != nil { glog.V(4).Infof("Failed to update BuildConfig %s/%s so no Build will be created", buildConfig.Namespace, buildConfig.Name) return nil, err } } return g.createBuild(ctx, newBuild) }
// Instantiate returns a 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, errors.NewBadRequest(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, errors.NewBadRequest(err.Error()) } if err := g.updateImageTriggers(ctx, bc, request.From, request.TriggeredByImage); err != nil { if _, ok := err.(errors.APIStatus); ok { return nil, err } return nil, errors.NewInternalError(err) } newBuild, err := g.generateBuildFromConfig(ctx, bc, request.Revision, request.Binary) if err != nil { if _, ok := err.(errors.APIStatus); ok { return nil, err } return nil, errors.NewInternalError(err) } // Add labels and annotations from the buildrequest. Existing // label/annotations will take precedence because we don't want system // annotations/labels (eg buildname) to get stomped on. newBuild.Annotations = policy.MergeMaps(request.Annotations, newBuild.Annotations) newBuild.Labels = policy.MergeMaps(request.Labels, newBuild.Labels) // Copy build trigger information to the build object. newBuild.Spec.TriggeredBy = request.TriggeredBy 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) }
// 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) }