github.com/jaylevin/jenkins-library@v1.230.4/vars/containerPushToRegistry.groovy (about)

     1  import com.sap.piper.GenerateDocumentation
     2  import com.sap.piper.Utils
     3  import com.sap.piper.ConfigurationHelper
     4  import com.sap.piper.DockerUtils
     5  import groovy.transform.Field
     6  
     7  import static com.sap.piper.Prerequisites.checkScript
     8  
     9  @Field String STEP_NAME = getClass().getName()
    10  @Field Set GENERAL_CONFIG_KEYS = [
    11      /**
    12       * Defines the id of the Jenkins username/password credentials containing the credentials for the target Docker registry.
    13       */
    14      'dockerCredentialsId',
    15      /** Defines the registry url where the image should be pushed to, incl. the protocol like `https://my.registry.com`*/
    16      'dockerRegistryUrl',
    17  ]
    18  @Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
    19      /** Not supported yet - Docker archive to be pushed to registry*/
    20      'dockerArchive',
    21      /** For images built locally on the Docker Deamon, reference to the image object resulting from `docker.build` execution */
    22      'dockerBuildImage',
    23      /** Defines the name (incl. tag) of the target image*/
    24      'dockerImage',
    25      /**
    26       * Only if no Docker daemon available on your Jenkins image: Docker image to be used for [Skopeo](https://github.com/containers/skopeo) calls
    27       * Unfortunately no proper image known to be available.
    28       * Simple custom Dockerfile could look as follows: <br>
    29       * ```
    30       * FROM fedora:29
    31       * RUN dnf install -y skopeo
    32       * ```
    33       */
    34      'skopeoImage',
    35      /** Defines the name (incl. tag) of the source image to be pushed to a new image defined in `dockerImage`.<br>
    36       * This is helpful for moving images from one location to another.
    37       */
    38      'sourceImage',
    39      /** Defines a registry url from where the image should optionally be pulled from, incl. the protocol like `https://my.registry.com`*/
    40      'sourceRegistryUrl',
    41      /** Defines the id of the Jenkins username/password credentials containing the credentials for the source Docker registry. */
    42      'sourceCredentialsId',
    43      /** Defines if the image should be tagged as `latest`*/
    44      'tagLatest',
    45      /** Defines if the image should be tagged with the artifact version */
    46      'tagArtifactVersion'
    47  ])
    48  @Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
    49  
    50  /**
    51   * This step allows you to push a Docker image into a dedicated Container registry.
    52   *
    53   * By default an image available via the local Docker daemon will be pushed.
    54   *
    55   * In case you want to pull an existing image from a remote container registry, a source image and source registry needs to be specified.<br />
    56   * This makes it possible to move an image from one registry to another.
    57   */
    58  @GenerateDocumentation
    59  void call(Map parameters = [:]) {
    60      handlePipelineStepErrors (stepName: STEP_NAME, stepParameters: parameters) {
    61          final script = checkScript(this, parameters) ?: this
    62          String stageName = parameters.stageName ?: env.STAGE_NAME
    63  
    64          // load default & individual configuration
    65          Map config = ConfigurationHelper.newInstance(this)
    66              .loadStepDefaults([:], stageName)
    67              .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
    68              .mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
    69              .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
    70              .mixin(parameters, PARAMETER_KEYS)
    71              .addIfEmpty('sourceImage', script.commonPipelineEnvironment.getValue('containerImage'))
    72              .addIfEmpty('sourceRegistryUrl', script.commonPipelineEnvironment.getValue('containerRegistryUrl'))
    73              .mixin(artifactVersion: script.commonPipelineEnvironment.getArtifactVersion())
    74              .withMandatoryProperty('dockerCredentialsId')
    75              .withMandatoryProperty('dockerRegistryUrl')
    76              .use()
    77  
    78          DockerUtils dockerUtils = new DockerUtils(script)
    79  
    80          if (config.sourceRegistryUrl) {
    81              config.sourceRegistry = dockerUtils.getRegistryFromUrl(config.sourceRegistryUrl)
    82          }
    83  
    84          // telemetry reporting
    85          new Utils().pushToSWA([
    86              step: STEP_NAME
    87          ], config)
    88  
    89          if (!config.dockerImage)
    90              config.dockerImage = config.sourceImage
    91  
    92          if (dockerUtils.withDockerDaemon()) {
    93  
    94              //Prevent NullPointerException in case no dockerImage nor dockerBuildImage is provided
    95              if (!config.dockerImage && !config.dockerBuildImage) {
    96                  error "[${STEP_NAME}] Please provide a dockerImage (either in your config.yml or via step parameter)."
    97              }
    98              config.dockerBuildImage = config.dockerBuildImage?:docker.image(config.dockerImage)
    99  
   100              if (config.sourceRegistry && config.sourceImage) {
   101  
   102                  def sourceBuildImage = docker.image(config.sourceImage)
   103                  docker.withRegistry(
   104                      config.sourceRegistryUrl,
   105                      config.sourceCredentialsId
   106                  ) {
   107                      sourceBuildImage.pull()
   108                  }
   109                  sh "docker tag ${config.sourceRegistry}/${config.sourceImage} ${config.dockerImage}"
   110              }
   111  
   112              docker.withRegistry(
   113                  config.dockerRegistryUrl,
   114                  config.dockerCredentialsId
   115              ) {
   116                  config.dockerBuildImage.push()
   117                  if (config.tagLatest)
   118                      config.dockerBuildImage.push('latest')
   119                  if (config.tagArtifactVersion )
   120                      config.dockerBuildImage.push(config.artifactVersion)
   121              }
   122          } else {
   123              //handling for Kubernetes case
   124              dockerExecute(
   125                  script: script,
   126                  dockerImage: config.skopeoImage
   127              ) {
   128  
   129                  if (!config.dockerArchive && !config.dockerBuildImage) {
   130                      dockerUtils.moveImage([image: config.sourceImage, registryUrl: config.sourceRegistryUrl], [image: config.dockerImage, registryUrl: config.dockerRegistryUrl, credentialsId: config.dockerCredentialsId])
   131                      if (config.tagLatest) {
   132                          def latestImage = "${config.dockerImage.split(':')[0]}:latest"
   133                          dockerUtils.moveImage([image: config.sourceImage, registryUrl: config.sourceRegistryUrl], [image: latestImage, registryUrl: config.dockerRegistryUrl, credentialsId: config.dockerCredentialsId])
   134                      }
   135                      if (config.tagArtifactVersion) {
   136                          def imageName = "${config.dockerImage.split(':')[0]}:${config.artifactVersion}"
   137                          dockerUtils.moveImage([image: config.sourceImage, registryUrl: config.sourceRegistryUrl], [image: imageName, registryUrl: config.dockerRegistryUrl, credentialsId: config.dockerCredentialsId])
   138                      }
   139                  } else {
   140                      error "[${STEP_NAME}] Running on Kubernetes: Only moving images from one registry to another supported."
   141                  }
   142              }
   143          }
   144      }
   145  }