github.com/jfrog/jfrog-cli-core@v1.12.1/artifactory/commands/container/push.go (about)

     1  package container
     2  
     3  import (
     4  	commandsutils "github.com/jfrog/jfrog-cli-core/artifactory/commands/utils"
     5  	"github.com/jfrog/jfrog-cli-core/artifactory/utils"
     6  	"github.com/jfrog/jfrog-cli-core/artifactory/utils/container"
     7  	"github.com/jfrog/jfrog-cli-core/utils/config"
     8  	servicesutils "github.com/jfrog/jfrog-client-go/artifactory/services/utils"
     9  	clientutils "github.com/jfrog/jfrog-client-go/utils"
    10  	"github.com/jfrog/jfrog-client-go/utils/errorutils"
    11  	"github.com/jfrog/jfrog-client-go/utils/io/content"
    12  )
    13  
    14  type PushCommand struct {
    15  	ContainerManagerCommand
    16  	threads              int
    17  	containerManagerType container.ContainerManagerType
    18  	detailedSummary      bool
    19  	result               *commandsutils.Result
    20  }
    21  
    22  func NewPushCommand(containerManager container.ContainerManagerType) *PushCommand {
    23  	return &PushCommand{containerManagerType: containerManager}
    24  }
    25  
    26  func (pc *PushCommand) Threads() int {
    27  	return pc.threads
    28  }
    29  
    30  func (pc *PushCommand) SetThreads(threads int) *PushCommand {
    31  	pc.threads = threads
    32  	return pc
    33  }
    34  
    35  func (pc *PushCommand) SetDetailedSummary(detailedSummary bool) *PushCommand {
    36  	pc.detailedSummary = detailedSummary
    37  	return pc
    38  }
    39  
    40  func (pc *PushCommand) IsDetailedSummary() bool {
    41  	return pc.detailedSummary
    42  }
    43  
    44  func (pc *PushCommand) Result() *commandsutils.Result {
    45  	return pc.result
    46  }
    47  
    48  func (pc *PushCommand) SetResult(result *commandsutils.Result) *PushCommand {
    49  	pc.result = result
    50  	return pc
    51  }
    52  
    53  // Push image and create build info if needed
    54  func (pc *PushCommand) Run() error {
    55  	if pc.containerManagerType == container.DockerClient {
    56  		err := container.ValidateClientApiVersion()
    57  		if err != nil {
    58  			return err
    59  		}
    60  	}
    61  	serverDetails, err := pc.ServerDetails()
    62  	if errorutils.CheckError(err) != nil {
    63  		return err
    64  	}
    65  	// Perform login
    66  	if err := pc.PerformLogin(serverDetails, pc.containerManagerType); err != nil {
    67  		return err
    68  	}
    69  	// Perform push.
    70  	cm := container.NewManager(pc.containerManagerType)
    71  	image := container.NewImage(pc.imageTag)
    72  	err = cm.Push(image)
    73  	if err != nil {
    74  		return err
    75  	}
    76  	// Return if build-info and detailed summary were not requested.
    77  	saveBuildInfo := pc.buildConfiguration.BuildName != "" && pc.buildConfiguration.BuildNumber != ""
    78  	if !saveBuildInfo && !pc.IsDetailedSummary() {
    79  		return nil
    80  	}
    81  	if err := utils.SaveBuildGeneralDetails(pc.buildConfiguration.BuildName, pc.buildConfiguration.BuildNumber, pc.buildConfiguration.Project); err != nil {
    82  		return err
    83  	}
    84  	serviceManager, err := utils.CreateServiceManagerWithThreads(serverDetails, false, pc.threads, -1)
    85  	if err != nil {
    86  		return err
    87  	}
    88  	builder, err := container.NewBuildInfoBuilder(image, pc.Repo(), pc.BuildConfiguration().BuildName, pc.BuildConfiguration().BuildNumber, pc.BuildConfiguration().Project, serviceManager, container.Push, cm)
    89  	if err != nil {
    90  		return err
    91  	}
    92  	// Save buildinfo if needed
    93  	if saveBuildInfo {
    94  		buildInfo, err := builder.Build(pc.BuildConfiguration().Module)
    95  		if err != nil {
    96  			return err
    97  		}
    98  		err = utils.SaveBuildInfo(pc.BuildConfiguration().BuildName, pc.BuildConfiguration().BuildNumber, pc.BuildConfiguration().Project, buildInfo)
    99  		if err != nil {
   100  			return err
   101  		}
   102  	}
   103  	// Save detailed summary if needed
   104  	if pc.IsDetailedSummary() {
   105  		if !saveBuildInfo {
   106  			// If we saved buildinfo earlier, this update already happened.
   107  			err = builder.UpdateArtifactsAndDependencies()
   108  			if err != nil {
   109  				return err
   110  			}
   111  		}
   112  		artifactsDetails := layersMapToFileTransferDetails(serverDetails.ArtifactoryUrl, builder.GetLayers())
   113  		tempFile, err := clientutils.SaveFileTransferDetailsInTempFile(artifactsDetails)
   114  		if err != nil {
   115  			return err
   116  		}
   117  		result := new(commandsutils.Result)
   118  		result.SetReader(content.NewContentReader(tempFile, "files"))
   119  		result.SetSuccessCount(len(*artifactsDetails))
   120  		pc.SetResult(result)
   121  	}
   122  	return nil
   123  }
   124  
   125  func layersMapToFileTransferDetails(artifactoryUrl string, layers *[]servicesutils.ResultItem) *[]clientutils.FileTransferDetails {
   126  	var details []clientutils.FileTransferDetails
   127  	for _, layer := range *layers {
   128  		sha256 := ""
   129  		for _, property := range layer.Properties {
   130  			if property.Key == "sha256" {
   131  				sha256 = property.Value
   132  			}
   133  		}
   134  		target := artifactoryUrl + layer.Repo + "/" + layer.Path + "/" + layer.Name
   135  		details = append(details, clientutils.FileTransferDetails{TargetPath: target, Sha256: sha256})
   136  	}
   137  	return &details
   138  }
   139  
   140  func (pc *PushCommand) CommandName() string {
   141  	return "rt_docker_push"
   142  }
   143  
   144  func (pc *PushCommand) ServerDetails() (*config.ServerDetails, error) {
   145  	return pc.serverDetails, nil
   146  }