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  }