/ install
install
1 #!/bin/sh 2 # 3 # Radicle installation script. 4 # 5 set -e 6 7 # SSH signing key for the release archives. This is currently cloudhead's key. 8 SIGNER="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL460KIEccS4881p7PPpiiQBsxF+H5tgC6De6crw9rbU" 9 10 url() { 11 echo "https://files.radicle.xyz/releases/$1/radicle-$2.tar.xz" 12 } 13 14 info() { 15 printf "\033[36m$*\033[0m\n" 16 } 17 18 warn() { 19 printf "\033[33m$*\033[0m\n" 20 } 21 22 rad_home() { 23 if command -v rad >/dev/null 2>&1; then 24 rad path || true 25 fi 26 } 27 28 is_authed() { 29 RAD_HOME=$(rad_home) 30 31 if [ -n "$RAD_HOME" ] && [ -f "$RAD_HOME/keys/radicle.pub" ]; then 32 return 0 33 else 34 return 1 35 fi 36 } 37 38 success() { 39 version="$1" 40 41 printf "\033[32m✓\033[0m Radicle \033[2m$1\033[0m was installed successfully.\n" 42 43 RAD_HOME=$(rad_home) 44 45 if [ -n "$RAD_HOME" ] && [ -S "$RAD_HOME/node/control.sock" ]; then 46 printf "\n" 47 printf "Please restart your node to complete the upgrade.\n" 48 fi 49 } 50 51 error() { 52 printf "\033[31merror\033[0m: $*\n" >&2 53 } 54 55 fatal() { 56 error "$@" 57 exit 1 58 } 59 60 usage() { 61 echo "Usage" 62 echo 63 echo " $0 [<options>]" 64 echo 65 echo " This script will install the Radicle binaries under '$RAD_PATH'". 66 echo " To change the location, set \$RAD_PATH to a different directory." 67 echo 68 echo " Your Radicle home is set to '$RAD_HOME'." 69 echo " To change it, set \$RAD_HOME to a different directory." 70 echo 71 echo "Options" 72 echo 73 echo " --no-modify-path Do not modify the PATH environment variable" 74 echo " --version=VERSION Install the given version of Radicle (default: latest)" 75 echo " --prefix=PATH Radicle install prefix (default: ~/.radicle)" 76 echo " --help, -h Show this help message and exit" 77 echo 78 echo "Environment" 79 echo 80 echo " RAD_HOME Radicle home directory" 81 } 82 83 target() { 84 TARGET="" 85 86 case "$(uname)/$(uname -m)" in 87 Darwin/arm64) 88 TARGET="aarch64-apple-darwin" ;; 89 Darwin/x86_64) 90 TARGET="x86_64-apple-darwin" ;; 91 Linux/arm64|Linux/aarch64) 92 TARGET="aarch64-unknown-linux-musl" ;; 93 Linux/x86_64) 94 TARGET="x86_64-unknown-linux-musl" ;; 95 *) 96 fatal "Your operating system is currently unsupported. Sorry!" ;; 97 esac 98 echo $TARGET 99 } 100 101 in_path() { 102 IFS=":" 103 104 for dir in $PATH; do 105 if [ "$dir" = "$1" ]; then 106 return 0 # The path is in $PATH 107 fi 108 done 109 110 return 1 # The path is not in $PATH 111 } 112 113 get_started() { 114 printf "\n" 115 success "$@" 116 117 if ! is_authed; then 118 printf "\n" 119 printf "Get started by creating your Radicle key pair with \033[35m\`rad auth\`\033[0m.\n" 120 fi 121 } 122 123 verify() { 124 archive="$1" 125 signers="$(dirname $archive)/signers" 126 # Add the signer key to the allowed signers file we pass to ssh-keygen. 127 printf "cloudhead $SIGNER\n" > $signers 128 129 # Verify that `$archive` was signed by a key in `$signers`, identified by the 130 # name "cloudhead", using the signature in `$archive.sig`. 131 ssh-keygen -Y verify -f $signers -I cloudhead -n file -s "$archive.sig" < "$archive" || fatal "Invalid signature for $archive" 132 } 133 134 main() { 135 PREFIX=${RAD_HOME:-"$HOME/.radicle"} 136 SHELL_PATH=${SHELL:-"/bin/sh"} 137 NO_MODIFY_PATH=false 138 VERSION=latest 139 140 if [ -n "$RAD_PATH" ]; then 141 fatal "RAD_PATH is no longer supported; Use '--prefix' instead" 142 fi 143 144 if ! command -v tar >/dev/null 2>&1; then 145 fatal "The 'tar' tool is required to extract the archive; please install 'tar' and try again" 146 fi 147 148 if ! command -v xz >/dev/null 2>&1; then 149 fatal "The 'xz' tool is required to extract the archive; please install 'xz' or 'xz-utils' and try again" 150 fi 151 152 if ! command -v curl >/dev/null 2>&1; then 153 fatal "The 'curl' tool is required to download the archive; please install 'curl' and try again" 154 fi 155 156 if ! command -v ssh-keygen >/dev/null 2>&1; then 157 fatal "The 'ssh-keygen' tool is required to verify the archive; please install the 'openssh' and try again" 158 fi 159 160 while :; do 161 case "$1" in 162 --no-modify-path) 163 NO_MODIFY_PATH=true 164 ;; 165 --prefix=*) 166 PREFIX=${1#*=} 167 ;; 168 --version=*) 169 VERSION=${1#*=} 170 ;; 171 -h|--help) 172 usage 173 exit 0 ;; 174 -*) 175 error "Unrecognized argument '$1'" 176 echo ; usage ; exit 1 ;; 177 *) 178 break ;; 179 esac 180 shift 181 done 182 183 if [ -z "$VERSION" ]; then 184 fatal "Empty version string; use --version=VERSION" 185 fi 186 187 if [ -z "$PREFIX" ]; then 188 fatal "Empty installation prefix; use --prefix=PATH or set RAD_HOME" 189 fi 190 mkdir -p $PREFIX 191 192 echo 193 echo "👾 Welcome to Radicle" 194 echo 195 196 # Where to install binaries. 197 RAD_PATH=$PREFIX/bin 198 199 info "Detecting operating system..." 200 TARGET=$(target) 201 ARCHIVE="$(mktemp -d)/radicle-$TARGET.tar.xz" # Nb. `-d` must be used on BSDs. 202 URL="$(url "$VERSION" "$TARGET")" 203 204 info "Downloading $URL..." 205 curl --proto '=https' --fail --tlsv1.2 -# -L "$URL" -o "$ARCHIVE" || fatal "Failed to fetch $URL" # Nb. `--tlsv1.3` is not supported on macOS 206 info "Downloading $URL.sig..." 207 curl --proto '=https' --fail --tlsv1.2 -# -L "$URL.sig" -o "$ARCHIVE.sig" || fatal "Failed to fetch $URL.sig" 208 209 info "Verifying $(basename $ARCHIVE)..." 210 verify "$ARCHIVE" 211 212 info "Installing Radicle into $PREFIX..." 213 tar -xJf "$ARCHIVE" --strip-components=1 -C "$PREFIX" 214 215 chmod +x \ 216 $RAD_PATH/radicle-node \ 217 $RAD_PATH/rad \ 218 $RAD_PATH/git-remote-rad 219 220 if ! command -v git >/dev/null 2>&1; then 221 warn 222 warn "Warning: a Git installation was not detected on your system." 223 warn "Warning: please install Git for Radicle to work correctly." 224 fi 225 version="$($RAD_PATH/rad --version | cut -f2 -d' ' -)" 226 227 # If radicle is not in $PATH, add it here. 228 if $NO_MODIFY_PATH; then 229 info "Not modifying shell path variable, as requested." 230 get_started $version 231 elif in_path $RAD_PATH; then 232 info "Radicle is configured in shell already, not modifying." 233 get_started $version 234 else 235 PROFILE="" 236 237 case $SHELL_PATH in 238 */zsh) 239 PROFILE=$HOME/.zshenv ;; 240 */bash) 241 PROFILE=$HOME/.bashrc ;; 242 */fish) 243 PROFILE=$HOME/.config/fish/config.fish ;; 244 */ash) 245 PROFILE=$HOME/.profile ;; 246 */csh) 247 PROFILE=$HOME/.cshrc ;; 248 esac 249 250 if [ -z "$PROFILE" ]; then 251 warn "Warning: unable to update your PATH variable." 252 warn "Warning: please manually add $RAD_PATH to your PATH." 253 get_started $version 254 else 255 info "Configuring path variable in ~${PROFILE#$HOME}..." 256 echo >> "$PROFILE" 257 echo "# Added by Radicle." >> "$PROFILE" 258 echo "export PATH=\"\$PATH:$RAD_PATH\"" >> "$PROFILE" 259 echo 260 261 success $version 262 263 if command -v rad >/dev/null 2>&1; then 264 EXISTING=$(command -v rad) 265 printf "\n" 266 warn "Warning: Pre-existing binaries found at $(dirname "$EXISTING")." 267 warn "Warning: Installed new binaries in $RAD_PATH." 268 fi 269 270 printf "\n" 271 printf "Before running Radicle for the first time,\n" 272 printf "run \033[34m\`source ~${PROFILE#$HOME}\`\033[0m or open a new terminal.\n" 273 274 if ! is_authed; then 275 printf "\n" 276 printf "Then, create your Radicle key pair with \033[35m\`rad auth\`\033[0m.\n" 277 fi 278 fi 279 fi 280 } 281 282 main "$@"