#! /bin/sh # usage: user=makefu target_system=wry debug=true \ # krebs_cred=~/secrets/cac.json \ # retiolum_key=~/secrets/wry/retiolum.rsa_key.priv \ # infest-cac-centos7 # IMPORTANT: set debug to TRUE if you want to actually keep the system # must be run in <stockholm> set -euf # 2 secrets are required: # login to panel krebs_cred=${krebs_cred-./cac.json} # tinc retiolum key for host retiolum_key=${retiolum_key-./retiolum.rsa_key.priv} # build this host user=${user:-shared} system=${target_system:-test-centos7} log(){ echo "[$(date +"%Y-%m-%d %T")] $@" 2>&1 } clear_defer(){ echo "${trapstr:-exit}" trap - INT TERM EXIT KILL } defer(){ if test -z "${debug:-}"; then trapstr="$1;${trapstr:-exit}" trap "$trapstr" INT TERM EXIT KILL else log "ignored defer: $1" fi } test -z "${debug:-}" && log "debug enabled, vm will not be deleted on error" # Sanity if test ! -r "$krebs_cred";then echo "\$krebs_cred=$krebs_cred must be readable"; exit 1 fi if test ! -r "$retiolum_key";then echo "\$retiolum_key=$retiolum_key must be readable"; exit 1 fi if test ! -r "${user}/1systems/${system}.nix" ;then echo "cannot find ${user}/1systems/${system}.nix , not started in stockholm directory?" exit 1 fi krebs_secrets=$(mktemp -d) sec_file=$krebs_secrets/cac_config krebs_ssh=$krebs_secrets/tempssh export cac_resources_cache=$krebs_secrets/res_cache.json export cac_servers_cache=$krebs_secrets/servers_cache.json export cac_tasks_cache=$krebs_secrets/tasks_cache.json export cac_templates_cache=$krebs_secrets/templates_cache.json defer "trap - INT TERM EXIT" defer "rm -r $krebs_secrets" cat > $sec_file <<EOF cac_login="$(jq -r .email $krebs_cred)" cac_key="$(cac-panel --config $krebs_cred settings | jq -r .apicode)" EOF export cac_secrets=$sec_file log "adding own ip to allowed ips via cac-panel" cac-panel --config $krebs_cred add-api-ip # test login: log "updating cac-api state" cac-api update log "list of cac servers:" cac-api servers # preserve old trap old_trapstr=$(clear_defer) while true;do # Template 26: CentOS7 # TODO: use cac-api templates to determine the real Centos7 template in case it changes out=$(cac-api build cpu=1 ram=512 storage=10 os=26 2>&1) if name=$(echo "$out" | jq -r .servername);then id=servername:$name log "got a working machine, id=$id" else log "Unable to build a virtual machine, retrying in 15 seconds" log "Output of build program: $out" sleep 15 continue fi clear_defer >/dev/null defer "cac-api delete $id" # TODO: timeout? wait_login_cac(){ # we wait for 30 minutes for t in `seq 180`;do # now we have a working cac-api server if cac-api ssh $1 -o ConnectTimeout=10 \ cat /etc/redhat-release >/dev/null 2>&1 ;then return 0 fi log "cac-api ssh $1 failed, retrying" sleep 10 done log "cac-api ssh failed for 30 minutes, assuming something else broke. bailing ou.t" return 1 } # die on timeout if ! wait_login_cac $id;then log "unable to boot a working system within time frame, retrying..." log "Cleaning up old image,last status: $(cac-api update;cac-api getserver $id | jq -r .status)" eval "$(clear_defer | sed 's/;exit//')" sleep 15 else log "got a working system: $id" break fi done clear_defer >/dev/null defer "cac-api delete $id;$old_trapstr" mkdir -p shared/2configs/temp cac-api generatenetworking $id > \ shared/2configs/temp/networking.nix # new temporary ssh key we will use to log in after install ssh-keygen -f $krebs_ssh -N "" cp "$retiolum_key" $krebs_secrets/retiolum.rsa_key.priv # we override the directories for secrets and stockholm # additionally we set the ssh key we generated ip=$(cac-api getserver $id | jq -r .ip) cat > shared/2configs/temp/dirs.nix <<EOF _: { krebs.build.source = { secrets = "$krebs_secrets"; stockholm = "$(pwd)"; }; users.extraUsers.root.openssh.authorizedKeys.keys = [ "$(cat ${krebs_ssh}.pub)" ]; } EOF log "starting prepare and installation" # TODO: try harder make install \ LOGNAME=${user} \ SSHPASS="$(cac-api getserver $id | jq -r .rootpass)" \ ssh='sshpass -e ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' \ system=${system} \ target=$ip log "finalizing installation" cac-api ssh $id < krebs/4lib/infest/finalize.sh log "reset $id" cac-api powerop $id reset wait_login(){ # timeout for t in `seq 90`;do # now we have a working cac-api server if ssh -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ -i $krebs_ssh \ -o ConnectTimeout=10 \ -o BatchMode=yes \ root@$1 nixos-version >/dev/null 2>&1;then log "login to host $1 successful" return 0 fi log "unable to log into server, waiting" sleep 10 done log "unable to log in after 15 minutes, bailing out" return 1 } log "waiting for system to come up" wait_login $ip