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  }