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 }