github.com/wanddynosios/cli/v8@v8.7.9-0.20240221182337-1a92e3a7017f/actor/v7action/build.go (about) 1 package v7action 2 3 import ( 4 "errors" 5 "strings" 6 "time" 7 8 "code.cloudfoundry.org/cli/actor/actionerror" 9 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 11 "code.cloudfoundry.org/cli/resources" 12 13 log "github.com/sirupsen/logrus" 14 ) 15 16 func (actor Actor) StagePackage(packageGUID, appName, spaceGUID string) (<-chan resources.Droplet, <-chan Warnings, <-chan error) { 17 dropletStream := make(chan resources.Droplet) 18 warningsStream := make(chan Warnings) 19 errorStream := make(chan error) 20 go func() { 21 defer close(dropletStream) 22 defer close(warningsStream) 23 defer close(errorStream) 24 25 apps, warnings, err := actor.GetApplicationsByNamesAndSpace([]string{appName}, spaceGUID) 26 warningsStream <- warnings 27 if err != nil { 28 if _, ok := err.(actionerror.ApplicationsNotFoundError); ok { 29 err = actionerror.ApplicationNotFoundError{Name: appName} 30 } 31 errorStream <- err 32 return 33 } 34 app := apps[0] 35 36 pkgs, allWarnings, err := actor.CloudControllerClient.GetPackages( 37 ccv3.Query{Key: ccv3.GUIDFilter, Values: []string{packageGUID}}, 38 ccv3.Query{Key: ccv3.AppGUIDFilter, Values: []string{app.GUID}}, 39 ccv3.Query{Key: ccv3.PerPage, Values: []string{"1"}}, 40 ccv3.Query{Key: ccv3.Page, Values: []string{"1"}}, 41 ) 42 warningsStream <- Warnings(allWarnings) 43 if err != nil { 44 errorStream <- err 45 return 46 } 47 48 if len(pkgs) == 0 { 49 err = actionerror.PackageNotFoundInAppError{GUID: packageGUID, AppName: appName} 50 errorStream <- err 51 return 52 } 53 54 build := resources.Build{PackageGUID: packageGUID} 55 build, allWarnings, err = actor.CloudControllerClient.CreateBuild(build) 56 warningsStream <- Warnings(allWarnings) 57 58 if err != nil { 59 errorStream <- err 60 return 61 } 62 63 timer := actor.Clock.NewTimer(time.Millisecond) 64 defer timer.Stop() 65 timeout := actor.Clock.After(actor.Config.StagingTimeout()) 66 67 for { 68 select { 69 case <-timeout: 70 errorStream <- actionerror.StagingTimeoutError{AppName: appName, Timeout: actor.Config.StagingTimeout()} 71 return 72 case <-timer.C(): 73 var warnings ccv3.Warnings 74 build, warnings, err = actor.CloudControllerClient.GetBuild(build.GUID) 75 warningsStream <- Warnings(warnings) 76 if err != nil { 77 errorStream <- err 78 return 79 } 80 81 switch build.State { 82 case constant.BuildFailed: 83 if strings.Contains(build.Error, "NoAppDetectedError") { 84 errorStream <- actionerror.StagingFailedNoAppDetectedError{Reason: build.Error} 85 } else { 86 errorStream <- actionerror.StagingFailedError{Reason: build.Error} 87 } 88 return 89 case constant.BuildStaging: 90 timer.Reset(actor.Config.PollingInterval()) 91 default: 92 93 //TODO: uncomment after #150569020 94 // droplet, warnings, err := actor.CloudControllerClient.GetDroplet(build.DropletGUID) 95 // warningsStream <- Warnings(warnings) 96 // if err != nil { 97 // errorStream <- err 98 // return 99 // } 100 101 droplet := resources.Droplet{ 102 GUID: build.DropletGUID, 103 State: constant.DropletState(build.State), 104 CreatedAt: build.CreatedAt, 105 } 106 107 dropletStream <- droplet 108 return 109 } 110 } 111 } 112 }() 113 114 return dropletStream, warningsStream, errorStream 115 } 116 117 func (actor Actor) StageApplicationPackage(packageGUID string) (resources.Build, Warnings, error) { 118 var allWarnings Warnings 119 120 build := resources.Build{PackageGUID: packageGUID} 121 build, warnings, err := actor.CloudControllerClient.CreateBuild(build) 122 log.Debug("created build") 123 allWarnings = append(allWarnings, warnings...) 124 if err != nil { 125 return resources.Build{}, allWarnings, err 126 } 127 128 log.Debug("no errors creating build") 129 return resources.Build{GUID: build.GUID}, allWarnings, nil 130 } 131 132 func (actor Actor) PollBuild(buildGUID string, appName string) (resources.Droplet, Warnings, error) { 133 var allWarnings Warnings 134 135 timeout := actor.Clock.After(actor.Config.StagingTimeout()) 136 interval := actor.Clock.NewTimer(time.Millisecond) 137 138 for { 139 select { 140 case <-interval.C(): 141 build, warnings, err := actor.CloudControllerClient.GetBuild(buildGUID) 142 allWarnings = append(allWarnings, warnings...) 143 if err != nil { 144 return resources.Droplet{}, allWarnings, err 145 } 146 147 switch build.State { 148 case constant.BuildFailed: 149 return resources.Droplet{}, allWarnings, errors.New(build.Error) 150 151 case constant.BuildStaged: 152 droplet, warnings, err := actor.CloudControllerClient.GetDroplet(build.DropletGUID) 153 allWarnings = append(allWarnings, warnings...) 154 if err != nil { 155 return resources.Droplet{}, allWarnings, err 156 } 157 158 return resources.Droplet{ 159 GUID: droplet.GUID, 160 State: droplet.State, 161 CreatedAt: droplet.CreatedAt, 162 }, allWarnings, nil 163 } 164 165 interval.Reset(actor.Config.PollingInterval()) 166 167 case <-timeout: 168 return resources.Droplet{}, allWarnings, actionerror.StagingTimeoutError{AppName: appName, Timeout: actor.Config.StagingTimeout()} 169 } 170 } 171 }