github.com/jfrog/jfrog-cli-core/v2@v2.51.0/artifactory/commands/container/push.go (about) 1 package container 2 3 import ( 4 "path" 5 6 commandsutils "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/utils" 7 "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" 8 "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils/container" 9 "github.com/jfrog/jfrog-cli-core/v2/common/build" 10 "github.com/jfrog/jfrog-cli-core/v2/utils/config" 11 servicesutils "github.com/jfrog/jfrog-client-go/artifactory/services/utils" 12 clientutils "github.com/jfrog/jfrog-client-go/utils" 13 "github.com/jfrog/jfrog-client-go/utils/errorutils" 14 "github.com/jfrog/jfrog-client-go/utils/io/content" 15 ) 16 17 type PushCommand struct { 18 ContainerCommand 19 threads int 20 detailedSummary bool 21 result *commandsutils.Result 22 } 23 24 func NewPushCommand(containerManagerType container.ContainerManagerType) *PushCommand { 25 return &PushCommand{ 26 ContainerCommand: ContainerCommand{ 27 containerManagerType: containerManagerType, 28 }, 29 } 30 } 31 32 func (pc *PushCommand) Threads() int { 33 return pc.threads 34 } 35 36 func (pc *PushCommand) SetThreads(threads int) *PushCommand { 37 pc.threads = threads 38 return pc 39 } 40 41 func (pc *PushCommand) SetDetailedSummary(detailedSummary bool) *PushCommand { 42 pc.detailedSummary = detailedSummary 43 return pc 44 } 45 46 func (pc *PushCommand) IsDetailedSummary() bool { 47 return pc.detailedSummary 48 } 49 50 func (pc *PushCommand) Result() *commandsutils.Result { 51 return pc.result 52 } 53 54 func (pc *PushCommand) SetResult(result *commandsutils.Result) *PushCommand { 55 pc.result = result 56 return pc 57 } 58 59 func (pc *PushCommand) Run() error { 60 if err := pc.init(); err != nil { 61 return err 62 } 63 if pc.containerManagerType == container.DockerClient { 64 err := container.ValidateClientApiVersion() 65 if err != nil { 66 return err 67 } 68 } 69 serverDetails, err := pc.ServerDetails() 70 if errorutils.CheckError(err) != nil { 71 return err 72 } 73 // Perform login 74 if err := pc.PerformLogin(serverDetails, pc.containerManagerType); err != nil { 75 return err 76 } 77 // Perform push. 78 cm := container.NewManager(pc.containerManagerType) 79 err = cm.RunNativeCmd(pc.cmdParams) 80 if err != nil { 81 return err 82 } 83 toCollect, err := pc.buildConfiguration.IsCollectBuildInfo() 84 if err != nil { 85 return err 86 } 87 if !toCollect && !pc.IsDetailedSummary() { 88 return nil 89 } 90 buildName, err := pc.buildConfiguration.GetBuildName() 91 if err != nil { 92 return err 93 } 94 buildNumber, err := pc.buildConfiguration.GetBuildNumber() 95 if err != nil { 96 return err 97 } 98 serviceManager, err := utils.CreateServiceManagerWithThreads(serverDetails, false, pc.threads, -1, 0) 99 if err != nil { 100 return err 101 } 102 repo, err := pc.GetRepo() 103 if err != nil { 104 return err 105 } 106 builder, err := container.NewLocalAgentBuildInfoBuilder(pc.image, repo, buildName, buildNumber, pc.BuildConfiguration().GetProject(), serviceManager, container.Push, cm) 107 if err != nil { 108 return err 109 } 110 if toCollect { 111 if err := build.SaveBuildGeneralDetails(buildName, buildNumber, pc.buildConfiguration.GetProject()); err != nil { 112 return err 113 } 114 buildInfoModule, err := builder.Build(pc.BuildConfiguration().GetModule()) 115 if err != nil || buildInfoModule == nil { 116 return err 117 } 118 if err = build.SaveBuildInfo(buildName, buildNumber, pc.BuildConfiguration().GetProject(), buildInfoModule); err != nil { 119 return err 120 } 121 } 122 if pc.IsDetailedSummary() { 123 if !toCollect { 124 // The build-info collection hasn't been triggered at this point, and we do need it for handling the detailed summary. 125 // We are therefore skipping setting mage build name/number props before running build-info collection. 126 builder.SetSkipTaggingLayers(true) 127 _, err = builder.Build("") 128 if err != nil { 129 return err 130 } 131 } 132 return pc.layersMapToFileTransferDetails(serverDetails.ArtifactoryUrl, builder.GetLayers()) 133 } 134 return nil 135 } 136 137 func (pc *PushCommand) layersMapToFileTransferDetails(artifactoryUrl string, layers *[]servicesutils.ResultItem) error { 138 var details []clientutils.FileTransferDetails 139 for _, layer := range *layers { 140 sha256 := "" 141 for _, property := range layer.Properties { 142 if property.Key == "sha256" { 143 sha256 = property.Value 144 } 145 } 146 details = append(details, clientutils.FileTransferDetails{TargetPath: path.Join(layer.Repo, layer.Path, layer.Name), RtUrl: artifactoryUrl, Sha256: sha256}) 147 } 148 tempFile, err := clientutils.SaveFileTransferDetailsInTempFile(&details) 149 if err != nil { 150 return err 151 } 152 result := new(commandsutils.Result) 153 result.SetReader(content.NewContentReader(tempFile, "files")) 154 result.SetSuccessCount(len(details)) 155 pc.SetResult(result) 156 return nil 157 } 158 159 func (pc *PushCommand) CommandName() string { 160 return "rt_docker_push" 161 } 162 163 func (pc *PushCommand) ServerDetails() (*config.ServerDetails, error) { 164 return pc.serverDetails, nil 165 }