code.cloudfoundry.org/cli@v7.1.0+incompatible/actor/v3action/package.go (about) 1 package v3action 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) CreateDockerPackageByApplicationNameAndSpace(appName string, spaceGUID string, dockerImageCredentials DockerImageCredentials) (Package, Warnings, error) { 30 app, allWarnings, err := actor.GetApplicationByNameAndSpace(appName, spaceGUID) 31 if err != nil { 32 return Package{}, allWarnings, err 33 } 34 inputPackage := ccv3.Package{ 35 Type: constant.PackageTypeDocker, 36 Relationships: resources.Relationships{ 37 constant.RelationshipTypeApplication: resources.Relationship{GUID: app.GUID}, 38 }, 39 DockerImage: dockerImageCredentials.Path, 40 DockerUsername: dockerImageCredentials.Username, 41 DockerPassword: dockerImageCredentials.Password, 42 } 43 pkg, warnings, err := actor.CloudControllerClient.CreatePackage(inputPackage) 44 allWarnings = append(allWarnings, warnings...) 45 if err != nil { 46 return Package{}, allWarnings, err 47 } 48 return Package(pkg), allWarnings, err 49 } 50 51 func (actor Actor) CreateAndUploadBitsPackageByApplicationNameAndSpace(appName string, spaceGUID string, bitsPath string) (Package, Warnings, error) { 52 app, allWarnings, err := actor.GetApplicationByNameAndSpace(appName, spaceGUID) 53 if err != nil { 54 return Package{}, allWarnings, err 55 } 56 57 if bitsPath == "" { 58 bitsPath, err = os.Getwd() 59 if err != nil { 60 return Package{}, allWarnings, err 61 } 62 } 63 64 info, err := os.Stat(bitsPath) 65 if err != nil { 66 return Package{}, allWarnings, err 67 } 68 69 var fileResources []sharedaction.Resource 70 if info.IsDir() { 71 fileResources, err = actor.SharedActor.GatherDirectoryResources(bitsPath) 72 } else { 73 fileResources, err = actor.SharedActor.GatherArchiveResources(bitsPath) 74 } 75 if err != nil { 76 return Package{}, allWarnings, err 77 } 78 79 // potentially match resources here in the future 80 81 var archivePath string 82 if info.IsDir() { 83 archivePath, err = actor.SharedActor.ZipDirectoryResources(bitsPath, fileResources) 84 } else { 85 archivePath, err = actor.SharedActor.ZipArchiveResources(bitsPath, fileResources) 86 } 87 if err != nil { 88 os.RemoveAll(archivePath) 89 return Package{}, allWarnings, err 90 } 91 defer os.RemoveAll(archivePath) 92 93 inputPackage := ccv3.Package{ 94 Type: constant.PackageTypeBits, 95 Relationships: resources.Relationships{ 96 constant.RelationshipTypeApplication: resources.Relationship{GUID: app.GUID}, 97 }, 98 } 99 100 pkg, warnings, err := actor.CloudControllerClient.CreatePackage(inputPackage) 101 allWarnings = append(allWarnings, warnings...) 102 if err != nil { 103 return Package{}, allWarnings, err 104 } 105 106 _, warnings, err = actor.CloudControllerClient.UploadPackage(pkg, archivePath) 107 allWarnings = append(allWarnings, warnings...) 108 if err != nil { 109 return Package{}, allWarnings, err 110 } 111 112 for pkg.State != constant.PackageReady && 113 pkg.State != constant.PackageFailed && 114 pkg.State != constant.PackageExpired { 115 time.Sleep(actor.Config.PollingInterval()) 116 pkg, warnings, err = actor.CloudControllerClient.GetPackage(pkg.GUID) 117 allWarnings = append(allWarnings, warnings...) 118 if err != nil { 119 return Package{}, allWarnings, err 120 } 121 } 122 123 if pkg.State == constant.PackageFailed { 124 return Package{}, allWarnings, actionerror.PackageProcessingFailedError{} 125 } else if pkg.State == constant.PackageExpired { 126 return Package{}, allWarnings, actionerror.PackageProcessingExpiredError{} 127 } 128 129 updatedPackage, updatedWarnings, err := actor.PollPackage(Package(pkg)) 130 return updatedPackage, append(allWarnings, updatedWarnings...), err 131 } 132 133 // GetApplicationPackages returns a list of package of an app. 134 func (actor *Actor) GetApplicationPackages(appName string, spaceGUID string) ([]Package, Warnings, error) { 135 app, allWarnings, err := actor.GetApplicationByNameAndSpace(appName, spaceGUID) 136 if err != nil { 137 return nil, allWarnings, err 138 } 139 140 ccv3Packages, warnings, err := actor.CloudControllerClient.GetPackages( 141 ccv3.Query{Key: ccv3.AppGUIDFilter, Values: []string{app.GUID}}, 142 ) 143 allWarnings = append(allWarnings, warnings...) 144 if err != nil { 145 return nil, allWarnings, err 146 } 147 148 var packages []Package 149 for _, ccv3Package := range ccv3Packages { 150 packages = append(packages, Package(ccv3Package)) 151 } 152 153 return packages, allWarnings, nil 154 } 155 156 func (actor Actor) CreateBitsPackageByApplication(appGUID string) (Package, Warnings, error) { 157 inputPackage := ccv3.Package{ 158 Type: constant.PackageTypeBits, 159 Relationships: resources.Relationships{ 160 constant.RelationshipTypeApplication: resources.Relationship{GUID: appGUID}, 161 }, 162 } 163 164 pkg, warnings, err := actor.CloudControllerClient.CreatePackage(inputPackage) 165 if err != nil { 166 return Package{}, Warnings(warnings), err 167 } 168 169 return Package(pkg), Warnings(warnings), err 170 } 171 172 func (actor Actor) UploadBitsPackage(pkg Package, existingResources []sharedaction.Resource, newResources io.Reader, newResourcesLength int64) (Package, Warnings, error) { 173 apiResources := make([]ccv3.Resource, 0, len(existingResources)) // Explicitly done to prevent nils 174 175 for _, resource := range existingResources { 176 apiResources = append(apiResources, ccv3.Resource(resource.ToV3Resource())) 177 } 178 179 appPkg, warnings, err := actor.CloudControllerClient.UploadBitsPackage(ccv3.Package(pkg), apiResources, newResources, newResourcesLength) 180 return Package(appPkg), Warnings(warnings), err 181 } 182 183 // PollPackage returns a package of an app. 184 func (actor Actor) PollPackage(pkg Package) (Package, Warnings, error) { 185 var allWarnings Warnings 186 187 for pkg.State != constant.PackageReady && pkg.State != constant.PackageFailed && pkg.State != constant.PackageExpired { 188 time.Sleep(actor.Config.PollingInterval()) 189 ccPkg, warnings, err := actor.CloudControllerClient.GetPackage(pkg.GUID) 190 log.WithFields(log.Fields{ 191 "package_guid": pkg.GUID, 192 "state": pkg.State, 193 }).Debug("polling package state") 194 195 allWarnings = append(allWarnings, warnings...) 196 if err != nil { 197 return Package{}, allWarnings, err 198 } 199 200 pkg = Package(ccPkg) 201 } 202 203 if pkg.State == constant.PackageFailed { 204 return Package{}, allWarnings, actionerror.PackageProcessingFailedError{} 205 } else if pkg.State == constant.PackageExpired { 206 return Package{}, allWarnings, actionerror.PackageProcessingExpiredError{} 207 } 208 209 return pkg, allWarnings, nil 210 }