#!/bin/bash e() { printf "%s" "$*"; } warn() { e "${YELLOW}Warning:$NORMAL" "$*"$'\n' >&2 ; } info() { e "${BLUE}II$NORMAL" "$*"$'\n' >&2 ; } verb() { [ -z "$VERBOSE" ] || e "$*"$'\n' >&2; } debug() { [ -z "$DEBUG" ] || e "$*"$'\n' >&2; } err() { e "${RED}Error:$NORMAL $*"$'\n' >&2 ; } die() { err "$@" ; exit 1; } get_path() { ( IFS=: for d in $PATH; do filename="$d/$1" [ -f "$filename" -a -x "$filename" ] && { echo "$d/$1" return 0 } done return 1 ) } ansi_color() { local choice="$1" if [ "$choice" == "tty" ]; then if [ -t 1 ]; then choice="yes" else choice="no" fi fi ANSI_ESC=$'\e[' if [ "$choice" != "no" ]; then NORMAL="${ANSI_ESC}0m" GRAY="${ANSI_ESC}1;30m" RED="${ANSI_ESC}1;31m" GREEN="${ANSI_ESC}1;32m" YELLOW="${ANSI_ESC}1;33m" BLUE="${ANSI_ESC}1;34m" PINK="${ANSI_ESC}1;35m" CYAN="${ANSI_ESC}1;36m" WHITE="${ANSI_ESC}1;37m" DARKGRAY="${ANSI_ESC}0;30m" DARKRED="${ANSI_ESC}0;31m" DARKGREEN="${ANSI_ESC}0;32m" DARKYELLOW="${ANSI_ESC}0;33m" DARKBLUE="${ANSI_ESC}0;34m" DARKPINK="${ANSI_ESC}0;35m" DARKCYAN="${ANSI_ESC}0;36m" DARKWHITE="${ANSI_ESC}0;37m" fi ansi_color="$choice" export NORMAL \ GRAY RED GREEN YELLOW BLUE PINK CYAN WHITE DARKGRAY \ DARKRED DARKGREEN DARKYELLOW DARKBLUE DARKPINK DARKCYAN \ ansi_color } depends() { ## Avoid colliding with variables that are created with depends. local __i __path __new_name for __i in "$@"; do if ! __path=$(get_path "$__i"); then __new_name="$(echo "${__i//-/_}")" if [ "$__new_name" != "$__i" ]; then depends "$__new_name" else err "dependency check: couldn't find '$__i' required command." exit 1 fi else if ! test -z "$__path" ; then export "$(echo "${__i//- /__}")"="$__path" fi fi done } get_os() { local uname_output uname_output="$(uname -s)" case "${uname_output}" in Linux*) if [[ "$(< /proc/version)" =~ ^.*@(Microsoft|WSL).*$ ]]; then e wsl elif [[ "$(< /proc/version)" =~ ^.*-microsoft-.*$ ]]; then e wsl2 elif [[ "$(< /proc/version)" == *-boot2docker* ]] && [[ -d /Users ]]; then e docker-toolbox-for-mac else e linux fi ;; Darwin*) e mac;; CYGWIN*) e cygwin;; MINGW*) e mingw;; *) e "UNKNOWN:${uname_output}";; esac } OS=$(get_os) || { err "Couldn't figure what OS you are running." exit 1 } fn.exists() { declare -F "$1" >/dev/null; } ## copy stdin to file, archive previous existing file if any install_file() { local path="$1" tmpfile tmpfile="$(mktemp)" cat > "${tmpfile}" || return 1 mkdir -vp "${path%/*}" || exit 1 if [[ -e "$path" ]]; then if ! diff "${tmpfile}" "${path}" >/dev/null 2>&1;then info "File '$path' exists but is different, archiving current content and replacing it." candidate="${path}.bak" n=1 while [ -e "$candidate" ]; do candidate="${path}.bak.$((n++))" done echo "Archiving previous version of '$path'" mv -v "${path}" "$candidate" || return 1 else info "File '$path' exists and is already with the right content." rm -f "$tmpfile" return fi fi echo "Creating '${path}'." mv "${tmpfile}" "$path" || return 1 } get_charm_store() { local branch="${1:master}" if ! [ -d "$CHARM_PATH" ]; then info "Creating charm-store in '$CHARM_PATH'.." git clone https://git.myceliandre.fr/0k/0k-charms -b "$branch" "$CHARM_PATH" || { echo " .. ${RED}Failed${NORMAL}." >&2 return 1 } echo " .. ${GREEN}Done${NORMAL}." >&2 else info "Updating existing charm-store in '$CHARM_PATH'." cd "$CHARM_PATH" || exit 1 git fetch && git checkout "$branch" && git pull -r || { warn "Could not update charm-store, do you have devs ingoing ?" echo " .. ${BLUE}No action${NORMAL}." >&2 return 0 } echo " .. ${GREEN}Done${NORMAL}." >&2 fi } fetch_binary() { local url="$1" name="$2" bin_path tmpfile mkdir -p "$BIN_PATH" || return 1 info "Downloading '$name'..." ( tmpfile=$(mktemp) && trap "rm -f '$tmpfile'" EXIT && curl -sS "$url" > "$tmpfile" && chmod +x "$tmpfile" || { echo " .. ${RED}Failed${NORMAL}." >&2 return 1 } if [[ "$(cat "$tmpfile")" == ""* ]]; then echo " $GRAY|$NORMAL fetching: $url" >&2 echo " .. ${RED}Failed${NORMAL} (fetched content is HTML !?!)." >&2 return 1 fi if [ -e "$BIN_PATH/$name" ] && diff "$tmpfile" "$BIN_PATH/$name" >/dev/null 2>&1; then echo " .. ${GREEN}Done${NORMAL} (File '$BIN_PATH/$name' was already up to date.)" >&2 else mv "$tmpfile" "$BIN_PATH/$name" && echo " .. ${GREEN}Done${NORMAL}." >&2 fi ) || return 1 hash -r if bin_path=$(type -p "$name"); then if [ "$bin_path" != "$BIN_PATH/$name" ]; then warn "Found a '$name' in \$PATH at '$bin_path'." \ $'\n'" That doesn't match expected location '$BIN_PATH/$name'." \ $'\n'" You might need to change you \$PATH to include '$BIN_PATH' before '${bin_path%/*}'." fi fi } get_docker_ip() { fetch_binary https://docker.0k.io/downloads/docker-ip-08c71ec docker-ip } install.linux() { depends docker curl git if [ "$UID" != 0 ]; then BIN_PATH=~/bin CHARM_PATH=~/.charm-store DEFAULT_COMPOSE_YML=~/.compose/etc/compose.yml COMPOSE_OPTION_FILE=~/.compose/etc/local.conf else BIN_PATH=/usr/local/bin CHARM_PATH=/srv/charm-store DEFAULT_COMPOSE_YML=/etc/compose/compose.yml COMPOSE_OPTION_FILE=/etc/compose/local.conf fi fetch_binary "https://docker.0k.io/downloads/compose-c93d82f" compose || return 1 get_docker_ip || return 1 if [[ ":$PATH:" != *":$BIN_PATH:"* ]]; then warn "Please ensure that '$BIN_PATH' is in your \$PATH to ensure" \ "the simple usage of 'compose' command." fi get_charm_store "${DEPLOY_REF}" || return 1 cat <&2 fi } ## ## Code ## ansi_color tty DEPLOY_REF="${DEPLOY_REF:-master}" run