diff --git a/bootstrap-Ubuntu.sh b/bootstrap-Ubuntu.sh new file mode 100755 index 0000000..abfbc32 --- /dev/null +++ b/bootstrap-Ubuntu.sh @@ -0,0 +1,151 @@ +#!/bin/bash + +set -e + +show_usage() { + echo "usage: $0 [-h] [-d]" +} + +show_help() { + show_usage + echo + echo "Bootstrap a Ubuntu or Linux Mint instance with:" + echo + echo "* update apt cache" + echo "* upgrade apt packages" + echo "* git - from apt" + echo "* python - from apt" + echo "* python-pip - from apt" + echo "* virtualenv - from pip" + echo "* SSH key - from ssh-keygen" + echo "* GitHub public key - with SSH key" + echo "* conduit - configuration manager" + echo + echo "If any already exist they will not be reinstalled." + echo + echo "optional arguments:" + echo " -h show this help message and exit" + echo " -y assume yes when prompted" +} + +yes=0 + +while getopts 'hy' opt; do + case $opt in + h) show_help; exit 0 ;; + y) yes=1 ;; + *) show_usage; exit 1 ;; + esac +done + +missing() { + which $1 &> /dev/null && return 1 || return 0 +} + +agree() { + local check=^[Nn]$ + [ $yes -eq 1 ] && [[ ! "$2" =~ $check ]] && return 0 + [[ "$2" =~ $check ]] && local default="[y/N]" || local default="[Y/n]" + read -p "$1 $default? " answer + case "$answer" in + y|Y|yes) return 0 ;; + n|N|no) return 1 ;; + '') [[ "$2" =~ $check ]] && return 1 || return 0 ;; + *) echo "invalid input: $answer" && return `agree "$1"` ;; + esac +} + +apt_install() { + sudo apt-get install --yes --install-recommends $1 > /dev/null +} + +pip_install() { + pip install --user $1 &> /dev/null +} + +export PATH=~/.local/bin:$PATH + +agree "Update apt cache" && sudo apt-get update > /dev/null +agree "Upgrade apt packages" "N" && sudo apt-get upgrade > /dev/null + +missing git && agree "Install git" && apt_install git + +if missing pip; then + agree "Install python-pip" && apt_install python-pip + agree "Upgrade pip with pip" && sudo -H pip install --upgrade pip > /dev/null +fi + +missing virtualenv && agree "Install virtualenv" && pip_install virtualenv + +if [ ! -f ~/.ssh/id_rsa ] && agree "Generate SSH key"; then + read -rp "SSH email: " email + [ ! -d ~/.ssh ] && mkdir -p ~/.ssh + ssh-keygen -t rsa -b 4096 -C "$email" -N "" -f ~/.ssh/id_rsa +fi + +if agree "GitHub public key"; then + env=$(mktemp -d) + virtualenv $env > /dev/null + source $env/bin/activate + pip install githubpy > /dev/null + python <(cat << EOF +from __future__ import print_function +from os import environ +from os.path import join +from getpass import getpass +from github import GitHub + + +def getinput(prompt): + try: + return raw_input(prompt) + except NameError: + return input(prompt) + + +def main(): + username = getinput('GitHub username: ') + password = getpass('GitHub password: ') + github = GitHub(username=username, password=password) + keys = github.user.keys().get() + id_rsa_pub_path = join(environ['HOME'], '.ssh', 'id_rsa.pub') + with open(id_rsa_pub_path, 'r') as id_rsa_pub_file: + local_key = id_rsa_pub_file.read() + for key in keys: + if local_key.startswith(key['key']): + print('Satisfied: GitHub public key') + exit(0) + title = getinput('GitHub key name: ') + github.user.keys().post(title=title, key=local_key) + print('Installed: GitHub public key') + exit(0) + + +if __name__ == '__main__': + try: + main() + except KeyboardInterrupt: + exit(130) + +EOF +) + deactivate + rm -r $env +fi + +# TODO: Gogs SSH key + +if [ -f ~/.ssh/id_rsa.pub ]; then + echo "----------------------------------------------------------------------" + cat ~/.ssh/id_rsa.pub + echo "----------------------------------------------------------------------" + read -rp "Set other SSH key recipients, press ENTER to continue: " +fi + +missing conduit && agree "Install conduit" && \ + pip_install git+ssh://git@github.com/kbenzie/conduit.git + +echo "To use install pip packages update your PATH:" +echo 'export PATH=~/.local/bin:$PATH' + +[ -f $0 ] && agree "Remove $0" "N" && rm $0