Skip to content

Instantly share code, notes, and snippets.

@ryansch
Last active May 19, 2021 17:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryansch/1adefefa50e70b8221025d597263837e to your computer and use it in GitHub Desktop.
Save ryansch/1adefefa50e70b8221025d597263837e to your computer and use it in GitHub Desktop.
Launch a linode from an image
#!/bin/bash
# On macos, this script's deps can be installed with:
# brew install jq python3
# pip3 install linode-cli
# If on another platform, remove the call to pbcopy at the end of the script.
set -euo pipefail
# Adapted from https://serverfault.com/a/298312
menu() {
echo "Avaliable options:"
for i in ${!options[@]}; do
printf "%3d%s) %s\n" $((i+1)) "${choices[i]:- }" "${options[i]}"
done
if [[ "${msg:-}" ]]; then echo "$msg"; fi
}
multi_prompt () {
options=("$@")
result=()
prompt="Check an option (again to uncheck, ENTER when done): "
while menu && read -rp "$prompt" num && [[ "$num" ]]; do
[[ "$num" != *[![:digit:]]* ]] &&
(( num > 0 && num <= ${#options[@]} )) ||
{ msg="Invalid option: $num"; continue; }
((num--)); msg="${options[num]} was ${choices[num]:+un}checked"
[[ "${choices[num]:-}" ]] && choices[num]="" || choices[num]="+"
done
printf "You selected"; msg=" nothing"
for i in ${!options[@]} ; do
[[ "${choices[i]:-}" ]] && { result+=("${options[i]}"); printf " %s" "${options[i]}"; msg=""; }
done
echo "$msg"
echo
}
echo "Choose linode type:"
linode-cli linodes types
types="$(linode-cli linodes types --json | jq -r ".[].id")"
select linode_type in $types ; do
echo "Using $linode_type"
break;
done
echo "Choose image:"
linode-cli images list
images="$(linode-cli images list --json | jq -r ".[].id")"
select linode_image in $images ; do
echo "Using $linode_image"
break;
done
echo "Choose region:"
linode-cli regions list
regions="$(linode-cli regions list --json | jq -r ".[].id")"
select linode_region in $regions ; do
echo "Using $linode_region"
break;
done
ssh_users=()
while IFS=$'\n' read -r user ; do
[[ -n "${user:-}" ]] && ssh_users+=("$user")
done <<< "$(linode-cli users list --json | jq -r 'map(select(.ssh_keys | length > 0)) | .[].username')"
echo "Choose SSH Users"
multi_prompt "${ssh_users[@]}"
if [[ "${#result[@]}" = 0 ]] ; then
echo "Unable to continue without at least one SSH user!"
exit 1
fi
ssh_users="${result[@]}"
echo "Backups enabled?"
select backups_enabled in "true" "false" ; do
echo "Using $backups_enabled"
break;
done
read -p 'Label: ' label
read -s -p 'Root Password: ' password
echo
linode_id="$(linode-cli linodes create \
--type "$linode_type" \
--region "$linode_region" \
--image "$linode_image" \
--root_pass "$password" \
--authorized_users "$ssh_users" \
--booted false \
--backups_enabled "$backups_enabled" \
--label "$label" \
--json \
--format 'id' \
| jq -r ".[0].id")"
echo "Linode:"
linode-cli linodes view "$linode_id"
# wait for linode
echo "Waiting for linode to provision..."
status="$(linode-cli linodes view "$linode_id" --json | jq -r ".[0].status")"
until [[ "$status" = "offline" ]]; do
sleep 1
status="$(linode-cli linodes view "$linode_id" --json | jq -r ".[0].status")"
done
echo "Done!"
total_size="$(linode-cli linodes type-view "$linode_type" --json | jq -r ".[0].disk")"
swap_size="512"
let "new_size=$total_size - $swap_size"
disk_id="$(linode-cli linodes disks-list "$linode_id" --json | jq -r ".[0].id")"
linode-cli linodes disk-resize "$linode_id" "$disk_id" --size "$new_size"
# wait for disk resize
echo "Waiting for disk to resize..."
status="$(linode-cli linodes disk-view "$linode_id" "$disk_id" --json | jq -r ".[0].status")"
until [[ "$status" = "ready" ]]; do
sleep 1
status="$(linode-cli linodes disk-view "$linode_id" "$disk_id" --json | jq -r ".[0].status")"
done
echo "Done!"
echo "Booting linode!"
linode-cli linodes boot "$linode_id"
public_ip="$(linode-cli linodes ips-list "$linode_id" --json | jq -r '.[0].ipv4.public[0].address')"
echo "Public IPv4 address: $public_ip"
echo -n "$public_ip" | pbcopy
echo "(Copied to clipboard)"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment