#!/bin/sh # # Initialize an uncloud VM. This script depends on: # curl grep getent (i.e. glibc) curl,dirname (i.e. coreutils) mktemp # TODO: complete other tasks even if one fail. # TODO: do not up ALL network interfaces. # TODO: write configuration instead of manually setting interfaces up? if [ "$(whoami)" != 'root' ]; then echo "This script must be run as root." >&2 exit 1 fi ### # TODO: handle command-line parameters. ENABLE_NETWORKING=1 DEPLOY_SSH_AUTHORIZED_KEYS=1 OVERRIDE_EXISTING_SSH_AUTHORIZED_KEYS=0 GROW_ROOT_PARTITION=0 SSH_USER=root SSH_DAEMON_CONFIG=/etc/ssh/sshd_config UNCLOUD_METADATA_SERVER=https://key.wf if [ ! $ENABLE_NETWORKING ] && [ $DEPLOY_SSH_AUTHORIZED_KEYS ]; then echo "SSH key deployment requires networking, please review uncloud-init \ configuration." >&2 exit 1 fi ### # Internal logic. deploy_ssh_authorized_keys () { # Ensure SSHD configuration can be found. if [ ! -f "$SSH_DAEMON_CONFIG" ]; then echo "Could not find SSHD configuration at $SSH_DAEMON_CONFIG" >&2 exit 1 fi # Ensure that login is not prevented by SSHD configuration. if [ "$SSH_USER" = "root" ]; then if grep -q -e "^PermitRootLogin no$" "$SSH_DAEMON_CONFIG"; then echo "PermitRootLogin yes" >> "$SSH_DAEMON_CONFIG" fi fi # Get home directory of SSH_USER. User might not exist or have a home # directory. homedir=$(getent passwd "$SSH_USER" | cut -d: -f6) if [ "$homedir" = "" ]; then echo "Could not resolve home directory of user $SSH_USER." >&2 exit 1 fi # Fetch and deploy SSH keys from metadata server. authorized_keys_file="$homedir/.ssh/authorized_keys" mkdir -p "$(dirname "$authorized_keys_file")" if [ -f "$authorized_keys_file" ] \ && [ ! $OVERRIDE_EXISTING_SSH_AUTHORIZED_KEYS ]; then echo "Aborting SSH key deployement to not override existing $authorized_keys_file." echo "You can change this behavior with the OVERRIDE_EXISTING_SSH_AUTHORIZED_KEYS flag." return fi if ! command -v curl; then echo "Could not find or execute curl. Exiting." >&2 exit 1 fi if ! command -v mktemp; then echo "Could not find or execute mktemp. Exiting." >&2 exit 1 fi curl_output=$(mktemp) if ! curl "$UNCLOUD_METADATA_SERVER/ungleich" --output "$curl_output"; then echo "Something went wrong fetching the authorized_keys file from the metedata server." >&2 echo "CURL Output: $(cat "$curl_output")" rm "$curl_output" exit 1 fi mv "$curl_output" "$authorized_keys_file" echo "Deployed $(wc -l < "$authorized_keys_file") entries in $authorized_keys_file." } grow_root_partition () { growpart_script='uncloud-init-growpart' if command -v "$growpart_script"; then # TODO: this command seems quite fragile... # sh growpart -q /dev/vda 3 > /dev/null; true # no-op else echo "Could not find or execute $growpart_script." >&2 exit 1 fi } up_network_interfaces () { interfaces=$(ip -o link | cut -d: -f2 | grep -v '^ lo') for i in $interfaces; do echo "Setting $i UP." ip link set dev "$i" up done } ### # Entrypoint. if [ "$ENABLE_NETWORKING" = '1' ]; then routine='up main network interface' echo "--- RUNNING $routine..." up_network_interfaces echo "--- DONE with $routine." fi if [ "$DEPLOY_SSH_AUTHORIZED_KEYS" = '1' ]; then routine='SSH authorized_keys deployment routine' echo "--- RUNNING $routine..." deploy_ssh_authorized_keys echo "--- DONE with $routine." fi if [ "$GROW_ROOT_PARTITION" = '1' ]; then routine='growing root partition and filesystem' echo "--- RUNNING $routine..." grow_root_partition echo "--- DONE with $routine." fi