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