github.com/hashicorp/packer@v1.14.3/scripts/codesign_example.sh (about)

     1  #! /usr/bin/env bash
     2  # Copyright (c) HashiCorp, Inc.
     3  # SPDX-License-Identifier: BUSL-1.1
     4  
     5  set -euo pipefail
     6  
     7  # first makes some assertions about the environment and set some shared
     8  # variables before starting the script.
     9  if ! command -v jq > /dev/null 2>&1; then
    10    echo "This script requires jq to work properly."
    11    exit 1
    12  fi
    13  
    14  if ! command -v sha256sum > /dev/null 2>&1; then
    15    if !command -v gsha256sum > /dev/null 2>&1; then
    16      echo "This script requires sha256sum (linux) or gsha256sum (osx) to work properly."
    17      exit 1
    18    else
    19      SHASUM_PROG=gsha256sum
    20    fi
    21  else
    22    SHASUM_PROG=sha256sum
    23  fi
    24  
    25  PRODUCT_NAME="${PRODUCT_NAME:-""}"
    26  if [ -z "$PRODUCT_NAME" ]; then
    27    echo "Missing required product name: ${PRODUCT_NAME}"
    28    exit 1
    29  fi
    30  
    31  TARGET_ZIP="${TARGET_ZIP:-""}"
    32  if [ -z "$TARGET_ZIP" ]; then
    33    echo "Missing required target path"
    34    exit 1
    35  fi
    36  
    37  # Artifactory configuration
    38  ARTIFACTORY_ENDPOINT="${ARTIFACTORY_ENDPOINT:-"https://artifactory.hashicorp.engineering/artifactory"}"
    39  ARTIFACTORY_INPUT_REPO="${ARTIFACTORY_INPUT_REPO:-"hc-signing-input"}"
    40  ARTIFACTORY_OUTPUT_REPO="${ARTIFACTORY_OUTPUT_REPO:-"hc-signing-output"}"
    41  
    42  ARTIFACTORY_TOKEN="${ARTIFACTORY_TOKEN:-""}"
    43  ARTIFACTORY_USER="${ARTIFACTORY_USER:-""}"
    44  
    45  if [[ -z "$ARTIFACTORY_TOKEN" || -z "$ARTIFACTORY_USER" ]]; then
    46    echo "Missing required Artifactory credentials"
    47    exit 1
    48  fi
    49  
    50  # Create the sign/notarize ID "SN_ID"
    51  if command -v uuidgen > /dev/null 2>&1; then
    52    uuid="$(uuidgen)"
    53  elif [ -f /proc/sys/kernel/random/uuid ]; then
    54    uuid="$(cat /proc/sys/kernel/random/uuid)"
    55  else
    56    echo "This script needs some way to generate a uuid."
    57    exit 1
    58  fi
    59  SN_ID="$uuid"
    60  
    61  # CircleCI configuration
    62  CIRCLE_ENDPOINT="${CIRCLE_ENDPOINT:-"https://circleci.com/api/v2"}"
    63  CIRCLE_PROJECT="${CIRCLE_PROJECT:-"project/github/hashicorp/circle-codesign"}"
    64  
    65  CIRCLE_TOKEN="${CIRCLE_TOKEN:-""}"
    66  if [ -z "$CIRCLE_TOKEN" ]; then
    67    echo "Missing required CircleCI credentials"
    68    exit 1
    69  fi
    70  
    71  # Next, upload an unsigned zip file to the Artifactory at
    72  # https://artifactory.hashicorp.engineering/artifactory/hc-signing-input/{PRODUCT}/{ID}.zip
    73  echo "Uploading unsigned zip to ${ARTIFACTORY_ENDPOINT}/${ARTIFACTORY_INPUT_REPO}/${PRODUCT_NAME}/${SN_ID}.zip"
    74  
    75  curl --show-error --silent --fail \
    76    --user "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" \
    77    --request PUT \
    78    "${ARTIFACTORY_ENDPOINT}/${ARTIFACTORY_INPUT_REPO}/${PRODUCT_NAME}/${SN_ID}.zip" \
    79    --upload-file "$TARGET_ZIP" > /dev/null
    80  
    81  # Next, start the CircleCI Pipeline, then wait for a Workflow
    82  # to start.
    83  echo "Executing CircleCI job"
    84  
    85  res="$(curl --show-error --silent --fail --user "${CIRCLE_TOKEN}:" \
    86    --request POST \
    87    --header 'Content-Type: application/json' \
    88    --header 'Accept: application/json' \
    89    --data "{ \"branch\": \"main\" ,\"parameters\": { \"PRODUCT\": \"${PRODUCT_NAME}\", \"PKG_NAME\": \"${SN_ID}.zip\" } }" \
    90    "${CIRCLE_ENDPOINT}/${CIRCLE_PROJECT}/pipeline")"
    91  pipeline_id="$(echo "$res" | jq -r '.id')"
    92  echo "CircleCI Pipeline $pipeline_id started"
    93  
    94  echo -n "Retrieving CircleCI Workflow ID"
    95  # 24 * 5 seconds = 2 minutes
    96  counter=12
    97  workflow_id=""
    98  # wait until a Workflow ID is found
    99  until [ "$workflow_id" != "" ]; do
   100    echo -n "."
   101    workflow_id=$(curl --silent --fail --user "${CIRCLE_TOKEN}:" \
   102      --request GET \
   103      --header 'Accept: application/json' \
   104      "${CIRCLE_ENDPOINT}/pipeline/${pipeline_id}/workflow" \
   105      | jq -r '.items[].id'
   106    )
   107   if [ "$counter" -eq "0" ]; then
   108      echo "Tried too many times, but Pipeline ${pipeline_id} still has no Workflows"
   109      exit 1
   110    fi
   111    counter=$((counter - 1))
   112    sleep 5
   113  done
   114  echo ""
   115  
   116  echo "CircleCI Workflow $workflow_id started"
   117  
   118  # Next, wait for the Workflow to reach a terminal state, then fails if it isn't
   119  # "success"
   120  echo -n "Waiting for CircleCI Workflow ID: ${workflow_id}"
   121  # 360 * 5 seconds = 30 minutes
   122  counter=360
   123  finished="not_run"
   124  # wait for one of the terminal states: ["success", "failed", "error", "canceled"]
   125  until [[ "$finished" == "success" || "$finished" == "failed" || "$finished" == "error" || "$finished" == "canceled" ]]; do
   126    echo -n "."
   127    finished=$(curl --silent --fail --user "${CIRCLE_TOKEN}:" \
   128      --header 'Accept: application/json' \
   129      "${CIRCLE_ENDPOINT}/workflow/${workflow_id}" \
   130      | jq -r '.status'
   131    )
   132    if [ "$counter" -eq "0" ]; then
   133      echo "Tried too many times, but workflow is still in state ${finished}"
   134      exit 1
   135    fi
   136    counter=$((counter - 1))
   137    sleep 5
   138  done
   139  echo ""
   140  
   141  if [ "$finished" != "success" ]; then
   142    echo "Workflow ID ${workflow_id} ${finished}"
   143    exit 1
   144  fi
   145  
   146  # Next, download the signed zip from Artifactory at
   147  # https://artifactory.hashicorp.engineering/artifactory/hc-signing-output/{PRODUCT}/{ID}.zip
   148  echo "Retrieving signed zip from ${ARTIFACTORY_ENDPOINT}/${ARTIFACTORY_OUTPUT_REPO}/${PRODUCT_NAME}/${SN_ID}.zip"
   149  
   150  curl --show-error --silent --fail --user "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" \
   151    --request GET \
   152    "${ARTIFACTORY_ENDPOINT}/${ARTIFACTORY_OUTPUT_REPO}/${PRODUCT_NAME}/${SN_ID}.zip" \
   153    --output "signed_${SN_ID}.zip"
   154  
   155  signed_checksum=$(
   156    curl --silent --show-error --fail --user "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" \
   157      --head \
   158      "${ARTIFACTORY_ENDPOINT}/${ARTIFACTORY_OUTPUT_REPO}/${PRODUCT_NAME}/${SN_ID}.zip" \
   159      | grep -i "x-checksum-sha256" | awk 'gsub("[\r\n]", "", $2) {print $2;}'
   160  )
   161  
   162  echo "${signed_checksum}  signed_${SN_ID}.zip" | $SHASUM_PROG -c
   163  if [ $? -ne 0 ]; then
   164    exit 1
   165  fi
   166  
   167  mv "signed_${SN_ID}.zip" "$TARGET_ZIP"