diff --git a/.github/workflows/release_build_infisical_cli.yml b/.github/workflows/release_build_infisical_cli.yml index c592daf81..d93e08ff1 100644 --- a/.github/workflows/release_build_infisical_cli.yml +++ b/.github/workflows/release_build_infisical_cli.yml @@ -1,132 +1,145 @@ name: Build and release CLI on: - workflow_dispatch: + workflow_dispatch: - push: - # run only against tags - tags: - - "infisical-cli/v*.*.*" + push: + # run only against tags + tags: + - "infisical-cli/v*.*.*" permissions: - contents: write + contents: write jobs: - cli-integration-tests: - name: Run tests before deployment - uses: ./.github/workflows/run-cli-tests.yml - secrets: - CLI_TESTS_UA_CLIENT_ID: ${{ secrets.CLI_TESTS_UA_CLIENT_ID }} - CLI_TESTS_UA_CLIENT_SECRET: ${{ secrets.CLI_TESTS_UA_CLIENT_SECRET }} - CLI_TESTS_SERVICE_TOKEN: ${{ secrets.CLI_TESTS_SERVICE_TOKEN }} - CLI_TESTS_PROJECT_ID: ${{ secrets.CLI_TESTS_PROJECT_ID }} - CLI_TESTS_ENV_SLUG: ${{ secrets.CLI_TESTS_ENV_SLUG }} - CLI_TESTS_USER_EMAIL: ${{ secrets.CLI_TESTS_USER_EMAIL }} - CLI_TESTS_USER_PASSWORD: ${{ secrets.CLI_TESTS_USER_PASSWORD }} - CLI_TESTS_INFISICAL_VAULT_FILE_PASSPHRASE: ${{ secrets.CLI_TESTS_INFISICAL_VAULT_FILE_PASSPHRASE }} + cli-integration-tests: + name: Run tests before deployment + uses: ./.github/workflows/run-cli-tests.yml + secrets: + CLI_TESTS_UA_CLIENT_ID: ${{ secrets.CLI_TESTS_UA_CLIENT_ID }} + CLI_TESTS_UA_CLIENT_SECRET: ${{ secrets.CLI_TESTS_UA_CLIENT_SECRET }} + CLI_TESTS_SERVICE_TOKEN: ${{ secrets.CLI_TESTS_SERVICE_TOKEN }} + CLI_TESTS_PROJECT_ID: ${{ secrets.CLI_TESTS_PROJECT_ID }} + CLI_TESTS_ENV_SLUG: ${{ secrets.CLI_TESTS_ENV_SLUG }} + CLI_TESTS_USER_EMAIL: ${{ secrets.CLI_TESTS_USER_EMAIL }} + CLI_TESTS_USER_PASSWORD: ${{ secrets.CLI_TESTS_USER_PASSWORD }} + CLI_TESTS_INFISICAL_VAULT_FILE_PASSPHRASE: ${{ secrets.CLI_TESTS_INFISICAL_VAULT_FILE_PASSPHRASE }} - npm-release: - runs-on: ubuntu-latest + npm-release: + runs-on: ubuntu-latest + env: + working-directory: ./npm + needs: + - cli-integration-tests + - goreleaser + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Extract version + run: | + VERSION=$(echo ${{ github.ref_name }} | sed 's/infisical-cli\/v//') + echo "Version extracted: $VERSION" + echo "CLI_VERSION=$VERSION" >> $GITHUB_ENV + + - name: Print version + run: echo ${{ env.CLI_VERSION }} + + - name: Setup Node + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0 + with: + node-version: 20 + cache: "npm" + cache-dependency-path: ./npm/package-lock.json + - name: Install dependencies + working-directory: ${{ env.working-directory }} + run: npm install --ignore-scripts + + - name: Set NPM version + working-directory: ${{ env.working-directory }} + run: npm version ${{ env.CLI_VERSION }} --allow-same-version --no-git-tag-version + + - name: Setup NPM + working-directory: ${{ env.working-directory }} + run: | + echo 'registry="https://registry.npmjs.org/"' > ./.npmrc + echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ./.npmrc + + echo 'registry="https://registry.npmjs.org/"' > ~/.npmrc + echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc env: - working-directory: ./npm - needs: - - cli-integration-tests - - goreleaser - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - name: Extract version - run: | - VERSION=$(echo ${{ github.ref_name }} | sed 's/infisical-cli\/v//') - echo "Version extracted: $VERSION" - echo "CLI_VERSION=$VERSION" >> $GITHUB_ENV + - name: Pack NPM + working-directory: ${{ env.working-directory }} + run: npm pack - - name: Print version - run: echo ${{ env.CLI_VERSION }} + - name: Publish NPM + working-directory: ${{ env.working-directory }} + run: npm publish --tarball=./infisical-sdk-${{github.ref_name}} --access public --registry=https://registry.npmjs.org/ + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - name: Setup Node - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0 - with: - node-version: 20 - cache: "npm" - cache-dependency-path: ./npm/package-lock.json - - name: Install dependencies - working-directory: ${{ env.working-directory }} - run: npm install --ignore-scripts - - - name: Set NPM version - working-directory: ${{ env.working-directory }} - run: npm version ${{ env.CLI_VERSION }} --allow-same-version --no-git-tag-version - - - name: Setup NPM - working-directory: ${{ env.working-directory }} - run: | - echo 'registry="https://registry.npmjs.org/"' > ./.npmrc - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ./.npmrc - - echo 'registry="https://registry.npmjs.org/"' > ~/.npmrc - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: Pack NPM - working-directory: ${{ env.working-directory }} - run: npm pack - - - name: Publish NPM - working-directory: ${{ env.working-directory }} - run: npm publish --tarball=./infisical-sdk-${{github.ref_name}} --access public --registry=https://registry.npmjs.org/ - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - goreleaser: - runs-on: ubuntu-latest - needs: [cli-integration-tests] - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: 🐋 Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: 🔧 Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - run: git fetch --force --tags - - run: echo "Ref name ${{github.ref_name}}" - - uses: actions/setup-go@v3 - with: - go-version: ">=1.19.3" - cache: true - cache-dependency-path: cli/go.sum - - name: Setup for libssl1.0-dev - run: | - echo 'deb http://security.ubuntu.com/ubuntu bionic-security main' | sudo tee -a /etc/apt/sources.list - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32 - sudo apt update - sudo apt-get install -y libssl1.0-dev - - name: OSXCross for CGO Support - run: | - mkdir ../../osxcross - git clone https://github.com/plentico/osxcross-target.git ../../osxcross/target - - uses: goreleaser/goreleaser-action@v4 - with: - distribution: goreleaser-pro - version: v1.26.2-pro - args: release --clean - env: - GITHUB_TOKEN: ${{ secrets.GO_RELEASER_GITHUB_TOKEN }} - POSTHOG_API_KEY_FOR_CLI: ${{ secrets.POSTHOG_API_KEY_FOR_CLI }} - FURY_TOKEN: ${{ secrets.FURYPUSHTOKEN }} - AUR_KEY: ${{ secrets.AUR_KEY }} - GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} - - uses: actions/setup-python@v4 - - run: pip install --upgrade cloudsmith-cli - - name: Publish to CloudSmith - run: sh cli/upload_to_cloudsmith.sh - env: - CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }} + goreleaser: + runs-on: ubuntu-latest + needs: [cli-integration-tests] + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: 🐋 Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: 🔧 Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - run: git fetch --force --tags + - run: echo "Ref name ${{github.ref_name}}" + - uses: actions/setup-go@v3 + with: + go-version: ">=1.19.3" + cache: true + cache-dependency-path: cli/go.sum + - name: Setup for libssl1.0-dev + run: | + echo 'deb http://security.ubuntu.com/ubuntu bionic-security main' | sudo tee -a /etc/apt/sources.list + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32 + sudo apt update + sudo apt-get install -y libssl1.0-dev + - name: OSXCross for CGO Support + run: | + mkdir ../../osxcross + git clone https://github.com/plentico/osxcross-target.git ../../osxcross/target + - uses: goreleaser/goreleaser-action@v4 + with: + distribution: goreleaser-pro + version: v1.26.2-pro + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GO_RELEASER_GITHUB_TOKEN }} + POSTHOG_API_KEY_FOR_CLI: ${{ secrets.POSTHOG_API_KEY_FOR_CLI }} + FURY_TOKEN: ${{ secrets.FURYPUSHTOKEN }} + AUR_KEY: ${{ secrets.AUR_KEY }} + GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} + - uses: actions/setup-python@v4 + - run: pip install --upgrade cloudsmith-cli + - uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1 + with: + ruby-version: "3.1" # Not needed with a .ruby-version file + - name: Install deb-s3 + run: gem install deb-s3 + - name: Configure GPG Key + run: echo -n "$GPG_SIGNING_KEY" | base64 --decode | gpg --import + env: + GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} + - name: Publish to CloudSmith + run: sh cli/upload_to_cloudsmith.sh + env: + CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }} + INFISICAL_CLI_S3_BUCKET: ${{ secrets.INFISICAL_CLI_S3_BUCKET }} + INFISICAL_CLI_REPO_SIGNING_KEY_ID: ${{ secrets.INFISICAL_CLI_REPO_SIGNING_KEY_ID }} + AWS_ACCESS_KEY_ID: ${{ secrets.INFISICAL_CLI_REPO_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.INFISICAL_CLI_REPO_AWS_SECRET_ACCESS_KEY }} diff --git a/cli/packages/cmd/root.go b/cli/packages/cmd/root.go index 04af9cce8..5096178b3 100644 --- a/cli/packages/cmd/root.go +++ b/cli/packages/cmd/root.go @@ -50,6 +50,7 @@ func init() { config.INFISICAL_URL = util.AppendAPIEndpoint(config.INFISICAL_URL) + util.DisplayAptInstallationChangeBanner() if !util.IsRunningInDocker() && !silent { util.CheckForUpdate() } diff --git a/cli/packages/util/check-for-update.go b/cli/packages/util/check-for-update.go index f3aca2776..06c161b5d 100644 --- a/cli/packages/util/check-for-update.go +++ b/cli/packages/util/check-for-update.go @@ -53,6 +53,21 @@ func CheckForUpdate() { } } +func DisplayAptInstallationChangeBanner() { + if runtime.GOOS == "linux" { + _, err := exec.LookPath("apt-get") + isApt := err == nil + if isApt { + yellow := color.New(color.FgYellow).SprintFunc() + msg := fmt.Sprintf("%s", + yellow("Update Required: Your current package installation script is outdated and will no longer receive updates.\nPlease update to the new installation script which can be found here https://infisical.com/docs/cli/overview#installation debian section\n"), + ) + + fmt.Fprintln(os.Stderr, msg) + } + } +} + func getLatestTag(repoOwner string, repoName string) (string, string, error) { url := fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/latest", repoOwner, repoName) resp, err := http.Get(url) diff --git a/cli/scripts/install-cli-deb.sh b/cli/scripts/install-cli-deb.sh new file mode 100644 index 000000000..ef24bcadc --- /dev/null +++ b/cli/scripts/install-cli-deb.sh @@ -0,0 +1,551 @@ +#!/usr/bin/env bash +# +# The core commands execute start from the "MAIN" section below. +# + +test -z "$BASH_SOURCE" && { + self="sudo -E bash" + prefix=" |" +} || { + self=$(readlink -f ${BASH_SOURCE:-$0}) + prefix="" +} + +tmp_log=$(mktemp .s3_setup_XXXXXXXXX) + +# Environment variables that can be set +PKG_URL=${PKG_URL:-"https://artifacts-cli.infisical.com"} +PKG_PATH=${PKG_PATH:-"deb"} +PACKAGE_NAME=${PACKAGE_NAME:-"infisical"} +GPG_KEY_URL=${GPG_KEY_URL:-"${PKG_URL}/infisical.gpg"} + +colours=$(tput colors 2>/dev/null || echo "256") +no_colour="\e[39;49m" +green_colour="\e[32m" +red_colour="\e[41;97m" +bold="\e[1m" +reset="\e[0m" +use_colours=$(test -n "$colours" && test $colours -ge 8 && echo "yes") +test "$use_colours" == "yes" || { + no_colour="" + green_colour="" + red_colour="" + bold="" + reset="" +} + +example_name="Ubuntu/Focal (20.04)" +example_distro="ubuntu" +example_codename="focal" +example_version="20.04" + +function echo_helptext { + local help_text="$*" + echo " ^^^^: ... $help_text" +} + +function die { + local text="$@" + test ! -z "$text" && { + echo_helptext "$text" 1>&2 + } + + local prefix="${red_colour} !!!!${no_colour}" + + echo -e "$prefix: Oh no, your setup failed! :-( ... But we might be able to help. :-)" + echo -e "$prefix: " + echo -e "$prefix: ${bold}Please check your S3 bucket configuration and try again.${reset}" + echo -e "$prefix: " + + test -f "$tmp_log" && { + local n=20 + echo -e "$prefix: Last $n log lines from $tmp_log (might not be errors, nor even relevant):" + echo -e "$prefix:" + check_tool_silent "xargs" && { + check_tool_silent "fmt" && { + tail -n $n $tmp_log | fmt -t | xargs -Ilog echo -e "$prefix: > log" + } || { + tail -n $n $tmp_log | xargs -Ilog echo -e "$prefix: > log" + } + } || { + echo + tail -n $n $tmp_log + } + } + exit 1 +} + +function echo_colour { + local colour="${1:-"no"}_colour"; shift + echo -e "${!colour}$@${no_colour}" +} + +function echo_green_or_red { + local rc="$1" + local good="${2:-YES}" + local bad="${3:-NO}" + + test "$rc" -eq 0 && { + echo_colour "green" "$good" + } || { + echo_colour "red" "$bad" + } + return $rc +} + +function echo_clearline { + local rc="$?" + echo -e -n "\033[1K\r" + return $rc +} + +function echo_status { + local rc="$1" + local good="$2" + local bad="$3" + local text="$4" + local help_text="$5" + local newline=$(test "$6" != "no" && echo "\n" || echo "") + local status_text=$(echo_green_or_red "$rc" "$good" "$bad") + + echo_clearline + local width=$(test "$use_colours" == "yes" && echo "16" || echo "5") + printf "%${width}s %s${newline}" "${status_text}:" "$text" + test $rc -ne 0 && test ! -z "$help_text" && { + echo_helptext "$help_text" + echo + } + + return $rc +} + +function echo_running { + local rc=$? + local text="$1" + echo_status 0 " RUN" " RUN" "$text" "" "no" + return $rc +} + +function echo_okfail_rc { + local rc=$1 + local text="$2" + local help_text="$3" + echo_clearline + echo_status $rc " OK" " NOPE" "$text" "$help_text" + return $rc +} + +function echo_okfail { + echo_okfail_rc $? "$@" + return $? +} + +function check_tool_silent { + local tool=${1} + command -v $tool &>/dev/null || which $tool &>/dev/null + return $? +} + +function check_tool { + local tool=${1} + local optional=${2:-false} + local required_text="optional" + if ! $optional; then required_text="required"; fi + local text="Checking for $required_text executable '$tool' ..." + echo_running "$text" + check_tool_silent "$tool" + echo_okfail "$text" || { + if ! $optional; then + die "$tool is not installed, but is required by this script." + fi + return 1 + } + return 0 +} + +function cleanup { + echo + rm -rf $tmp_log +} + +function shutdown { + echo_colour "red" " !!!!: Operation cancelled by user!" + exit 2 +} + +function check_os { + test ! -z "$distro" && test ! -z "${version}${codename}" + return $? +} + +function detect_os_system { + check_os && return 0 + echo_running "$text" + local text="Detecting your OS distribution and release using system methods ..." + + local tool_rc=1 + test -f '/etc/os-release' && { + . /etc/os-release + distro=${distro:-$ID} + codename=${codename:-$VERSION_CODENAME} + codename=${codename:-$(echo $VERSION | cut -d '(' -f 2 | cut -d ')' -f 1)} + version=${version:-$VERSION_ID} + + test -z "${version}${codename}" && test -f '/etc/debian_version' && { + # Workaround for Debian unstable releases; get the codename from debian_version + codename=$(cat /etc/debian_version | cut -d '/' -f1) + } + + tool_rc=0 + } + + check_os + local rc=$? + echo_okfail_rc $rc "$text" + + test $tool_rc -eq 0 && { + report_os_expanded + } + + return $rc +} + +function report_os_attribute { + local name=$1 + local value=$2 + local coloured="" + echo -n "$name=" + test -z "$value" && { + echo -e -n "${red_colour}${no_colour} " + } || { + echo -e -n "${green_colour}${value}${no_colour} " + } +} + +function report_os_expanded { + echo_helptext "Detected/provided for your OS/distribution, version and architecture:" + echo " >>>>:" + report_os_values +} + +function report_os_values { + echo -n " >>>>: ... " + report_os_attribute "distro" $distro + report_os_attribute "codename" "stable (fixed)" + report_os_attribute "arch" $arch + echo + echo " >>>>:" +} + +function detect_os_legacy_python { + check_os && return 0 + + local text="Detecting your OS distribution and release using legacy python ..." + echo_running "$text" + + IFS='' read -r -d '' script <<-'EOF' +from __future__ import unicode_literals, print_function +import platform; +info = platform.linux_distribution() or ('', '', ''); +for key, value in zip(('distro', 'version', 'codename'), info): + print("local guess_%s=\"%s\"\n" % (key, value.lower().replace(' ', ''))); +EOF + + local tool_rc=1 + check_tool_silent "python" && { + eval $(python -c "$script") + distro=${distro:-$guess_distro} + codename=${codename:-$guess_codename} + version=${version:-$guess_version} + tool_rc=$? + } + + check_os + local rc=$? + echo_okfail_rc $rc "$text" + + check_tool_silent "python" || { + echo_helptext "Python isn't available, so skipping detection method (hint: install python)" + } + + test $tool_rc -eq 0 && { + report_os + } + + return $rc +} + +function detect_os_modern_python { + check_os && return 0 + + check_tool_silent "python" && { + local text="Ensuring python-pip is installed ..." + echo_running "$text" + check_tool_silent "pip" + echo_okfail "$text" || { + local text="Checking if pip can be bootstrapped without get-pip ..." + echo_running "$text" + python -m ensurepip --default-pip &>$tmp_log + echo_okfail "$text" || { + local text="Installing pip via get-pip bootstrap ..." + echo_running "$text" + curl -1sLf https://bootstrap.pypa.io/get-pip.py 2>$tmp/log | python &>$tmp_log + echo_okfail "$text" || die "Failed to install pip!" + } + } + + local text="Installing 'distro' python library ..." + echo_running "$text" + python -c 'import distro' &>$tmp_log || python -m pip install distro &>$tmp_log + echo_okfail "$text" || die "Failed to install required 'distro' python library!" + } + + IFS='' read -r -d '' script <<-'EOF' +from __future__ import unicode_literals, print_function +import distro; +info = distro.linux_distribution(full_distribution_name=False) or ('', '', ''); +for key, value in zip(('distro', 'version', 'codename'), info): + print("local guess_%s=\"%s\"\n" % (key, value.lower().replace(' ', ''))); +EOF + + local text="Detecting your OS distribution and release using modern python ..." + echo_running "$text" + + local tool_rc=1 + check_tool_silent "python" && { + eval $(python -c "$script") + distro=${distro:-$guess_distro} + codename=${codename:-$guess_codename} + version=${version:-$guess_version} + tool_rc=$? + } + + check_os + local rc=$? + echo_okfail_rc $rc "$text" + + check_tool_silent "python" || { + echo_helptext "Python isn't available, so skipping detection method (hint: install python)" + } + + test $tool_rc -eq 0 && { + report_os_expanded + } + + return $rc +} + +function detect_os { + # Backwards compat for old distribution parameter names + distro=${distro:-$os} + + # Always use "stable" as the codename + codename="stable" + + arch=${arch:-$(arch || uname -m)} + + # Only detect OS if not manually specified + if [ -z "$distro" ]; then + detect_os_system || + detect_os_legacy_python || + detect_os_modern_python + fi + + # Always ensure we have a distro + (test -z "$distro") && { + echo_okfail_rc "1" "Unable to detect your OS distribution!" + cat <>>>: + >>>>: The 'distro' value is required. Without it, the install script + >>>>: cannot retrieve the correct configuration for this system. + >>>>: + >>>>: You can force this script to use a particular value by specifying distro + >>>>: via environment variable. E.g., to specify a distro + >>>>: such as $example_name, use the following: + >>>>: + >>>>: $prefix distro=$example_distro $self + >>>>: +EOF + die + } +} + +function create_repo_config { + if [ -z "$PKG_PATH" ]; then + repo_url="${PKG_URL}" + else + repo_url="${PKG_URL}/${PKG_PATH}" + fi + + # Create configuration with GPG key verification + local gpg_keyring_path="/usr/share/keyrings/${PACKAGE_NAME}-archive-keyring.gpg" + local apt_conf=$(cat <>>>: + >>>>: It looks like we can't access the GPG key at ${GPG_KEY_URL} + >>>>: +EOF + die + } +} + +function check_dpkg_tool { + local tool=${1} + local required=${2:-true} + local install=${3:-true} + + local text="Checking for apt dependency '$tool' ..." + echo_running "$text" + dpkg -l | grep "$tool\>" &>$tmp_log + echo_okfail "$text" || { + if $install; then + test "$apt_updated" == "yes" || update_apt + local text="Attempting to install '$tool' ..." + echo_running "$text" + apt-get install -y "$tool" &>$tmp_log + echo_okfail "$text" || { + if $required; then + die "Could not install '$tool', check your permissions, etc." + fi + } + else { + if $required; then + die "$tool is not installed, but is required by this script." + fi + } + fi + } + return 0 +} + +function update_apt { + local text="Updating apt repository metadata cache ..." + local tmp_log=$(mktemp .s3_deb_output_XXXXXXXXX.log) + echo_running "$text" + apt-get update &>$tmp_log + echo_okfail "$text" || { + echo_colour "red" "Failed to update via apt-get update" + cat $tmp_log + rm -rf $tmp_log + die "Failed to update via apt-get update - Context above (maybe no packages?)." + } + rm -rf $tmp_log + apt_updated="yes" +} + +function install_apt_prereqs { + # Debian-archive-keyring has to be installed for apt-transport-https. + test "${distro}" == "debian" && { + check_dpkg_tool "debian-keyring" + check_dpkg_tool "debian-archive-keyring" + } + + check_dpkg_tool "apt-transport-https" + check_dpkg_tool "ca-certificates" false + check_dpkg_tool "gnupg" +} + +function import_gpg_key { + local text="Importing '$PACKAGE_NAME' repository GPG key from S3 ..." + echo_running "$text" + + local gpg_keyring_path="/usr/share/keyrings/${PACKAGE_NAME}-archive-keyring.gpg" + + # Check if GPG key is accessible + check_gpg_key + + # Download and import GPG key + curl -1sLf "${GPG_KEY_URL}" | gpg --dearmor > $gpg_keyring_path + chmod 644 $gpg_keyring_path + + # Check for older apt versions that don't support signed-by + local signed_by_version="1.1" + local detected_version=$(dpkg -s apt | grep Version | cut -d' ' -f2) + + if [ "$(printf "%s\n" $detected_version $signed_by_version | sort -V | head -n 1)" != "$signed_by_version" ]; then + echo_helptext "Detected older apt version without signed-by support. Copying key to trusted.gpg.d." + cp ${gpg_keyring_path} /etc/apt/trusted.gpg.d/${PACKAGE_NAME}.gpg + chmod 644 /etc/apt/trusted.gpg.d/${PACKAGE_NAME}.gpg + fi + + echo_okfail "$text" || die "Could not import the GPG key for this repository" +} + +function setup_repository { + local repo_path="/etc/apt/sources.list.d/${PACKAGE_NAME}.list" + + local text="Installing '$PACKAGE_NAME' repository via apt ..." + echo_running "$text" + create_repo_config > "$repo_path" + chmod 644 $repo_path + echo_okfail "$text" || die "Could not install the repository, do you have permissions?" +} + +function usage () { + cat <