github.com/xgoffin/jenkins-library@v1.154.0/cmd/containerSaveImage.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 9 piperDocker "github.com/SAP/jenkins-library/pkg/docker" 10 "github.com/SAP/jenkins-library/pkg/log" 11 "github.com/SAP/jenkins-library/pkg/piperutils" 12 "github.com/SAP/jenkins-library/pkg/telemetry" 13 14 "github.com/pkg/errors" 15 ) 16 17 func containerSaveImage(config containerSaveImageOptions, telemetryData *telemetry.CustomData) { 18 var cachePath = "./cache" 19 20 dClientOptions := piperDocker.ClientOptions{ImageName: config.ContainerImage, RegistryURL: config.ContainerRegistryURL, LocalPath: config.FilePath, IncludeLayers: config.IncludeLayers} 21 dClient := &piperDocker.Client{} 22 dClient.SetOptions(dClientOptions) 23 24 _, err := runContainerSaveImage(&config, telemetryData, cachePath, "", dClient, piperutils.Files{}) 25 if err != nil { 26 log.Entry().WithError(err).Fatal("step execution failed") 27 } 28 } 29 30 func runContainerSaveImage(config *containerSaveImageOptions, telemetryData *telemetry.CustomData, cachePath, rootPath string, dClient piperDocker.Download, fileUtils piperutils.FileUtils) (string, error) { 31 if err := correctContainerDockerConfigEnvVar(config, fileUtils); err != nil { 32 return "", err 33 } 34 35 err := os.RemoveAll(cachePath) 36 if err != nil { 37 return "", errors.Wrap(err, "failed to prepare cache") 38 } 39 40 err = os.Mkdir(cachePath, 0755) 41 if err != nil { 42 return "", errors.Wrap(err, "failed to create cache") 43 } 44 45 // ensure that download cache is cleaned up at the end 46 defer os.RemoveAll(cachePath) 47 48 imageSource, err := dClient.GetImageSource() 49 if err != nil { 50 return "", errors.Wrap(err, "failed to get docker image source") 51 } 52 image, err := dClient.DownloadImageToPath(imageSource, cachePath) 53 if err != nil { 54 return "", errors.Wrap(err, "failed to download docker image") 55 } 56 57 tarfilePath := config.FilePath 58 if len(tarfilePath) == 0 { 59 tarfilePath = filenameFromContainer(rootPath, config.ContainerImage) 60 } else { 61 tarfilePath = filenameFromContainer(rootPath, tarfilePath) 62 } 63 64 tarFile, err := os.Create(tarfilePath) 65 if err != nil { 66 return "", errors.Wrapf(err, "failed to create %v for docker image", tarfilePath) 67 } 68 defer tarFile.Close() 69 70 if err := os.Chmod(tarfilePath, 0644); err != nil { 71 return "", errors.Wrapf(err, "failed to adapt permissions on %v", tarfilePath) 72 } 73 74 err = dClient.TarImage(tarFile, image) 75 if err != nil { 76 return "", errors.Wrap(err, "failed to tar container image") 77 } 78 79 return tarfilePath, nil 80 } 81 82 func filenameFromContainer(rootPath, containerImage string) string { 83 return filepath.Join(rootPath, strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(containerImage, "/", "_"), ":", "_"), ".", "_")+".tar") 84 } 85 86 func correctContainerDockerConfigEnvVar(config *containerSaveImageOptions, utils piperutils.FileUtils) error { 87 dockerConfigDir, err := utils.TempDir("", "docker") 88 89 if err != nil { 90 return errors.Wrap(err, "unable to create docker config dir") 91 } 92 93 dockerConfigFile := fmt.Sprintf("%s/%s", dockerConfigDir, "config.json") 94 95 if len(config.DockerConfigJSON) > 0 { 96 log.Entry().Infof("Docker credentials configuration: %v", config.DockerConfigJSON) 97 98 if exists, _ := utils.FileExists(config.DockerConfigJSON); exists { 99 if _, err = utils.Copy(config.DockerConfigJSON, dockerConfigFile); err != nil { 100 return errors.Wrap(err, "unable to copy docker config") 101 } 102 } 103 } else { 104 log.Entry().Info("Docker credentials configuration: NONE") 105 } 106 107 if len(config.ContainerRegistryURL) > 0 && len(config.ContainerRegistryUser) > 0 && len(config.ContainerRegistryPassword) > 0 { 108 if _, err = piperDocker.CreateDockerConfigJSON(config.ContainerRegistryURL, config.ContainerRegistryUser, config.ContainerRegistryPassword, dockerConfigFile, dockerConfigFile, utils); err != nil { 109 log.Entry().Warningf("failed to update Docker config.json: %v", err) 110 } 111 } 112 113 os.Setenv("DOCKER_CONFIG", dockerConfigDir) 114 115 return nil 116 }