github.com/sleungcy-sap/cli@v7.1.0+incompatible/actor/v7pushaction/create_bits_package_for_application.go (about)

     1  package v7pushaction
     2  
     3  import (
     4  	"os"
     5  
     6  	"code.cloudfoundry.org/cli/actor/actionerror"
     7  	"code.cloudfoundry.org/cli/actor/sharedaction"
     8  	"code.cloudfoundry.org/cli/actor/v7action"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
    10  	log "github.com/sirupsen/logrus"
    11  )
    12  
    13  const PushRetries = 3
    14  
    15  func (actor Actor) CreateBitsPackageForApplication(pushPlan PushPlan, eventStream chan<- *PushEvent, progressBar ProgressBar) (PushPlan, Warnings, error) {
    16  	pkg, warnings, err := actor.CreateAndUploadApplicationBits(pushPlan, eventStream, progressBar)
    17  	if err != nil {
    18  		return pushPlan, warnings, err
    19  	}
    20  
    21  	polledPackage, pollWarnings, err := actor.V7Actor.PollPackage(pkg)
    22  
    23  	pushPlan.PackageGUID = polledPackage.GUID
    24  
    25  	return pushPlan, append(warnings, pollWarnings...), err
    26  }
    27  
    28  func (actor Actor) CreateAndUploadApplicationBits(pushPlan PushPlan, eventStream chan<- *PushEvent, progressBar ProgressBar) (v7action.Package, Warnings, error) {
    29  	log.WithField("Path", pushPlan.BitsPath).Info("creating archive")
    30  
    31  	var (
    32  		allWarnings        Warnings
    33  		matchedResources   []sharedaction.V3Resource
    34  		unmatchedResources []sharedaction.V3Resource
    35  	)
    36  
    37  	// check if all source files are empty
    38  	shouldResourceMatch := false
    39  	for _, resource := range pushPlan.AllResources {
    40  		if resource.SizeInBytes != 0 {
    41  			shouldResourceMatch = true
    42  		}
    43  	}
    44  
    45  	if shouldResourceMatch {
    46  		eventStream <- &PushEvent{Plan: pushPlan, Event: ResourceMatching}
    47  		var warnings Warnings
    48  		var err error
    49  
    50  		matchedResources, unmatchedResources, warnings, err = actor.MatchResources(pushPlan.AllResources)
    51  		allWarnings = append(allWarnings, warnings...)
    52  		if err != nil {
    53  			return v7action.Package{}, allWarnings, err
    54  		}
    55  	} else {
    56  		matchedResources = []sharedaction.V3Resource{}
    57  		unmatchedResources = pushPlan.AllResources
    58  	}
    59  
    60  	eventStream <- &PushEvent{Plan: pushPlan, Event: CreatingPackage}
    61  	log.WithField("GUID", pushPlan.Application.GUID).Info("creating package")
    62  	pkg, createPackageWarnings, err := actor.V7Actor.CreateBitsPackageByApplication(pushPlan.Application.GUID)
    63  	allWarnings = append(allWarnings, createPackageWarnings...)
    64  	if err != nil {
    65  		return v7action.Package{}, allWarnings, err
    66  	}
    67  
    68  	if len(unmatchedResources) > 0 {
    69  		eventStream <- &PushEvent{Plan: pushPlan, Event: CreatingArchive}
    70  		archivePath, archiveErr := actor.CreateAndReturnArchivePath(pushPlan, unmatchedResources)
    71  		if archiveErr != nil {
    72  			return v7action.Package{}, allWarnings, archiveErr
    73  		}
    74  		defer os.RemoveAll(archivePath)
    75  
    76  		// Uploading package/app bits
    77  		for count := 0; count < PushRetries; count++ {
    78  			eventStream <- &PushEvent{Plan: pushPlan, Event: ReadingArchive}
    79  			log.WithField("GUID", pushPlan.Application.GUID).Info("reading archive")
    80  			file, size, readErr := actor.SharedActor.ReadArchive(archivePath)
    81  			if readErr != nil {
    82  				return v7action.Package{}, allWarnings, readErr
    83  			}
    84  			defer file.Close()
    85  
    86  			eventStream <- &PushEvent{Plan: pushPlan, Event: UploadingApplicationWithArchive}
    87  			progressReader := progressBar.NewProgressBarWrapper(file, size)
    88  			var uploadWarnings v7action.Warnings
    89  			pkg, uploadWarnings, err = actor.V7Actor.UploadBitsPackage(pkg, matchedResources, progressReader, size)
    90  			allWarnings = append(allWarnings, uploadWarnings...)
    91  
    92  			if _, ok := err.(ccerror.PipeSeekError); ok {
    93  				eventStream <- &PushEvent{Plan: pushPlan, Event: RetryUpload}
    94  				continue
    95  			}
    96  			break
    97  		}
    98  
    99  		if err != nil {
   100  			if e, ok := err.(ccerror.PipeSeekError); ok {
   101  				return v7action.Package{}, allWarnings, actionerror.UploadFailedError{Err: e.Err}
   102  			}
   103  			return v7action.Package{}, allWarnings, err
   104  		}
   105  
   106  		eventStream <- &PushEvent{Plan: pushPlan, Event: UploadWithArchiveComplete}
   107  	} else {
   108  		eventStream <- &PushEvent{Plan: pushPlan, Event: UploadingApplication}
   109  		var uploadWarnings v7action.Warnings
   110  		pkg, uploadWarnings, err = actor.V7Actor.UploadBitsPackage(pkg, matchedResources, nil, 0)
   111  		allWarnings = append(allWarnings, uploadWarnings...)
   112  		if err != nil {
   113  			return v7action.Package{}, allWarnings, err
   114  		}
   115  	}
   116  
   117  	return pkg, allWarnings, nil
   118  }
   119  
   120  func (actor Actor) CreateAndReturnArchivePath(pushPlan PushPlan, unmatchedResources []sharedaction.V3Resource) (string, error) {
   121  	// translate between v3 and v2 resources
   122  	var v2Resources []sharedaction.Resource
   123  	for _, resource := range unmatchedResources {
   124  		v2Resources = append(v2Resources, resource.ToV2Resource())
   125  	}
   126  
   127  	if pushPlan.Archive {
   128  		return actor.SharedActor.ZipArchiveResources(pushPlan.BitsPath, v2Resources)
   129  	}
   130  	return actor.SharedActor.ZipDirectoryResources(pushPlan.BitsPath, v2Resources)
   131  }