本文整理汇总了Golang中github.com/openshift/origin/pkg/build/util.IsBuildComplete函数的典型用法代码示例。如果您正苦于以下问题:Golang IsBuildComplete函数的具体用法?Golang IsBuildComplete怎么用?Golang IsBuildComplete使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了IsBuildComplete函数的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: HandlePod
// HandlePod updates the state of the build based on the pod state
func (bc *BuildPodController) HandlePod(pod *kapi.Pod) error {
obj, exists, err := bc.BuildStore.Get(buildKey(pod))
if err != nil {
glog.V(4).Infof("Error getting build for pod %s/%s: %v", pod.Namespace, pod.Name, err)
return err
}
if !exists || obj == nil {
glog.V(5).Infof("No build found for pod %s/%s", pod.Namespace, pod.Name)
return nil
}
build := obj.(*buildapi.Build)
nextStatus := build.Status.Phase
switch pod.Status.Phase {
case kapi.PodRunning:
// The pod's still running
nextStatus = buildapi.BuildPhaseRunning
case kapi.PodSucceeded:
// Check the exit codes of all the containers in the pod
nextStatus = buildapi.BuildPhaseComplete
if len(pod.Status.ContainerStatuses) == 0 {
// no containers in the pod means something went badly wrong, so the build
// should be failed.
glog.V(2).Infof("Failing build %s/%s because the pod has no containers", build.Namespace, build.Name)
nextStatus = buildapi.BuildPhaseFailed
} else {
for _, info := range pod.Status.ContainerStatuses {
if info.State.Terminated != nil && info.State.Terminated.ExitCode != 0 {
nextStatus = buildapi.BuildPhaseFailed
break
}
}
}
case kapi.PodFailed:
nextStatus = buildapi.BuildPhaseFailed
}
if build.Status.Phase != nextStatus && !buildutil.IsBuildComplete(build) {
glog.V(4).Infof("Updating build %s/%s status %s -> %s", build.Namespace, build.Name, build.Status.Phase, nextStatus)
build.Status.Phase = nextStatus
build.Status.Reason = ""
build.Status.Message = ""
if buildutil.IsBuildComplete(build) {
now := unversioned.Now()
build.Status.CompletionTimestamp = &now
}
if build.Status.Phase == buildapi.BuildPhaseRunning {
now := unversioned.Now()
build.Status.StartTimestamp = &now
}
if err := bc.BuildUpdater.Update(build.Namespace, build); err != nil {
return fmt.Errorf("failed to update build %s/%s: %v", build.Namespace, build.Name, err)
}
glog.V(4).Infof("Build %s/%s status was updated %s -> %s", build.Namespace, build.Name, build.Status.Phase, nextStatus)
}
return nil
}
示例2: HandleBuildPodDeletion
// HandleBuildPodDeletion sets the status of a build to error if the build pod has been deleted
func (bc *BuildPodDeleteController) HandleBuildPodDeletion(pod *kapi.Pod) error {
glog.V(4).Infof("Handling deletion of build pod %s/%s", pod.Namespace, pod.Name)
obj, exists, err := bc.BuildStore.Get(buildKey(pod))
if err != nil {
glog.V(4).Infof("Error getting build for pod %s/%s", pod.Namespace, pod.Name)
return err
}
if !exists || obj == nil {
glog.V(5).Infof("No Build found for deleted pod %s/%s", pod.Namespace, pod.Name)
return nil
}
build := obj.(*buildapi.Build)
if buildutil.IsBuildComplete(build) {
glog.V(4).Infof("Pod was deleted but Build %s/%s is already completed, so no need to update it.", build.Namespace, build.Name)
return nil
}
nextStatus := buildapi.BuildPhaseError
if build.Status.Phase != nextStatus {
glog.V(4).Infof("Updating build %s/%s status %s -> %s", build.Namespace, build.Name, build.Status.Phase, nextStatus)
build.Status.Phase = nextStatus
build.Status.Message = "The Pod for this Build was deleted before the Build completed."
now := util.Now()
build.Status.CompletionTimestamp = &now
if err := bc.BuildUpdater.Update(build.Namespace, build); err != nil {
return fmt.Errorf("Failed to update Build %s/%s: %v", build.Namespace, build.Name, err)
}
}
return nil
}
示例3: HandlePod
// HandlePod updates the state of the build based on the pod state
func (bc *BuildPodController) HandlePod(pod *kapi.Pod) error {
obj, exists, err := bc.BuildStore.Get(buildKey(pod))
if err != nil {
glog.V(4).Infof("Error getting Build for pod %s/%s: %v", pod.Namespace, pod.Name, err)
return err
}
if !exists || obj == nil {
glog.V(5).Infof("No Build found for pod %s/%s", pod.Namespace, pod.Name)
return nil
}
build := obj.(*buildapi.Build)
// A cancelling event was triggered for the build, delete its pod and update build status.
if build.Status.Cancelled {
glog.V(4).Infof("Cancelling Build %s/%s.", build.Namespace, build.Name)
if err := bc.CancelBuild(build, pod); err != nil {
return fmt.Errorf("failed to cancel Build %s/%s: %v, will retry", build.Namespace, build.Name, err)
}
return nil
}
nextStatus := build.Status.Phase
switch pod.Status.Phase {
case kapi.PodRunning:
// The pod's still running
nextStatus = buildapi.BuildPhaseRunning
case kapi.PodSucceeded, kapi.PodFailed:
// Check the exit codes of all the containers in the pod
nextStatus = buildapi.BuildPhaseComplete
for _, info := range pod.Status.ContainerStatuses {
if info.State.Terminated != nil && info.State.Terminated.ExitCode != 0 {
nextStatus = buildapi.BuildPhaseFailed
break
}
}
}
if build.Status.Phase != nextStatus {
glog.V(4).Infof("Updating Build %s/%s status %s -> %s", build.Namespace, build.Name, build.Status.Phase, nextStatus)
build.Status.Phase = nextStatus
if buildutil.IsBuildComplete(build) {
now := util.Now()
build.Status.CompletionTimestamp = &now
}
if build.Status.Phase == buildapi.BuildPhaseRunning {
now := util.Now()
build.Status.StartTimestamp = &now
}
if err := bc.BuildUpdater.Update(build.Namespace, build); err != nil {
return fmt.Errorf("failed to update Build %s/%s: %v", build.Namespace, build.Name, err)
}
glog.V(4).Infof("Build %s/%s status was updated %s -> %s", build.Namespace, build.Name, build.Status.Phase, nextStatus)
}
return nil
}
示例4: HandleBuild
// HandleBuild deletes pods for cancelled builds and takes new builds and puts
// them in the pending state after creating a corresponding pod
func (bc *BuildController) HandleBuild(build *buildapi.Build) error {
// these builds are processed/updated/etc by the jenkins sync plugin
if build.Spec.Strategy.JenkinsPipelineStrategy != nil {
glog.V(4).Infof("Ignoring build with jenkins pipeline strategy")
return nil
}
glog.V(4).Infof("Handling build %s/%s (%s)", build.Namespace, build.Name, build.Status.Phase)
runPolicy := policy.ForBuild(build, bc.RunPolicies)
if runPolicy == nil {
return fmt.Errorf("unable to determine build scheduler for %s/%s", build.Namespace, build.Name)
}
if buildutil.IsBuildComplete(build) {
if err := runPolicy.OnComplete(build); err != nil {
return err
}
return nil
}
// A cancelling event was triggered for the build, delete its pod and update build status.
if build.Status.Cancelled && build.Status.Phase != buildapi.BuildPhaseCancelled {
glog.V(5).Infof("Marking build %s/%s as cancelled", build.Namespace, build.Name)
if err := bc.CancelBuild(build); err != nil {
build.Status.Reason = buildapi.StatusReasonCancelBuildFailed
build.Status.Message = buildapi.StatusMessageCancelBuildFailed
if err = bc.BuildUpdater.Update(build.Namespace, build); err != nil {
utilruntime.HandleError(fmt.Errorf("Failed to update build %s/%s: %v", build.Namespace, build.Name, err))
}
return fmt.Errorf("Failed to cancel build %s/%s: %v, will retry", build.Namespace, build.Name, err)
}
}
// Handle only new builds from this point
if build.Status.Phase != buildapi.BuildPhaseNew {
return nil
}
// The runPolicy decides whether to execute this build or not.
if run, err := runPolicy.IsRunnable(build); err != nil || !run {
return err
}
if err := bc.nextBuildPhase(build); err != nil {
return err
}
if err := bc.BuildUpdater.Update(build.Namespace, build); err != nil {
// This is not a retryable error because the build has been created. The worst case
// outcome of not updating the buildconfig is that we might rerun a build for the
// same "new" imageid change in the future, which is better than guaranteeing we
// run the build 2+ times by retrying it here.
glog.V(2).Infof("Failed to record changes to build %s/%s: %v", build.Namespace, build.Name, err)
}
return nil
}
示例5: ValidateBuildUpdate
func ValidateBuildUpdate(build *buildapi.Build, older *buildapi.Build) fielderrors.ValidationErrorList {
allErrs := fielderrors.ValidationErrorList{}
allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(&build.ObjectMeta, &older.ObjectMeta).Prefix("metadata")...)
allErrs = append(allErrs, ValidateBuild(build)...)
if buildutil.IsBuildComplete(older) && older.Status.Phase != build.Status.Phase {
allErrs = append(allErrs, fielderrors.NewFieldInvalid("status.Phase", build.Status.Phase, "phase cannot be updated from a terminal state"))
}
if !kapi.Semantic.DeepEqual(build.Spec, older.Spec) {
allErrs = append(allErrs, fielderrors.NewFieldInvalid("spec", "content of spec is not printed out, please refer to the \"details\"", "spec is immutable"))
}
return allErrs
}
示例6: List
// List lists all Pods associated with a Build.
func (lw *buildPodDeleteLW) List(options kapi.ListOptions) (runtime.Object, error) {
glog.V(5).Info("Checking for deleted build pods")
buildList, err := lw.Client.Builds(kapi.NamespaceAll).List(options)
if err != nil {
glog.V(4).Infof("Failed to find any builds due to error %v", err)
return nil, err
}
for _, build := range buildList.Items {
glog.V(5).Infof("Found build %s/%s", build.Namespace, build.Name)
if buildutil.IsBuildComplete(&build) {
glog.V(5).Infof("Ignoring build %s/%s because it is complete", build.Namespace, build.Name)
continue
}
if build.Spec.Strategy.JenkinsPipelineStrategy != nil {
glog.V(5).Infof("Ignoring build %s/%s because it is a pipeline build", build.Namespace, build.Name)
continue
}
pod, err := lw.KubeClient.Pods(build.Namespace).Get(buildapi.GetBuildPodName(&build))
if err != nil {
if !kerrors.IsNotFound(err) {
glog.V(4).Infof("Error getting pod for build %s/%s: %v", build.Namespace, build.Name, err)
return nil, err
} else {
pod = nil
}
} else {
if buildName := buildapi.GetBuildName(pod); buildName != build.Name {
pod = nil
}
}
if pod == nil {
deletedPod := &kapi.Pod{
ObjectMeta: kapi.ObjectMeta{
Name: buildapi.GetBuildPodName(&build),
Namespace: build.Namespace,
},
}
glog.V(4).Infof("No build pod found for build %s/%s, sending delete event for build pod", build.Namespace, build.Name)
err := lw.store.Delete(deletedPod)
if err != nil {
glog.V(4).Infof("Error queuing delete event: %v", err)
}
} else {
glog.V(5).Infof("Found build pod %s/%s for build %s", pod.Namespace, pod.Name, build.Name)
}
}
return &kapi.PodList{}, nil
}
示例7: HandleBuildPodDeletion
// HandleBuildPodDeletion sets the status of a build to error if the build pod has been deleted
func (bc *BuildPodDeleteController) HandleBuildPodDeletion(pod *kapi.Pod) error {
glog.V(4).Infof("Handling deletion of build pod %s/%s", pod.Namespace, pod.Name)
obj, exists, err := bc.BuildStore.Get(buildKey(pod))
if err != nil {
glog.V(4).Infof("Error getting build for pod %s/%s", pod.Namespace, pod.Name)
return err
}
if !exists || obj == nil {
glog.V(5).Infof("No build found for deleted pod %s/%s", pod.Namespace, pod.Name)
return nil
}
build := obj.(*buildapi.Build)
if build.Spec.Strategy.JenkinsPipelineStrategy != nil {
glog.V(4).Infof("Build %s/%s is a pipeline build, ignoring", build.Namespace, build.Name)
return nil
}
// If build was cancelled, we'll leave HandleBuild to update the build
if build.Status.Cancelled {
glog.V(4).Infof("Cancelation for build %s/%s was already triggered, ignoring", build.Namespace, build.Name)
return nil
}
if buildutil.IsBuildComplete(build) {
glog.V(4).Infof("Pod was deleted but build %s/%s is already completed, so no need to update it.", build.Namespace, build.Name)
return nil
}
nextStatus := buildapi.BuildPhaseError
if build.Status.Phase != nextStatus {
glog.V(4).Infof("Updating build %s/%s status %s -> %s", build.Namespace, build.Name, build.Status.Phase, nextStatus)
build.Status.Phase = nextStatus
build.Status.Reason = buildapi.StatusReasonBuildPodDeleted
build.Status.Message = buildapi.StatusMessageBuildPodDeleted
now := unversioned.Now()
build.Status.CompletionTimestamp = &now
if err := bc.BuildUpdater.Update(build.Namespace, build); err != nil {
return fmt.Errorf("Failed to update build %s/%s: %v", build.Namespace, build.Name, err)
}
}
return nil
}
示例8: cancelPreviousBuilds
// cancelPreviousBuilds cancels all queued builds that have the build sequence number
// lower than the given build. It retries the cancellation in case of conflict.
func (s *SerialLatestOnlyPolicy) cancelPreviousBuilds(build *buildapi.Build) []error {
bcName := buildutil.ConfigNameForBuild(build)
if len(bcName) == 0 {
return []error{}
}
currentBuildNumber, err := buildutil.BuildNumber(build)
if err != nil {
return []error{NewNoBuildNumberAnnotationError(build)}
}
builds, err := buildutil.BuildConfigBuilds(s.BuildLister, build.Namespace, bcName, func(b buildapi.Build) bool {
// Do not cancel the complete builds, builds that were already cancelled, or
// running builds.
if buildutil.IsBuildComplete(&b) || b.Status.Phase == buildapi.BuildPhaseRunning {
return false
}
// Prevent race-condition when there is a newer build than this and we don't
// want to cancel it. The HandleBuild() function that runs for that build
// will cancel this build.
buildNumber, _ := buildutil.BuildNumber(&b)
return buildNumber < currentBuildNumber
})
if err != nil {
return []error{err}
}
var result = []error{}
for _, b := range builds.Items {
err := wait.Poll(500*time.Millisecond, 5*time.Second, func() (bool, error) {
b.Status.Cancelled = true
err := s.BuildUpdater.Update(b.Namespace, &b)
if err != nil && errors.IsConflict(err) {
glog.V(5).Infof("Error cancelling build %s/%s: %v (will retry)", b.Namespace, b.Name, err)
return false, nil
}
return true, err
})
if err != nil {
result = append(result, err)
}
}
return result
}
示例9: ValidateBuildUpdate
func ValidateBuildUpdate(build *buildapi.Build, older *buildapi.Build) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(&build.ObjectMeta, &older.ObjectMeta, field.NewPath("metadata"))...)
allErrs = append(allErrs, ValidateBuild(build)...)
if buildutil.IsBuildComplete(older) && older.Status.Phase != build.Status.Phase {
allErrs = append(allErrs, field.Invalid(field.NewPath("status", "phase"), build.Status.Phase, "phase cannot be updated from a terminal state"))
}
if !kapi.Semantic.DeepEqual(build.Spec, older.Spec) {
diff, err := diffBuildSpec(build.Spec, older.Spec)
if err != nil {
glog.V(2).Infof("Error calculating build spec patch: %v", err)
diff = "[unknown]"
}
detail := fmt.Sprintf("spec is immutable, diff: %s", diff)
allErrs = append(allErrs, field.Invalid(field.NewPath("spec"), "content of spec is not printed out, please refer to the details", detail))
}
return allErrs
}
示例10: List
// List lists all Pods associated with a Build.
func (lw *buildPodDeleteLW) List() (runtime.Object, error) {
glog.V(5).Info("Checking for deleted build pods")
buildList, err := lw.Client.Builds(kapi.NamespaceAll).List(labels.Everything(), fields.Everything())
if err != nil {
glog.V(4).Infof("Failed to find any builds due to error %v", err)
return nil, err
}
for _, build := range buildList.Items {
glog.V(5).Infof("Found build %s/%s", build.Namespace, build.Name)
if buildutil.IsBuildComplete(&build) {
glog.V(5).Infof("Ignoring build %s/%s because it is complete", build.Namespace, build.Name)
continue
}
pod, err := lw.KubeClient.Pods(build.Namespace).Get(buildutil.GetBuildPodName(&build))
if err != nil && !kerrors.IsNotFound(err) {
glog.V(4).Infof("Error getting pod for build %s/%s: %v", build.Namespace, build.Name, err)
return nil, err
}
if (err != nil && kerrors.IsNotFound(err)) || pod.Labels[buildapi.BuildLabel] != build.Name {
pod = nil
}
if pod == nil {
deletedPod := &kapi.Pod{
ObjectMeta: kapi.ObjectMeta{
Name: buildutil.GetBuildPodName(&build),
Namespace: build.Namespace,
},
}
glog.V(4).Infof("No build pod found for build %s/%s, sending delete event for build pod", build.Namespace, build.Name)
err := lw.store.Delete(deletedPod)
if err != nil {
glog.V(4).Infof("Error queuing delete event: %v", err)
}
} else {
glog.V(5).Infof("Found build pod %s/%s for build %s", pod.Namespace, pod.Name, build.Name)
}
}
return &kapi.PodList{}, nil
}
示例11: ictMarker
// ictMarker inspects the image change triggers for the provided deploymentconfig and returns
// a marker in case of the following two scenarios:
//
// 1. The image stream pointed by the dc trigger doen not exist.
// 2. The image stream tag pointed by the dc trigger does not exist and there is no build in
// flight that could push to the tag.
func ictMarker(g osgraph.Graph, f osgraph.Namer, dcNode *deploygraph.DeploymentConfigNode) *osgraph.Marker {
for _, uncastIstNode := range g.PredecessorNodesByEdgeKind(dcNode, deployedges.TriggersDeploymentEdgeKind) {
if istNode := uncastIstNode.(*imagegraph.ImageStreamTagNode); !istNode.Found() {
// The image stream for the tag of interest does not exist.
if isNode, exists := doesImageStreamExist(g, uncastIstNode); !exists {
return &osgraph.Marker{
Node: dcNode,
RelatedNodes: []graph.Node{uncastIstNode, isNode},
Severity: osgraph.ErrorSeverity,
Key: MissingImageStreamErr,
Message: fmt.Sprintf("The image trigger for %s will have no effect because %s does not exist.",
f.ResourceName(dcNode), f.ResourceName(isNode)),
// TODO: Suggest `oc create imagestream` once we have that.
}
}
for _, bcNode := range buildedges.BuildConfigsForTag(g, istNode) {
// Avoid warning for the dc image trigger in case there is a build in flight.
if latestBuild := buildedges.GetLatestBuild(g, bcNode); latestBuild != nil && !buildutil.IsBuildComplete(latestBuild.Build) {
return nil
}
}
// The image stream tag of interest does not exist.
return &osgraph.Marker{
Node: dcNode,
RelatedNodes: []graph.Node{uncastIstNode},
Severity: osgraph.WarningSeverity,
Key: MissingImageStreamTagWarning,
Message: fmt.Sprintf("The image trigger for %s will have no effect until %s is imported or created by a build.",
f.ResourceName(dcNode), f.ResourceName(istNode)),
}
}
}
return nil
}
示例12:
LabelSelector: buildutil.BuildConfigSelector(bcName),
})
defer buildWatch.Stop()
// Start first build
stdout, _, err := exutil.StartBuild(oc, bcName, "-o=name")
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(strings.TrimSpace(stdout)).ShouldNot(o.HaveLen(0))
// extract build name from "build/buildName" resource id
startedBuilds = append(startedBuilds, strings.TrimSpace(strings.Split(stdout, "/")[1]))
// Wait for it to become running
for {
event := <-buildWatch.ResultChan()
build := event.Object.(*buildapi.Build)
o.Expect(buildutil.IsBuildComplete(build)).Should(o.BeFalse())
if build.Name == startedBuilds[0] && build.Status.Phase == buildapi.BuildPhaseRunning {
break
}
}
for i := 0; i < 2; i++ {
stdout, _, err = exutil.StartBuild(oc, bcName, "-o=name")
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(strings.TrimSpace(stdout)).ShouldNot(o.HaveLen(0))
startedBuilds = append(startedBuilds, strings.TrimSpace(strings.Split(stdout, "/")[1]))
}
o.Expect(err).NotTo(o.HaveOccurred())
for {
示例13: HandlePod
// HandlePod updates the state of the build based on the pod state
func (bc *BuildPodController) HandlePod(pod *kapi.Pod) error {
obj, exists, err := bc.BuildStore.Get(buildKey(pod))
if err != nil {
glog.V(4).Infof("Error getting build for pod %s/%s: %v", pod.Namespace, pod.Name, err)
return err
}
if !exists || obj == nil {
glog.V(5).Infof("No build found for pod %s/%s", pod.Namespace, pod.Name)
return nil
}
build := obj.(*buildapi.Build)
nextStatus := build.Status.Phase
currentReason := build.Status.Reason
switch pod.Status.Phase {
case kapi.PodRunning:
// The pod's still running
build.Status.Reason = ""
nextStatus = buildapi.BuildPhaseRunning
case kapi.PodPending:
build.Status.Reason = ""
nextStatus = buildapi.BuildPhasePending
if secret := build.Spec.Output.PushSecret; secret != nil && currentReason != buildapi.StatusReasonMissingPushSecret {
if _, err := bc.SecretClient.Secrets(build.Namespace).Get(secret.Name); err != nil && errors.IsNotFound(err) {
build.Status.Reason = buildapi.StatusReasonMissingPushSecret
glog.V(4).Infof("Setting reason for pending build to %q due to missing secret %s/%s", build.Status.Reason, build.Namespace, secret.Name)
}
}
case kapi.PodSucceeded:
// Check the exit codes of all the containers in the pod
nextStatus = buildapi.BuildPhaseComplete
build.Status.Reason = ""
if len(pod.Status.ContainerStatuses) == 0 {
// no containers in the pod means something went badly wrong, so the build
// should be failed.
glog.V(2).Infof("Failing build %s/%s because the pod has no containers", build.Namespace, build.Name)
nextStatus = buildapi.BuildPhaseFailed
} else {
for _, info := range pod.Status.ContainerStatuses {
if info.State.Terminated != nil && info.State.Terminated.ExitCode != 0 {
nextStatus = buildapi.BuildPhaseFailed
break
}
}
}
case kapi.PodFailed:
build.Status.Reason = ""
nextStatus = buildapi.BuildPhaseFailed
}
// Update the build object when it progress to a next state or the reason for
// the current state changed.
if build.Status.Phase != nextStatus && !buildutil.IsBuildComplete(build) {
reason := ""
if len(build.Status.Reason) > 0 {
reason = " (" + string(build.Status.Reason) + ")"
}
glog.V(4).Infof("Updating build %s/%s status %s -> %s%s", build.Namespace, build.Name, build.Status.Phase, nextStatus, reason)
build.Status.Phase = nextStatus
build.Status.Message = ""
if buildutil.IsBuildComplete(build) {
now := unversioned.Now()
build.Status.CompletionTimestamp = &now
}
if build.Status.Phase == buildapi.BuildPhaseRunning {
now := unversioned.Now()
build.Status.StartTimestamp = &now
}
if err := bc.BuildUpdater.Update(build.Namespace, build); err != nil {
return fmt.Errorf("failed to update build %s/%s: %v", build.Namespace, build.Name, err)
}
glog.V(4).Infof("Build %s/%s status was updated %s -> %s", build.Namespace, build.Name, build.Status.Phase, nextStatus)
}
return nil
}
示例14: RunCancelBuild
// RunCancelBuild implements all the necessary functionality for CancelBuild.
func (o *CancelBuildOptions) RunCancelBuild() error {
var builds []*buildapi.Build
for _, name := range o.BuildNames {
build, err := o.BuildClient.Get(name)
if err != nil {
o.ReportError(fmt.Errorf("build %s/%s not found", o.Namespace, name))
continue
}
stateMatch := false
for _, state := range o.States {
if strings.ToLower(string(build.Status.Phase)) == state {
stateMatch = true
break
}
}
if stateMatch && !buildutil.IsBuildComplete(build) {
builds = append(builds, build)
}
}
if o.DumpLogs {
for _, b := range builds {
// Do not attempt to get logs from build that was not scheduled.
if b.Status.Phase == buildapi.BuildPhaseNew {
continue
}
opts := buildapi.BuildLogOptions{NoWait: true}
response, err := o.Client.BuildLogs(o.Namespace).Get(b.Name, opts).Do().Raw()
if err != nil {
o.ReportError(fmt.Errorf("unable to fetch logs for %s/%s: %v", b.Namespace, b.Name, err))
continue
}
fmt.Fprintf(o.Out, "==== Build %s/%s logs ====\n", b.Namespace, b.Name)
fmt.Fprint(o.Out, string(response))
}
}
var wg sync.WaitGroup
for _, b := range builds {
wg.Add(1)
go func(build *buildapi.Build) {
defer wg.Done()
err := wait.Poll(500*time.Millisecond, 30*time.Second, func() (bool, error) {
build.Status.Cancelled = true
_, err := o.BuildClient.Update(build)
switch {
case err == nil:
return true, nil
case kapierrors.IsConflict(err):
build, err = o.BuildClient.Get(build.Name)
return false, err
}
return true, err
})
if err != nil {
o.ReportError(fmt.Errorf("build %s/%s failed to update: %v", build.Namespace, build.Name, err))
return
}
// Make sure the build phase is really cancelled.
err = wait.Poll(500*time.Millisecond, 30*time.Second, func() (bool, error) {
updatedBuild, err := o.BuildClient.Get(build.Name)
if err != nil {
return true, err
}
return updatedBuild.Status.Phase == buildapi.BuildPhaseCancelled, nil
})
if err != nil {
o.ReportError(fmt.Errorf("build %s/%s failed to cancel: %v", build.Namespace, build.Name, err))
return
}
resource, name, _ := cmdutil.ResolveResource(buildapi.Resource("builds"), build.Name, o.Mapper)
kcmdutil.PrintSuccess(o.Mapper, false, o.Out, resource.Resource, name, "cancelled")
}(b)
}
wg.Wait()
if o.Restart {
for _, b := range builds {
request := &buildapi.BuildRequest{ObjectMeta: kapi.ObjectMeta{Name: b.Name}}
build, err := o.BuildClient.Clone(request)
if err != nil {
o.ReportError(fmt.Errorf("build %s/%s failed to restart: %v", b.Namespace, b.Name, err))
continue
}
resource, name, _ := cmdutil.ResolveResource(buildapi.Resource("builds"), build.Name, o.Mapper)
kcmdutil.PrintSuccess(o.Mapper, false, o.Out, resource.Resource, name, fmt.Sprintf("restarted build %q", b.Name))
}
}
if o.HasError {
return errors.New("failure during the build cancellation")
}
return nil
}