From 65374458a365a8c735eb50a39660e7c2545eeca0 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Wed, 8 Mar 2023 16:03:21 +0100 Subject: [PATCH 1/2] chore: add install method to docs --- static/install.sh | 201 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100755 static/install.sh diff --git a/static/install.sh b/static/install.sh new file mode 100755 index 0000000..9d63f7f --- /dev/null +++ b/static/install.sh @@ -0,0 +1,201 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Based on https://developer.fermyon.com/ install script thanks! +# Fancy colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' # No Color aka reset + +# Version to install. Defaults to latest or set by --version or -v +VERSION="" +FORCE_VERIFICATION=false +INSTALL_PATH=/usr/local/bin +PUBLIC_KEY_URL="https://chainloop.dev/cosign-releases.pub" + +# Print in colors - 0=green, 1=red, 2=neutral +# e.g. fancy_print 0 "All is great" +fancy_print() { + if [[ $1 == 0 ]]; then + echo -e "${GREEN}${2}${NC}" + elif [[ $1 == 1 ]]; then + echo -e "${RED}${2}${NC}" + else + echo -e "${2}" + fi +} + +downloadAndVerify() { + BASE_URL=$1 + URL="${BASE_URL}/${FILENAME}" + # Download file, exit if not found - e.g. version does not exist + fancy_print 0 "Step 1: Downloading: ${FILENAME}" + curl -fsL $URL -o $FILE || (fancy_print 1 "The requested file does not exist: ${URL}"; return 1) + fancy_print 0 "Done...\n" + + # Get checksum file and check it + fancy_print 0 "Step 1.2: Verifying checksum" + CHECKSUM_FILENAME=checksums.txt + CHECKSUM_FILE="${TMP_DIR}/${CHECKSUM_FILENAME}" + URL="${BASE_URL}/${CHECKSUM_FILENAME}" + curl -fsL $URL -o ${CHECKSUM_FILE} || (fancy_print 1 "The requested file does not exist: ${URL}"; return 1) + (cd ${TMP_DIR} && sha256sum --ignore-missing --quiet --check checksums.txt) + fancy_print 2 "Checksum OK\n" + + # Verify checksum file signature + if hash "cosign" &>/dev/null; then + # Constructing download FILE and URL + SIGNATURE_FILE="${CHECKSUM_FILENAME}.sig" + URL="${BASE_URL}/${SIGNATURE_FILE}" + # Download file, exit if not found - e.g. version does not exist + fancy_print 0 "Step 1.3: Verifying signature" + curl -fsOL $URL || (fancy_print 1 "The requested file does not exist: ${URL}"; return 1) + cosign verify-blob \ + --key ${PUBLIC_KEY_URL} \ + --signature ${SIGNATURE_FILE} \ + ${CHECKSUM_FILE} + + rm $SIGNATURE_FILE + else + fancy_print 2 "\nSignature verification skipped, cosign is not installed\n" + fi + + return +} + + +# Function to print the help message +print_help() { + fancy_print 2 "" + fancy_print 2 "---- Chainloop Installer Script ----" + fancy_print 2 "This script installs Chainloop in the current directory." + fancy_print 2 "" + fancy_print 2 "Command line arguments" + fancy_print 2 "--version or -v Provide what version to install e.g. \"v0.5.0\"." + fancy_print 2 "--path Installation path (default: /usr/local/bin)" + fancy_print 2 "--force-verification Force signature verification of the binary with cosign." + fancy_print 2 "--help or -h Shows this help message" +} + +# Function used to check if utilities are available +require() { + if ! hash "$1" &>/dev/null; then + fancy_print 1 "'$1' not found in PATH. This is required for this script to work." + exit 1 + fi +} + +# Parse input arguments +while [[ $# -gt 0 ]]; do + case $1 in + '--version' | -v) + shift + if [[ $# -ne 0 ]]; then + # Remove v prefix if provided + VERSION="$(echo ${1} | sed -e 's/^v\(.*\)/\1/')" + else + fancy_print 1 "Please provide the desired version. e.g. --version v0.5.0" + exit 0 + fi + ;; + '--help' | -h) + shift + print_help + ;; + '--force-verification') + FORCE_VERIFICATION=true + ;; + '--path') + shift + INSTALL_PATH=$1 + ;; + *) + fancy_print 1 "Unknown argument ${1}." + print_help + exit 1 + ;; + esac + shift +done + +# Check all required utilities are available +require curl +require tar +require uname + +if ! hash "cosign" &>/dev/null; then + if [[ $FORCE_VERIFICATION = true ]]; then + fancy_print 1 "--force-verification was set but Cosign is not present. Please download it from here https://docs.sigstore.dev/cosign/installation" + exit 1 + fi +fi + +# Check if we're on a supported system and get OS and processor architecture to download the right version +UNAME_ARC=$(uname -m) + +case $UNAME_ARC in +"x86_64") + ARC="amd64" + ;; +"arm64") + ARC="arm64" + ;; +*) + fancy_print 1 "The Processor type: ${UNAME_ARC} is not yet supported by Chainloop." + exit 1 + ;; +esac + +case $OSTYPE in +"linux-gnu"*) + OS="linux" + ;; +"darwin"*) + OS="darwin" + ;; +*) + fancy_print 1 "The OSTYPE: ${OSTYPE} is not supported by this script." + exit 1 + ;; +esac + +# Check desired version. Default to latest if no desired version was requested +if [[ $VERSION = "" ]]; then + VERSION=$(curl -so- https://github.com/chainloop-dev/chainloop/releases | grep 'href="/chainloop-dev/chainloop/releases/tag/v[0-9]*.[0-9]*.[0-9]*\"' | sed -E 's/.*\/chainloop-dev\/chainloop\/releases\/tag\/(v[0-9\.]+)".*/\1/g' | head -1) + # Remove v prefix + VERSION="$(echo ${VERSION} | sed -e 's/^v\(.*\)/\1/')" +fi + +# Temporary directory, works on Linux and macOS +TMP_DIR=$(mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir') +FILENAME="chainloop-cli-${VERSION}-${OS}-${ARC}.tar.gz" +# Constructing download FILE and URL +FILE="${TMP_DIR}/${FILENAME}" + +BASE_URL="https://github.com/chainloop-dev/chainloop/releases/download/v${VERSION}" +# Releases prior to Chainloop Open source are stored in a different location, we fallback if needed +# TODO: remove this fallback once we reach stable +FALLBACK_BASE_URL="https://storage.googleapis.com/chainloop-releases-public/cli/${VERSION}" + +downloadAndVerify $BASE_URL || downloadAndVerify $FALLBACK_BASE_URL + +# Decompress the file +fancy_print 0 "Step 2: Decompressing: ${FILE}" +BINARY_NAME="chainloop" +BINARY="${TMP_DIR}/chainloop" +(cd ${TMP_DIR} && tar xf $FILE) +fancy_print 0 "Done...\n" + +# Install +fancy_print 0 "Step 3: Installing: ${BINARY_NAME} in path ${INSTALL_PATH}" +install "${BINARY}" "${INSTALL_PATH}/" 2> /dev/null || sudo install "${BINARY}" "${INSTALL_PATH}/" + +# Remove the compressed file +fancy_print 0 "Step 4: Cleanup" +rm -r ${TMP_DIR} +fancy_print 0 "Done...\n" +${INSTALL_PATH}/${BINARY_NAME} version + + +fancy_print 2 "Check here for the next steps: https://docs.chainloop.dev\n" +fancy_print 2 "Run '${BINARY_NAME} auth login' to get started" From b9856d608d9122656b592c7bf01f1931421f2dbc Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Wed, 8 Mar 2023 16:07:14 +0100 Subject: [PATCH 2/2] remove fallback --- static/install.sh | 74 ++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 42 deletions(-) diff --git a/static/install.sh b/static/install.sh index 9d63f7f..83a9394 100755 --- a/static/install.sh +++ b/static/install.sh @@ -25,44 +25,6 @@ fancy_print() { fi } -downloadAndVerify() { - BASE_URL=$1 - URL="${BASE_URL}/${FILENAME}" - # Download file, exit if not found - e.g. version does not exist - fancy_print 0 "Step 1: Downloading: ${FILENAME}" - curl -fsL $URL -o $FILE || (fancy_print 1 "The requested file does not exist: ${URL}"; return 1) - fancy_print 0 "Done...\n" - - # Get checksum file and check it - fancy_print 0 "Step 1.2: Verifying checksum" - CHECKSUM_FILENAME=checksums.txt - CHECKSUM_FILE="${TMP_DIR}/${CHECKSUM_FILENAME}" - URL="${BASE_URL}/${CHECKSUM_FILENAME}" - curl -fsL $URL -o ${CHECKSUM_FILE} || (fancy_print 1 "The requested file does not exist: ${URL}"; return 1) - (cd ${TMP_DIR} && sha256sum --ignore-missing --quiet --check checksums.txt) - fancy_print 2 "Checksum OK\n" - - # Verify checksum file signature - if hash "cosign" &>/dev/null; then - # Constructing download FILE and URL - SIGNATURE_FILE="${CHECKSUM_FILENAME}.sig" - URL="${BASE_URL}/${SIGNATURE_FILE}" - # Download file, exit if not found - e.g. version does not exist - fancy_print 0 "Step 1.3: Verifying signature" - curl -fsOL $URL || (fancy_print 1 "The requested file does not exist: ${URL}"; return 1) - cosign verify-blob \ - --key ${PUBLIC_KEY_URL} \ - --signature ${SIGNATURE_FILE} \ - ${CHECKSUM_FILE} - - rm $SIGNATURE_FILE - else - fancy_print 2 "\nSignature verification skipped, cosign is not installed\n" - fi - - return -} - # Function to print the help message print_help() { @@ -173,11 +135,39 @@ FILENAME="chainloop-cli-${VERSION}-${OS}-${ARC}.tar.gz" FILE="${TMP_DIR}/${FILENAME}" BASE_URL="https://github.com/chainloop-dev/chainloop/releases/download/v${VERSION}" -# Releases prior to Chainloop Open source are stored in a different location, we fallback if needed -# TODO: remove this fallback once we reach stable -FALLBACK_BASE_URL="https://storage.googleapis.com/chainloop-releases-public/cli/${VERSION}" -downloadAndVerify $BASE_URL || downloadAndVerify $FALLBACK_BASE_URL +URL="${BASE_URL}/${FILENAME}" +# Download file, exit if not found - e.g. version does not exist +fancy_print 0 "Step 1: Downloading: ${FILENAME}" +curl -fsL $URL -o $FILE || (fancy_print 1 "The requested file does not exist: ${URL}"; exit 1) +fancy_print 0 "Done...\n" + +# Get checksum file and check it +fancy_print 0 "Step 1.2: Verifying checksum" +CHECKSUM_FILENAME=checksums.txt +CHECKSUM_FILE="${TMP_DIR}/${CHECKSUM_FILENAME}" +URL="${BASE_URL}/${CHECKSUM_FILENAME}" +curl -fsL $URL -o ${CHECKSUM_FILE} || (fancy_print 1 "The requested file does not exist: ${URL}"; exit 1) +(cd ${TMP_DIR} && sha256sum --ignore-missing --quiet --check checksums.txt) +fancy_print 2 "Checksum OK\n" + +# Verify checksum file signature +if hash "cosign" &>/dev/null; then + # Constructing download FILE and URL + SIGNATURE_FILE="${CHECKSUM_FILENAME}.sig" + URL="${BASE_URL}/${SIGNATURE_FILE}" + # Download file, exit if not found - e.g. version does not exist + fancy_print 0 "Step 1.3: Verifying signature" + curl -fsOL $URL || (fancy_print 1 "The requested file does not exist: ${SIGNATURE_FILE}"; exit 1) + cosign verify-blob \ + --key ${PUBLIC_KEY_URL} \ + --signature ${SIGNATURE_FILE} \ + ${CHECKSUM_FILE} + + rm $SIGNATURE_FILE +else + fancy_print 2 "\nSignature verification skipped, cosign is not installed\n" +fi # Decompress the file fancy_print 0 "Step 2: Decompressing: ${FILE}"