446 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			446 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash
 | |
| 
 | |
| # https://caddyserver.com/download
 | |
| # https://caddyserver.com/download/build?os=darwin&arch=amd64&features=DNS,awslambda,cors,expires,filemanager,filter,git,hugo,ipfilter,jsonp,jwt,locale,mailout,minify,multipass,prometheus,ratelimit,realip,search,upload,cloudflare,digitalocean,dnsimple,dyn,gandi,googlecloud,linode,namecheap,ovh,rfc2136,route53,vultr
 | |
| 
 | |
| installer_base="https://git.daplie.com/Daplie/caddy-installer/raw/master"
 | |
| caddy_systemd_service="$installer_base/etc/systemd/system/caddy.service"
 | |
| caddy_systemd_tmpfiles="$installer_base/etc/tmpfiles.d/caddy.conf"
 | |
| caddy_launchd_service="$installer_base/Library/LaunchDaemons/com.caddyserver.web.plist"
 | |
| caddy_localhost_index="$installer_base/srv/www/index.html"
 | |
| 
 | |
| all_oses="windows,darwin,linux,freebsd,openbsd"
 | |
| all_arches="arm64,amd64,386,armv5,armv6l,armv7l"
 | |
| all_plugins="DNS,awslambda,cors,expires,filemanager,filter,git,hugo,ipfilter,jsonp,jwt,locale,mailout,minify,multipass,prometheus,ratelimit,realip,search,upload,cloudflare,digitalocean,dnsimple,dyn,gandi,googlecloud,linode,namecheap,ovh,rfc2136,route53,vultr"
 | |
| 
 | |
| caddy_os=""
 | |
| default_os=""
 | |
| caddy_arch=""
 | |
| default_arch=""
 | |
| caddy_arm=""
 | |
| caddy_features=""
 | |
| caddy_user=www-data
 | |
| caddy_group=www-data
 | |
| install_path="/usr/local/bin"
 | |
| 
 | |
| caddy_bin="caddy"
 | |
| caddy_dl_ext=".tar.gz"
 | |
| 
 | |
| ###############################
 | |
| #                             #
 | |
| #         http_get            #
 | |
| # boilerplate for curl / wget #
 | |
| #                             #
 | |
| ###############################
 | |
| 
 | |
| # See https://git.daplie.com/Daplie/daplie-snippets/blob/master/bash/http-get.sh
 | |
| 
 | |
| http_get=""
 | |
| http_opts=""
 | |
| http_out=""
 | |
| 
 | |
| detect_http_get()
 | |
| {
 | |
|   if type -p curl >/dev/null 2>&1; then
 | |
|     http_get="curl"
 | |
|     http_opts="-fsSL"
 | |
|     http_out="-o"
 | |
|     #curl -fsSL "$caddy_url" -o "$PREFIX/tmp/$caddy_pkg"
 | |
|   elif type -p wget >/dev/null 2>&1; then
 | |
|     http_get="wget"
 | |
|     http_opts="--quiet"
 | |
|     http_out="-O"
 | |
|     #wget --quiet "$caddy_url" -O "$PREFIX/tmp/$caddy_pkg"
 | |
|   else
 | |
|     echo "Aborted, could not find curl or wget"
 | |
|     return 7
 | |
|   fi
 | |
| }
 | |
| 
 | |
| dap_dl()
 | |
| {
 | |
|   $http_get $http_opts $http_out "$2" "$1"
 | |
| }
 | |
| 
 | |
| detect_http_get
 | |
| 
 | |
| ## END HTTP_GET ##
 | |
| 
 | |
| detect_arch()
 | |
| {
 | |
|   trap 'echo -e "Aborted, error $? in command: $BASH_COMMAND"; trap ERR; return 1' ERR
 | |
| 
 | |
|   #########################
 | |
|   # Which OS and version? #
 | |
|   #########################
 | |
| 
 | |
|   default_arch="unknown"
 | |
| 
 | |
|   # NOTE: `uname -m` is more accurate and universal than `arch`
 | |
|   # See https://en.wikipedia.org/wiki/Uname
 | |
|   unamem="$(uname -m)"
 | |
|   if [[ $unamem == *aarch64* ]]; then
 | |
|     default_arch="arm64"
 | |
|   elif [[ $unamem == *64* ]]; then
 | |
|     default_arch="amd64"
 | |
|   elif [[ $unamem == *86* ]]; then
 | |
|     default_arch="386"
 | |
|   elif [[ $unamem == *armv5* ]]; then
 | |
|     default_arch="armv5"
 | |
|   elif [[ $unamem == *armv6l* ]]; then
 | |
|     default_arch="armv6l"
 | |
|   elif [[ $unamem == *armv7l* ]]; then
 | |
|     default_arch="armv7l"
 | |
|   else
 | |
|     default_arch="$unamem"
 | |
|   fi
 | |
| 
 | |
|   trap ERR
 | |
| }
 | |
| 
 | |
| detect_os()
 | |
| {
 | |
|   trap 'echo -e "Aborted, error $? in command: $BASH_COMMAND"; trap ERR; return 1' ERR
 | |
| 
 | |
|   default_os="unsupported"
 | |
| 
 | |
|   uname="$(uname)"
 | |
|   #declare -u unameu=$uname # requires bash v4+, not supported on macOS
 | |
|   unameu="$(echo $uname | tr '/a-z/' '/A-Z/')"
 | |
|   if [[ ${unameu} == *DARWIN* ]]; then
 | |
|     default_os="darwin"
 | |
|     vers=$(sw_vers)
 | |
|     version=${vers##*ProductVersion:}
 | |
|     IFS='.' read OSX_MAJOR OSX_MINOR _ <<<"$version"
 | |
| 
 | |
|     # Major
 | |
|     if ((OSX_MAJOR < 10)); then
 | |
|       echo "Aborted, unsupported OS X version (9-)"
 | |
|       return 3
 | |
|     fi
 | |
|     if ((OSX_MAJOR > 10)); then
 | |
|       echo "Aborted, unsupported OS X version (11+)"
 | |
|       return 4
 | |
|     fi
 | |
| 
 | |
|     # Minor
 | |
|     if ((OSX_MINOR < 5)); then
 | |
|       echo "Aborted, unsupported OS X version (10.5-)"
 | |
|       return 5
 | |
|     fi
 | |
|   elif [[ ${unameu} == *LINUX* ]]; then
 | |
|     default_os="linux"
 | |
|   elif [[ ${unameu} == *FREEBSD* ]]; then
 | |
|     default_os="freebsd"
 | |
|   elif [[ ${unameu} == *OPENBSD* ]]; then
 | |
|     default_os="openbsd"
 | |
|   elif [[ ${unameu} == *WIN* ]]; then
 | |
|     # Should catch cygwin
 | |
|     default_os="windows"
 | |
|     caddy_dl_ext=".zip"
 | |
|     caddy_bin=$caddy_bin.exe
 | |
|   else
 | |
|     default_os="$uname"
 | |
|   fi
 | |
| 
 | |
|   trap ERR
 | |
| }
 | |
| 
 | |
| detect_target()
 | |
| {
 | |
|   trap 'echo -e "Aborted, error $? in command: $BASH_COMMAND"; trap ERR; return 1' ERR
 | |
| 
 | |
|   detect_arch
 | |
|   detect_os
 | |
| 
 | |
|   while [[ $# -gt 0 ]]; do
 | |
|     key="$1"
 | |
|     case $key in
 | |
|       --arch)
 | |
|         caddy_arch="$2"
 | |
|         shift # past argument
 | |
|       ;;
 | |
|       --os)
 | |
|         caddy_os="$2"
 | |
|         shift # past argument
 | |
|       ;;
 | |
|       -h|--help)
 | |
|         echo ""
 | |
|         echo "Usage: install-caddy [plugin1,plugin2,...]"
 | |
|         echo ""
 | |
|         echo "Optional arguments (defaults shown)"
 | |
|         echo "  --os ${default_os} # options: $(echo $all_oses | tr "," " ")"
 | |
|         echo "  --arch ${default_arch}${caddy_arm} # options: $(echo $all_arches | tr "," " ")"
 | |
|         echo ""
 | |
|         echo "Features:"
 | |
|         echo "$(echo $all_plugins)"
 | |
|         echo ""
 | |
|         exit 0
 | |
|       ;;
 | |
|       -*)
 | |
|         # unknown argument
 | |
|         echo "unrecognized argument '$1'"
 | |
|         exit 13
 | |
|       ;;
 | |
|       *)
 | |
|         # unknown value
 | |
|         if [ -z "${caddy_features}" ]; then
 | |
|           caddy_features=$1
 | |
|         else
 | |
|           echo "unrecognized value '$1'"
 | |
|           exit 1
 | |
|         fi
 | |
|       ;;
 | |
|     esac
 | |
|   shift # past argument or value
 | |
|   done
 | |
| 
 | |
|   # use commandline-specified caddy os or the host OS
 | |
|   if [ -z "$caddy_os" ]; then
 | |
|     caddy_os=$default_os
 | |
|   fi
 | |
| 
 | |
|   if [[ ${caddy_os} == "darwin" ]]; then
 | |
|     caddy_user=_www
 | |
|     caddy_group=_www
 | |
|     caddy_dl_ext=".zip"
 | |
|   elif [[ ${caddy_os} == "linux" ]]; then
 | |
|     ignore=true
 | |
|   elif [[ ${caddy_os} == "freebsd" ]]; then
 | |
|     ignore=true
 | |
|   elif [[ ${caddy_os} == "openbsd" ]]; then
 | |
|     ignore=true
 | |
|   elif [[ ${caddy_os} == "windows" ]]; then
 | |
|     caddy_dl_ext=".zip"
 | |
|     caddy_bin=$caddy_bin.exe
 | |
|   else
 | |
|     echo "Aborted, unsupported or unknown os: $caddy_os"
 | |
|     return 6
 | |
|   fi
 | |
| 
 | |
|   # use commandline-specified caddy arch or the host arch
 | |
|   if [ -z "$caddy_arch" ]; then
 | |
|     caddy_arch=$default_arch
 | |
|   fi
 | |
| 
 | |
|   if [[ ${caddy_arch} == "arm64" ]]; then
 | |
|     ignore=true
 | |
|   elif [[ ${caddy_arch} == "amd64" ]]; then
 | |
|     ignore=true
 | |
|   elif [[ ${caddy_arch} == "386" ]]; then
 | |
|     ignore=true
 | |
|   elif [[ ${caddy_arch} == "armv5" ]]; then
 | |
|     caddy_arch="arm"
 | |
|     caddy_arm=5
 | |
|   elif [[ ${caddy_arch} == "armv6l" ]]; then
 | |
|     caddy_arch="arm"
 | |
|     caddy_arm=6
 | |
|   elif [[ ${caddy_arch} == "armv7l" ]]; then
 | |
|     caddy_arch="arm"
 | |
|     caddy_arm=7
 | |
|   else
 | |
|     echo "Aborted, unsupported or unknown architecture: $caddy_arch"
 | |
|     return 2
 | |
|   fi
 | |
| 
 | |
|   trap ERR
 | |
| }
 | |
| 
 | |
| download_caddy()
 | |
| {
 | |
|   trap 'echo -e "Aborted, error $? in command: $BASH_COMMAND"; trap ERR; return 1' ERR
 | |
| 
 | |
|   ########################
 | |
|   # Download and extract #
 | |
|   ########################
 | |
| 
 | |
|   echo "Downloading Caddy for $caddy_os/$caddy_arch$caddy_arm..."
 | |
|   #caddy_file="caddy_${caddy_os}_$caddy_arch${caddy_arm}_custom$caddy_dl_ext"
 | |
|   caddy_pkg="caddy_${caddy_os}_$caddy_arch${caddy_arm}_custom$caddy_dl_ext"
 | |
|   caddy_dir="caddy_${caddy_os}_$caddy_arch${caddy_arm}_custom"
 | |
|   # new.caddyserver.com
 | |
|   caddy_url="https://caddyserver.com/download/$caddy_os/$caddy_arch$caddy_arm?plugins=$caddy_features"
 | |
|   # old caddyserver.com
 | |
|   #caddy_url="https://caddyserver.com/download/build?os=$caddy_os&arch=$caddy_arch&arm=$caddy_arm&features=$caddy_features"
 | |
|   echo "$caddy_url"
 | |
| 
 | |
|   # Use $PREFIX for compatibility with Termux on Android
 | |
|   rm -rf "$PREFIX/tmp/$caddy_pkg" "$PREFIX/tmp/$caddy_dir"
 | |
| 
 | |
|   dap_dl "$caddy_url" "$PREFIX/tmp/$caddy_pkg"
 | |
| 
 | |
|   echo "Extracting..."
 | |
|   case "$caddy_pkg" in
 | |
|     *.zip)    unzip -o "$PREFIX/tmp/$caddy_pkg" "$caddy_bin" -d "$PREFIX/tmp/$caddy_dir/" ;;
 | |
|     #*.tar.gz) tar -xzf "$PREFIX/tmp/$caddy_file" -C "$PREFIX/tmp/" "$caddy_bin" ;;
 | |
|     *.tar.gz) mkdir -p "$PREFIX/tmp/$caddy_dir/"; tar -xzf "$PREFIX/tmp/$caddy_pkg" -C "$PREFIX/tmp/$caddy_dir/" ;;
 | |
|   esac
 | |
| 
 | |
|   trap ERR
 | |
| }
 | |
| 
 | |
| install_caddy()
 | |
| {
 | |
|   trap 'echo -e "Aborted, error $? in command: $BASH_COMMAND"; trap ERR; return 1' ERR
 | |
| 
 | |
|   if [ "$caddy_os" != "$default_os" ]; then
 | |
|     echo "caddy os does not match $default_os, skipping install"
 | |
|   fi
 | |
|   if [ "$caddy_arch" != "$default_arch" ]; then
 | |
|     echo "caddy arch does not match $default_arch, skipping install"
 | |
|   fi
 | |
| 
 | |
|   # Termux on Android has $PREFIX set which already ends with /usr
 | |
|   if [[ -n "$ANDROID_ROOT" && -n "$PREFIX" ]]; then
 | |
|     install_path="$PREFIX/bin"
 | |
|   fi
 | |
| 
 | |
|   # Fall back to /usr/bin if necessary
 | |
|   if [[ ! -d $install_path ]]; then
 | |
|     install_path="/usr/bin"
 | |
|   fi
 | |
| 
 | |
|   # Not every platform has or needs sudo (see issue #40)
 | |
|   ((EUID)) && [[ -z "$ANDROID_ROOT" ]] && sudo_cmd="sudo"
 | |
| 
 | |
|   # Back up existing caddy, if any
 | |
|   caddy_cur_ver="$("$caddy_bin" --version 2>/dev/null | cut -d ' ' -f2)"
 | |
|   if [[ $caddy_cur_ver ]]; then
 | |
|     # caddy of some version is already installed
 | |
|     caddy_path="$(type -p "$caddy_bin")"
 | |
|     caddy_backup="${caddy_path}_$caddy_cur_ver"
 | |
|     echo "Backing up $caddy_path to $caddy_backup"
 | |
|     echo "(Password may be required.)"
 | |
|     $sudo_cmd mv "$caddy_path" "$caddy_backup"
 | |
|   fi
 | |
| 
 | |
|   echo "Putting caddy in $install_path (may require password)"
 | |
|   $sudo_cmd mv "$PREFIX/tmp/$caddy_dir/$caddy_bin" "$install_path/$caddy_bin"
 | |
| 
 | |
|   $sudo_cmd mkdir -p $PREFIX/etc/caddy
 | |
|   if [ ! -f "$PREFIX/etc/caddy/Caddyfile" ] || [ -z "$(cat $PREFIX/etc/caddy/Caddyfile)" ]; then
 | |
|     cat <<'CADDY_EOF' >> $PREFIX/tmp/$caddy_dir/Caddyfile
 | |
| http://localhost {
 | |
|   root /srv/www/localhost
 | |
| }
 | |
| CADDY_EOF
 | |
|     $sudo_cmd mv "$PREFIX/tmp/$caddy_dir/Caddyfile" "$PREFIX/etc/caddy/Caddyfile"
 | |
|   fi
 | |
| 
 | |
|   $sudo_cmd mkdir -p $PREFIX/etc/ssl/caddy
 | |
|   $sudo_cmd mkdir -p $PREFIX/var/log/caddy
 | |
|   $sudo_cmd mkdir -p $PREFIX/srv/www/localhost
 | |
| 
 | |
|   $sudo_cmd chmod +x "$install_path/$caddy_bin"
 | |
|   $sudo_cmd chmod 755 $PREFIX/etc/caddy
 | |
|   $sudo_cmd chmod 755 $PREFIX/etc/caddy
 | |
|   $sudo_cmd chmod 750 $PREFIX/etc/ssl/caddy
 | |
|   $sudo_cmd chmod 750 $PREFIX/var/log/caddy
 | |
|   $sudo_cmd chmod 755 $PREFIX/srv/www
 | |
|   $sudo_cmd chmod 755 $PREFIX/srv/www/localhost
 | |
| 
 | |
|   if [ ! -f "$PREFIX/srv/www/localhost/index.html" ] || [ -z "$(cat $PREFIX/srv/www/localhost/index.html)" ]; then
 | |
|     dap_dl "$caddy_localhost_index" $PREFIX/tmp/$caddy_dir/index.html
 | |
|     $sudo_cmd mv $PREFIX/tmp/$caddy_dir/index.html $PREFIX/srv/www/localhost/
 | |
|     $sudo_cmd chown -R $caddy_user:$caddy_group $PREFIX/srv/www/localhost/
 | |
|     $sudo_cmd chmod 664 $PREFIX/srv/www/localhost/index.html
 | |
|   fi
 | |
| 
 | |
|   if setcap_cmd=$(type -p setcap); then
 | |
|     $sudo_cmd $setcap_cmd cap_net_bind_service=+ep "$install_path/$caddy_bin"
 | |
|   fi
 | |
|   $sudo_cmd rm -- "$PREFIX/tmp/$caddy_pkg"
 | |
| 
 | |
|   echo ""
 | |
|   # check installation
 | |
|   $caddy_bin --version
 | |
| 
 | |
|   echo "Successfully installed"
 | |
| 
 | |
|   echo ""
 | |
|   echo "Trying to set permissions to $caddy_user:$caddy_group"
 | |
|   echo '(if this fails please file a bug with the output of "uname -a" and "cat /etc/group")'
 | |
| 
 | |
|   # TODO if this fails perhaps catch and create a www-data group?
 | |
|   # TODO grep $caddy_user $PREFIX/etc/passwd
 | |
|   # TODO grep $caddy_group $PREFIX/etc/group
 | |
|   # TODO adduser $caddy_user
 | |
|   $sudo_cmd chown -R $caddy_user:$caddy_group $PREFIX/etc/caddy
 | |
|   $sudo_cmd chown -R $caddy_user:$caddy_group $PREFIX/etc/ssl/caddy
 | |
|   $sudo_cmd chown -R $caddy_user:$caddy_group $PREFIX/var/log/caddy
 | |
|   $sudo_cmd chown -R $caddy_user:$caddy_group $PREFIX/srv/www
 | |
| 
 | |
|   echo ""
 | |
|   echo "Successfully changed permissions"
 | |
|   echo ""
 | |
| 
 | |
|   if [ -d "$PREFIX/etc/systemd/system" ]; then
 | |
|     echo ""
 | |
|     echo "Installing as systemd service"
 | |
|     echo ""
 | |
|     dap_dl "$caddy_systemd_service" $PREFIX/tmp/$caddy_dir/caddy.service
 | |
|     $sudo_cmd mv $PREFIX/tmp/$caddy_dir/caddy.service $PREFIX/etc/systemd/system/caddy.service
 | |
|     $sudo_cmd chown -R root:root $PREFIX/etc/systemd/system/caddy.service
 | |
|     $sudo_cmd chmod 644 $PREFIX/etc/systemd/system/caddy.service
 | |
| 
 | |
|     dap_dl "$caddy_systemd_tmpfiles" $PREFIX/tmp/$caddy_dir/caddy.conf
 | |
|     $sudo_cmd mv $PREFIX/tmp/$caddy_dir/caddy.conf $PREFIX/etc/tmpfiles.d/caddy.conf
 | |
|     $sudo_cmd chown -R root:root $PREFIX/etc/tmpfiles.d/caddy.conf
 | |
|     $sudo_cmd chmod 644 $PREFIX/etc/tmpfiles.d/caddy.conf
 | |
| 
 | |
|     $sudo_cmd systemctl stop caddy.service >/dev/null 2>/dev/null
 | |
|     $sudo_cmd systemctl daemon-reload
 | |
|     $sudo_cmd systemctl start caddy.service
 | |
|     $sudo_cmd systemctl enable caddy.service
 | |
| 
 | |
|     echo "caddy started with systemctl"
 | |
|     echo "Check it out at http://localhost"
 | |
| 
 | |
|   elif [ -d "/Library/LaunchAgents" ]; then
 | |
|     echo ""
 | |
|     echo "Installing as launchd service"
 | |
|     echo ""
 | |
|     # See http://www.launchd.info/
 | |
|     dap_dl "$caddy_launchd_service" $PREFIX/tmp/$caddy_dir/com.caddyserver.web.plist
 | |
|     $sudo_cmd mv $PREFIX/tmp/$caddy_dir/com.caddyserver.web.plist /Library/LaunchAgents/com.caddyserver.web.plist
 | |
|     $sudo_cmd chown root:wheel /Library/LaunchAgents/com.caddyserver.web.plist
 | |
|     $sudo_cmd chmod 0644 /Library/LaunchAgents/com.caddyserver.web.plist
 | |
|     $sudo_cmd launchctl unload -w /Library/LaunchAgents/com.caddyserver.web.plist >/dev/null 2>/dev/null
 | |
|     $sudo_cmd launchctl load -w /Library/LaunchAgents/com.caddyserver.web.plist
 | |
| 
 | |
|     echo "caddy started with launchd"
 | |
| 
 | |
|   else
 | |
|     echo ""
 | |
|     echo "Unknown system service init type. You must install as a system service manually."
 | |
|     echo '(please file a bug with the output of "uname -a")'
 | |
|     echo ""
 | |
|   fi
 | |
| 
 | |
|   # cleanup
 | |
|   $sudo_cmd rm -rf -- "$PREFIX/tmp/$caddy_dir/"
 | |
| 
 | |
|   trap ERR
 | |
| }
 | |
| 
 | |
| run()
 | |
| {
 | |
|   trap 'echo -e "Aborted, error $? in command: $BASH_COMMAND"; trap ERR; return 1' ERR
 | |
| 
 | |
|   detect_http_get
 | |
|   detect_target "$@"
 | |
|   download_caddy "$@"
 | |
| 
 | |
|   if [ -f "$PREFIX/tmp/$caddy_dir/install.sh" ]; then
 | |
|     chmod a+x $PREFIX/tmp/$caddy_dir/install.sh
 | |
|     $PREFIX/tmp/$caddy_dir/install.sh "$PREFIX/tmp/$caddy_dir" "$@"
 | |
|   else
 | |
|     install_caddy "$@"
 | |
|   fi
 | |
| 
 | |
|   trap ERR
 | |
|   return 0
 | |
| }
 | |
| 
 | |
| run "$@"
 |