// CancelBuild updates a build status to Cancelled, after its associated pod is deleted. func (bc *BuildPodController) CancelBuild(build *buildapi.Build, pod *kapi.Pod) error { if !isBuildCancellable(build) { glog.V(4).Infof("Build %s/%s can be cancelled only if it has pending/running status, not %s.", build.Namespace, build.Name, build.Status) return nil } err := bc.PodManager.DeletePod(build.Namespace, pod) if err != nil && !errors.IsNotFound(err) { return err } glog.V(4).Infof("Build %s/%s is about to be cancelled", build.Namespace, build.Name) build.Status = buildapi.BuildStatusCancelled now := util.Now() build.CompletionTimestamp = &now if err := bc.BuildUpdater.Update(build.Namespace, build); err != nil { return err } glog.V(4).Infof("Build %s/%s was successfully cancelled.", build.Namespace, build.Name) return nil }
func withStatus(build *buildapi.Build, status buildapi.BuildStatus) *buildapi.Build { build.Status = status return build }
// nextBuildStatus updates build with any appropriate changes, or returns an error if // the change cannot occur. When returning nil, be sure to set build.Status and optionally // build.Message. func (bc *BuildController) nextBuildStatus(build *buildapi.Build) error { // If a cancelling event was triggered for the build, update build status. if build.Cancelled { glog.V(4).Infof("Cancelling Build %s/%s.", build.Namespace, build.Name) build.Status = buildapi.BuildStatusCancelled return nil } // lookup the destination from the referenced image repository spec := build.Parameters.Output.DockerImageReference if ref := build.Parameters.Output.To; ref != nil { // TODO: security, ensure that the reference image stream is actually visible namespace := ref.Namespace if len(namespace) == 0 { namespace = build.Namespace } repo, err := bc.ImageStreamClient.GetImageStream(namespace, ref.Name) if err != nil { if errors.IsNotFound(err) { return fmt.Errorf("the referenced output ImageStream %s/%s does not exist", namespace, ref.Name) } return fmt.Errorf("the referenced output ImageStream %s/%s could not be found by Build %s/%s: %v", namespace, ref.Name, build.Namespace, build.Name, err) } if len(repo.Status.DockerImageRepository) == 0 { e := fmt.Errorf("the ImageStream %s/%s cannot be used as the output for Build %s/%s because the integrated Docker registry is not configured, or the user forgot to set a valid external registry", namespace, ref.Name, build.Namespace, build.Name) bc.Recorder.Eventf(build, "invalidOutput", "Error starting build: %v", e) return e } spec = repo.Status.DockerImageRepository } // set the expected build parameters, which will be saved if no error occurs build.Status = buildapi.BuildStatusPending // Make a copy to avoid mutating the build from this point on copy, err := kapi.Scheme.Copy(build) if err != nil { return fmt.Errorf("unable to copy Build: %v", err) } buildCopy := copy.(*buildapi.Build) // override DockerImageReference in the strategy for the copy we send to the build pod buildCopy.Parameters.Output.DockerImageReference = spec buildCopy.Parameters.Output.To = nil // invoke the strategy to get a build pod podSpec, err := bc.BuildStrategy.CreateBuildPod(buildCopy) if err != nil { return fmt.Errorf("the strategy failed to create a build pod for Build %s/%s: %v", build.Namespace, build.Name, err) } glog.V(4).Infof("Pod %s for Build %s/%s is about to be created", podSpec.Name, build.Namespace, build.Name) if _, err := bc.PodManager.CreatePod(build.Namespace, podSpec); err != nil { if errors.IsAlreadyExists(err) { glog.V(4).Infof("Build pod already existed: %#v", podSpec) return nil } // log an event if the pod is not created (most likely due to quota denial) bc.Recorder.Eventf(build, "failedCreate", "Error creating: %v", err) return fmt.Errorf("failed to create pod for Build %s/%s: %v", build.Namespace, build.Name, err) } glog.V(4).Infof("Created pod for Build: %#v", podSpec) return nil }