// Get returns a streamer resource with the contents of the build log func (r *REST) Get(ctx kapi.Context, name string, opts runtime.Object) (runtime.Object, error) { buildLogOpts, ok := opts.(*api.BuildLogOptions) if !ok { return nil, errors.NewBadRequest("did not get an expected options.") } obj, err := r.Getter.Get(ctx, name) if err != nil { return nil, err } build := obj.(*api.Build) switch build.Status.Phase { // Build has not launched, wait til it runs case api.BuildPhaseNew, api.BuildPhasePending: if buildLogOpts.NoWait { glog.V(4).Infof("Build %s/%s is in %s state. No logs to retrieve yet.", build.Namespace, name, build.Status.Phase) // return empty content if not waiting for build return &genericrest.LocationStreamer{}, nil } glog.V(4).Infof("Build %s/%s is in %s state, waiting for Build to start", build.Namespace, name, build.Status.Phase) latest, ok, err := registry.WaitForRunningBuild(r.Watcher, ctx, build, r.Timeout) if err != nil { return nil, errors.NewBadRequest(fmt.Sprintf("unable to wait for build %s to run: %v", name, err)) } switch latest.Status.Phase { case api.BuildPhaseError: return nil, errors.NewBadRequest(fmt.Sprintf("build %s encountered an error: %s", name, buildutil.NoBuildLogsMessage)) case api.BuildPhaseCancelled: return nil, errors.NewBadRequest(fmt.Sprintf("build %s was cancelled: %s", name, buildutil.NoBuildLogsMessage)) } if !ok { return nil, errors.NewTimeoutError(fmt.Sprintf("timed out waiting for build %s to start after %s", build.Name, r.Timeout), 1) } // The build was cancelled case api.BuildPhaseCancelled: return nil, errors.NewBadRequest(fmt.Sprintf("build %s was cancelled. %s", name, buildutil.NoBuildLogsMessage)) // An error occurred launching the build, return an error case api.BuildPhaseError: return nil, errors.NewBadRequest(fmt.Sprintf("build %s is in an error state. %s", name, buildutil.NoBuildLogsMessage)) } // The container should be the default build container, so setting it to blank buildPodName := buildutil.GetBuildPodName(build) logOpts := &kapi.PodLogOptions{ Follow: buildLogOpts.Follow, } location, transport, err := pod.LogLocation(r.PodGetter, r.ConnectionInfo, ctx, buildPodName, logOpts) if err != nil { if errors.IsNotFound(err) { return nil, errors.NewNotFound("pod", buildPodName) } return nil, errors.NewBadRequest(err.Error()) } return &genericrest.LocationStreamer{ Location: location, Transport: transport, ContentType: "text/plain", Flush: buildLogOpts.Follow, }, nil }
func (h *binaryInstantiateHandler) handle(r io.Reader) (runtime.Object, error) { h.options.Name = h.name if err := rest.BeforeCreate(BinaryStrategy, h.ctx, h.options); err != nil { glog.Infof("failed to validate binary: %#v", h.options) return nil, err } request := &buildapi.BuildRequest{} request.Name = h.name if len(h.options.Commit) > 0 { request.Revision = &buildapi.SourceRevision{ Git: &buildapi.GitSourceRevision{ Committer: buildapi.SourceControlUser{ Name: h.options.CommitterName, Email: h.options.CommitterEmail, }, Author: buildapi.SourceControlUser{ Name: h.options.AuthorName, Email: h.options.AuthorEmail, }, Message: h.options.Message, Commit: h.options.Commit, }, } } request.Binary = &buildapi.BinaryBuildSource{ AsFile: h.options.AsFile, } build, err := h.r.Generator.Instantiate(h.ctx, request) if err != nil { glog.Infof("failed to instantiate: %#v", request) return nil, err } latest, ok, err := registry.WaitForRunningBuild(h.r.Watcher, h.ctx, build, h.r.Timeout) if err != nil { switch latest.Status.Phase { case buildapi.BuildPhaseError: return nil, errors.NewBadRequest(fmt.Sprintf("build %s encountered an error: %s", build.Name, buildutil.NoBuildLogsMessage)) case buildapi.BuildPhaseCancelled: return nil, errors.NewBadRequest(fmt.Sprintf("build %s was cancelled: %s", build.Name, buildutil.NoBuildLogsMessage)) } return nil, errors.NewBadRequest(fmt.Sprintf("unable to wait for build %s to run: %v", build.Name, err)) } if !ok { return nil, errors.NewTimeoutError(fmt.Sprintf("timed out waiting for build %s to start after %s", build.Name, h.r.Timeout), 0) } if latest.Status.Phase != buildapi.BuildPhaseRunning { return nil, errors.NewBadRequest(fmt.Sprintf("build %s is no longer running, cannot upload file: %s", build.Name, build.Status.Phase)) } // The container should be the default build container, so setting it to blank buildPodName := buildutil.GetBuildPodName(build) opts := &kapi.PodAttachOptions{ Stdin: true, } location, transport, err := pod.AttachLocation(h.r.PodGetter, h.r.ConnectionInfo, h.ctx, buildPodName, opts) if err != nil { if errors.IsNotFound(err) { return nil, errors.NewNotFound(kapi.Resource("pod"), buildPodName) } return nil, errors.NewBadRequest(err.Error()) } rawTransport, ok := transport.(*http.Transport) if !ok { return nil, errors.NewInternalError(fmt.Errorf("unable to connect to node, unrecognized type: %v", reflect.TypeOf(transport))) } upgrader := spdy.NewRoundTripper(rawTransport.TLSClientConfig) exec, err := remotecommand.NewStreamExecutor(upgrader, nil, "POST", location) if err != nil { return nil, errors.NewInternalError(fmt.Errorf("unable to connect to server: %v", err)) } if err := exec.Stream(r, nil, nil, false); err != nil { return nil, errors.NewInternalError(err) } return latest, nil }