github.com/lukasheimann/cloudfoundrycli@v7.1.0+incompatible/actor/v7action/package.go (about) 1 package v7action 2 3 import ( 4 "io" 5 "os" 6 "time" 7 8 "code.cloudfoundry.org/cli/actor/actionerror" 9 "code.cloudfoundry.org/cli/actor/sharedaction" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 12 "code.cloudfoundry.org/cli/resources" 13 log "github.com/sirupsen/logrus" 14 ) 15 16 const ( 17 DefaultFolderPermissions = 0755 18 DefaultArchiveFilePermissions = 0744 19 ) 20 21 type Package ccv3.Package 22 23 type DockerImageCredentials struct { 24 Path string 25 Username string 26 Password string 27 } 28 29 func (actor Actor) CreateDockerPackageByApplication(appGUID string, dockerImageCredentials DockerImageCredentials) (Package, Warnings, error) { 30 inputPackage := ccv3.Package{ 31 Type: constant.PackageTypeDocker, 32 Relationships: resources.Relationships{ 33 constant.RelationshipTypeApplication: resources.Relationship{GUID: appGUID}, 34 }, 35 DockerImage: dockerImageCredentials.Path, 36 DockerUsername: dockerImageCredentials.Username, 37 DockerPassword: dockerImageCredentials.Password, 38 } 39 pkg, warnings, err := actor.CloudControllerClient.CreatePackage(inputPackage) 40 return Package(pkg), Warnings(warnings), err 41 } 42 43 func (actor Actor) CreateDockerPackageByApplicationNameAndSpace(appName string, spaceGUID string, dockerImageCredentials DockerImageCredentials) (Package, Warnings, error) { 44 app, getWarnings, err := actor.GetApplicationByNameAndSpace(appName, spaceGUID) 45 if err != nil { 46 return Package{}, getWarnings, err 47 } 48 pkg, warnings, err := actor.CreateDockerPackageByApplication(app.GUID, dockerImageCredentials) 49 return pkg, append(getWarnings, warnings...), err 50 } 51 52 func (actor Actor) CreateAndUploadBitsPackageByApplicationNameAndSpace(appName string, spaceGUID string, bitsPath string) (Package, Warnings, error) { 53 app, allWarnings, err := actor.GetApplicationByNameAndSpace(appName, spaceGUID) 54 if err != nil { 55 return Package{}, allWarnings, err 56 } 57 58 if bitsPath == "" { 59 bitsPath, err = os.Getwd() 60 if err != nil { 61 return Package{}, allWarnings, err 62 } 63 } 64 65 info, err := os.Stat(bitsPath) 66 if err != nil { 67 return Package{}, allWarnings, err 68 } 69 70 var fileResources []sharedaction.Resource 71 if info.IsDir() { 72 fileResources, err = actor.SharedActor.GatherDirectoryResources(bitsPath) 73 } else { 74 fileResources, err = actor.SharedActor.GatherArchiveResources(bitsPath) 75 } 76 if err != nil { 77 return Package{}, allWarnings, err 78 } 79 80 // potentially match resources here in the future 81 82 var archivePath string 83 if info.IsDir() { 84 archivePath, err = actor.SharedActor.ZipDirectoryResources(bitsPath, fileResources) 85 } else { 86 archivePath, err = actor.SharedActor.ZipArchiveResources(bitsPath, fileResources) 87 } 88 if err != nil { 89 os.RemoveAll(archivePath) 90 return Package{}, allWarnings, err 91 } 92 defer os.RemoveAll(archivePath) 93 94 inputPackage := ccv3.Package{ 95 Type: constant.PackageTypeBits, 96 Relationships: resources.Relationships{ 97 constant.RelationshipTypeApplication: resources.Relationship{GUID: app.GUID}, 98 }, 99 } 100 101 pkg, warnings, err := actor.CloudControllerClient.CreatePackage(inputPackage) 102 allWarnings = append(allWarnings, warnings...) 103 if err != nil { 104 return Package{}, allWarnings, err 105 } 106 107 _, warnings, err = actor.CloudControllerClient.UploadPackage(pkg, archivePath) 108 allWarnings = append(allWarnings, warnings...) 109 if err != nil { 110 return Package{}, allWarnings, err 111 } 112 113 for pkg.State != constant.PackageReady && 114 pkg.State != constant.PackageFailed && 115 pkg.State != constant.PackageExpired { 116 time.Sleep(actor.Config.PollingInterval()) 117 pkg, warnings, err = actor.CloudControllerClient.GetPackage(pkg.GUID) 118 allWarnings = append(allWarnings, warnings...) 119 if err != nil { 120 return Package{}, allWarnings, err 121 } 122 } 123 124 if pkg.State == constant.PackageFailed { 125 return Package{}, allWarnings, actionerror.PackageProcessingFailedError{} 126 } else if pkg.State == constant.PackageExpired { 127 return Package{}, allWarnings, actionerror.PackageProcessingExpiredError{} 128 } 129 130 updatedPackage, updatedWarnings, err := actor.PollPackage(Package(pkg)) 131 return updatedPackage, append(allWarnings, updatedWarnings...), err 132 } 133 134 func (actor Actor) GetNewestReadyPackageForApplication(app resources.Application) (Package, Warnings, error) { 135 ccv3Packages, warnings, err := actor.CloudControllerClient.GetPackages( 136 ccv3.Query{ 137 Key: ccv3.AppGUIDFilter, 138 Values: []string{app.GUID}, 139 }, 140 ccv3.Query{ 141 Key: ccv3.StatesFilter, 142 Values: []string{string(constant.PackageReady)}, 143 }, 144 ccv3.Query{ 145 Key: ccv3.OrderBy, 146 Values: []string{ccv3.CreatedAtDescendingOrder}, 147 }, 148 ) 149 150 if err != nil { 151 return Package{}, Warnings(warnings), err 152 } 153 154 if len(ccv3Packages) == 0 { 155 return Package{}, Warnings(warnings), actionerror.NoEligiblePackagesError{AppName: app.Name} 156 } 157 158 return Package(ccv3Packages[0]), Warnings(warnings), nil 159 } 160 161 // GetApplicationPackages returns a list of package of an app. 162 func (actor *Actor) GetApplicationPackages(appName string, spaceGUID string) ([]Package, Warnings, error) { 163 app, allWarnings, err := actor.GetApplicationByNameAndSpace(appName, spaceGUID) 164 if err != nil { 165 return nil, allWarnings, err 166 } 167 168 ccv3Packages, warnings, err := actor.CloudControllerClient.GetPackages( 169 ccv3.Query{Key: ccv3.AppGUIDFilter, Values: []string{app.GUID}}, 170 ccv3.Query{Key: ccv3.OrderBy, Values: []string{ccv3.CreatedAtDescendingOrder}}, 171 ) 172 allWarnings = append(allWarnings, warnings...) 173 if err != nil { 174 return nil, allWarnings, err 175 } 176 177 var packages []Package 178 for _, ccv3Package := range ccv3Packages { 179 packages = append(packages, Package(ccv3Package)) 180 } 181 182 return packages, allWarnings, nil 183 } 184 185 func (actor Actor) CreateBitsPackageByApplication(appGUID string) (Package, Warnings, error) { 186 inputPackage := ccv3.Package{ 187 Type: constant.PackageTypeBits, 188 Relationships: resources.Relationships{ 189 constant.RelationshipTypeApplication: resources.Relationship{GUID: appGUID}, 190 }, 191 } 192 193 pkg, warnings, err := actor.CloudControllerClient.CreatePackage(inputPackage) 194 if err != nil { 195 return Package{}, Warnings(warnings), err 196 } 197 198 return Package(pkg), Warnings(warnings), err 199 } 200 201 func (actor Actor) UploadBitsPackage(pkg Package, matchedResources []sharedaction.V3Resource, newResources io.Reader, newResourcesLength int64) (Package, Warnings, error) { 202 apiResources := make([]ccv3.Resource, 0, len(matchedResources)) // Explicitly done to prevent nils 203 204 for _, resource := range matchedResources { 205 apiResources = append(apiResources, ccv3.Resource(resource)) 206 } 207 208 appPkg, warnings, err := actor.CloudControllerClient.UploadBitsPackage(ccv3.Package(pkg), apiResources, newResources, newResourcesLength) 209 return Package(appPkg), Warnings(warnings), err 210 } 211 212 // PollPackage returns a package of an app. 213 func (actor Actor) PollPackage(pkg Package) (Package, Warnings, error) { 214 var allWarnings Warnings 215 216 for pkg.State != constant.PackageReady && pkg.State != constant.PackageFailed && pkg.State != constant.PackageExpired { 217 time.Sleep(actor.Config.PollingInterval()) 218 ccPkg, warnings, err := actor.CloudControllerClient.GetPackage(pkg.GUID) 219 log.WithFields(log.Fields{ 220 "package_guid": pkg.GUID, 221 "state": pkg.State, 222 }).Debug("polling package state") 223 224 allWarnings = append(allWarnings, warnings...) 225 if err != nil { 226 return Package{}, allWarnings, err 227 } 228 229 pkg = Package(ccPkg) 230 } 231 232 if pkg.State == constant.PackageFailed { 233 return Package{}, allWarnings, actionerror.PackageProcessingFailedError{} 234 } else if pkg.State == constant.PackageExpired { 235 return Package{}, allWarnings, actionerror.PackageProcessingExpiredError{} 236 } 237 238 return pkg, allWarnings, nil 239 } 240 241 func (actor Actor) CopyPackage(sourceApp resources.Application, targetApp resources.Application) (Package, Warnings, error) { 242 var allWarnings Warnings 243 sourcePkg, warnings, err := actor.GetNewestReadyPackageForApplication(sourceApp) 244 allWarnings = append(allWarnings, warnings...) 245 if err != nil { 246 return Package{}, allWarnings, err 247 } 248 targetPkg, ccv3Warnings, err := actor.CloudControllerClient.CopyPackage(sourcePkg.GUID, targetApp.GUID) 249 allWarnings = append(allWarnings, ccv3Warnings...) 250 if err != nil { 251 return Package{}, allWarnings, err 252 } 253 254 readyPackage, warnings, err := actor.PollPackage(Package(targetPkg)) 255 allWarnings = append(allWarnings, warnings...) 256 if err != nil { 257 return Package{}, allWarnings, err 258 } 259 260 return readyPackage, allWarnings, nil 261 }