214 lines
8.1 KiB
Bash
214 lines
8.1 KiB
Bash
#! /usr/bin/env bash
|
|
|
|
######### Repo list
|
|
|
|
# this is a reference template
|
|
# function _repo_template_function() {
|
|
# REPO_FQDN='' # host FQDN, this will also be the name of the apt list/source file
|
|
# GPG_KEY_URL='' # [optional] URL to the GPG Key, if not supplied it will be https://$REPO_FQDN/gpg
|
|
# GPG_KEY_PATH='' # [optional] Location on disk for the public GPG key
|
|
# REPO_ARCH='' # [optional] System architecture specific package, '-' is shorthand for current architecture
|
|
# REPO_URL='' # [optional] REPO Url if not https://$REPO_FQDN, which is the default.
|
|
# REPO_SUITE='' # [optional] Suite / Release codename
|
|
# REPO_CMP='' # [optional] Package Channel - default is 'main', this is vendor specific.
|
|
# }
|
|
|
|
function _repo_docker() {
|
|
# for: docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
|
# Also don't forget:
|
|
# remove: docker docker-engine docker.io containerd runc
|
|
# possibly remove docker-compose and install: https://github.com/docker/compose-switch
|
|
|
|
REPO_FQDN='download.docker.com'
|
|
REPO_URL="https://download.docker.com/linux/$_OS"
|
|
GPG_KEY_URL="$REPO_URL/gpg"
|
|
REPO_CMP='stable'
|
|
}
|
|
function _repo_anydesk() {
|
|
# for: anydesk
|
|
REPO_FQDN='deb.anydesk.com'
|
|
REPO_URL="http://$REPO_FQDN/" # NOTE, this is http, not https
|
|
GPG_KEY_URL='https://keys.anydesk.com/repos/DEB-GPG-KEY'
|
|
REPO_ARCH='-'
|
|
REPO_CMP='main'
|
|
REPO_SUITE='all'
|
|
}
|
|
function _repo_gcloud() {
|
|
# for: google-cloud-cli
|
|
REPO_FQDN='packages.cloud.google.com'
|
|
REPO_URL="https://$REPO_FQDN/apt"
|
|
GPG_KEY_URL="$REPO_URL/doc/apt-key.gpg"
|
|
REPO_ARCH='-'
|
|
REPO_SUITE='cloud-sdk'
|
|
}
|
|
function _repo_mspackages() {
|
|
# for: code (optionally: powershell dotnet-*)
|
|
REPO_FQDN='packages.microsoft.com'
|
|
GPG_KEY_URL="https://$REPO_FQDN/keys/microsoft.asc"
|
|
REPO_URL="https://$REPO_FQDN/$_OS/$_REL/prod"
|
|
}
|
|
function _repo_msedge() {
|
|
# for: microsoft-edge-stable
|
|
REPO_FQDN='edge.microsoft.com'
|
|
GPG_KEY_URL="https://packages.microsoft.com/keys/microsoft.asc"
|
|
REPO_URL="http://packages.microsoft.com/repos/edge"
|
|
REPO_SUITE='stable'
|
|
}
|
|
function _repo_hashicorp() {
|
|
# for: terraform
|
|
REPO_FQDN='apt.releases.hashicorp.com'
|
|
# GPG_KEY_URL='' # default value is enough here
|
|
# REPO_URL='' # default value is enough here
|
|
}
|
|
function _repo_custom_xscreensavers() {
|
|
# I really LOVE xscreensavers, but it's been stuck in limbo on the
|
|
# `stable` repos, so I install it from the `unstable`, aka `sid`, suite.
|
|
# To do that safely, I make sure the repo is pinned to a lower priority.
|
|
# I do this BEFORE I add the repo.
|
|
|
|
# # Debian sid (unstable) as low-priority option
|
|
(echo 'Package: *'; echo 'Pin: release a=unstable'; echo 'Pin-Priority: 200') | sudo tee /etc/apt/preferences.d/unstable > /dev/null
|
|
# # pin xscreensaver to unstable
|
|
(echo 'Package: xscreenaver*'; echo 'Pin: release a=unstable'; echo 'Pin-Priority: 2000') | sudo tee /etc/apt/preferences.d/xscreensaver > /dev/null
|
|
|
|
# for: xscreensaver xscreensaver-data xscreensaver-data-extra
|
|
# xscreensaver-screensaver-bsod xscreensaver-screensaver-webcollage
|
|
# Add the unstable/sid repo - THIS IS DANGEROUS without the pinning via
|
|
# /etc/apt/preferences.d files created by the code above.
|
|
sudo apt-add-repository $_YES --no-update "deb [arch=amd64] http://deb.debian.org/debian sid main non-free contrib"
|
|
}
|
|
|
|
############ Script Logic starts here
|
|
set -e
|
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
|
USER_HOME=$HOME
|
|
[[ -n "${SUDO_USER}" ]] && USER_HOME="$(eval "echo ~${SUDO_USER}")"
|
|
. ${SHRC_D:-$USER_HOME/.pqb.shrc.d}/01_util.functions
|
|
|
|
# The function that does the _Heavy Lifting_.
|
|
# see the code that follows for the parameter signature
|
|
function add_repo() {
|
|
unset REPO_FQDN GPG_KEY_URL GPG_KEY_PATH REPO_ARCH REPO_URL REPO_SUITE REPO_CMP
|
|
|
|
# In case custom handling is required, call it and return.
|
|
if [[ "$(type -t _repo_custom_$1)" == 'function' ]]; then
|
|
eval "_repo_custom_$1" && return 0
|
|
return $?
|
|
# If no repo defintion exist, exit with an error
|
|
elif [[ "$(type -t _repo_$1)" != 'function' ]]; then
|
|
eval $(error 1 "Can't configure $1, could not find _repo_$1 definition!") || return $?
|
|
return 1
|
|
fi
|
|
# Grab the repo's defintion
|
|
eval "_repo_$1"
|
|
|
|
# Prepare all necessary vraiables
|
|
[[ -z "$REPO_FQDN" ]] && eval $(error 1 "REPO_FQDN not defined for '$1'")
|
|
GPG_KEY_URL=${GPG_KEY_URL:-https:\/\/$REPO_FQDN\/gpg}
|
|
GPG_KEY_PATH=${GPG_KEY_PATH:-/usr/share/keyrings/$REPO_FQDN.gpg}
|
|
REPO_ARCH=${REPO_ARCH:-${_ARC}}
|
|
[[ $REPO_ARCH == '-' ]] && REPO_ARCH='' || REPO_ARCH="arch=$REPO_ARCH"
|
|
REPO_URL=${REPO_URL:-https:\/\/$REPO_FQDN}
|
|
REPO_SUITE=${REPO_SUITE:-$_CNM}
|
|
REPO_CMP=${REPO_CMP:-main}
|
|
|
|
# Grab the GPG key and save it.
|
|
curl -fsSL $GPG_KEY_URL | sudo gpg --dearmor -o $GPG_KEY_PATH $_YES
|
|
echo "Key created: $GPG_KEY_PATH"
|
|
# Define the package source
|
|
echo "deb [$(echo "$REPO_ARCH signed-by=$GPG_KEY_PATH" | xargs )] $REPO_URL $REPO_SUITE $REPO_CMP" | \
|
|
sudo tee /etc/apt/sources.list.d/$REPO_FQDN.list > /dev/null
|
|
echo "APT source list added: /etc/apt/sources.list.d/$REPO_FQDN.list"
|
|
}
|
|
|
|
function usage() {
|
|
printf " %s\n" \
|
|
"Usage:" \
|
|
" $0 [-v[v]] " \
|
|
" [--no-init] [--no-overwrite] " \
|
|
" all|<repo name>[ <repo name 2>...] " \
|
|
"" \
|
|
"Repos: $( \
|
|
printf "\n %s" $( \
|
|
typeset -f \
|
|
| grep '^_repo_' \
|
|
| sed 's/_repo\(_custom\)\?_\(.*\) ()/\2/' \
|
|
| sort \
|
|
))" \
|
|
"" \
|
|
"Options:" \
|
|
" --no-init - skip package initialization." \
|
|
" --no-overwrite - don't overwrite gpg keys automatially, ask." \
|
|
" new keys will still be written without asking." \
|
|
" -v[v] - script verbosity, equivalent to set -x and set -xv" \
|
|
""
|
|
}
|
|
|
|
function main() {
|
|
[[ ${#REPO_LIST[@]} -eq 0 ]] && usage && return 1
|
|
|
|
require_root
|
|
|
|
_OS=$(lsb_release -is | awk '{ print tolower($0) }')
|
|
[[ $_OS == 'pop' ]] && _OS='ubuntu'
|
|
_REL=$(lsb_release -rs) # Release
|
|
_CNM=$(lsb_release -cs) # CodeName
|
|
_ARC=$(dpkg --print-architecture) # Architecture
|
|
|
|
ANSI_Cyan "Initializing: Installing basic packages..."; echo
|
|
if [[ -n "$SHOULD_INIT" ]]; then
|
|
# Make sure the /usr/share/keyrings dir exists
|
|
mkdir -p /usr/share/keyrings 2>&1 > /dev/null
|
|
|
|
# Make sure all of the basic required tools are installed for the code
|
|
# below to work
|
|
apt-get install --yes --no-install-recommends \
|
|
curl gnupg software-properties-common apt-transport-https
|
|
fi
|
|
ANSI_Green "Done."; echo
|
|
|
|
while read r; do
|
|
ANSI_Cyan "Installing $r repository..."; echo
|
|
add_repo $r && UPDATE_REQUIRED=1 || return 2
|
|
ANSI_Green "Installation of $r repository completed."; echo
|
|
done < <(printf "%s\n" "${REPO_LIST[@]}")
|
|
|
|
# Finally, run `apt update` to check that everything completed successfully
|
|
if [[ $UPDATE_REQUIRED == 1 ]]; then
|
|
ANSI_Cyan "Finalizing: running 'apt update'..."; echo
|
|
|
|
MISSING_SIGNATURES=($( \
|
|
sudo apt update 2>&1 1>/dev/null \
|
|
| sed -ne 's/.*NO_PUBKEY //p' \
|
|
))
|
|
$MISSING_SIGNATURES| while read key; do if ! [[ ${keys[*]} =~ "$key" ]]; then sudo apt-key adv --keyserver hkp://pool.sks-keyservers.net:80 --recv-keys "$key"; keys+=("$key"); fi; done
|
|
sudo apt update
|
|
ANSI_Green "'apt update' completed."; echo
|
|
fi
|
|
}
|
|
|
|
# Iterate through stdin or parameters
|
|
if [[ $# == 0 ]]; then
|
|
usage
|
|
else
|
|
REPO_LIST=()
|
|
_YES='--yes'
|
|
_SHOULD_INIT=1
|
|
UPDATE_REQUIRED=0
|
|
|
|
READCMD='printf "%s\n" "${@}"'
|
|
[[ $# == 1 && $1 == '-' ]] && READCMD='cat - '
|
|
while read a; do
|
|
# Switch on _YES
|
|
[[ "$a" == "-v" ]] && set -x && continue
|
|
[[ "$a" == "-vv" ]] && set -xv && continue
|
|
[[ "$a" == "--no-overwrite" ]] && unset _YES && continue
|
|
[[ "$a" == "--no-init" ]] && unset _SHOULD_INIT && continue
|
|
|
|
# Add repo
|
|
[[ -n "$a" ]] && REPO_LIST+=("$a")
|
|
done < <( eval $READCMD )
|
|
|
|
main
|
|
fi
|