Replace external waitfor script with a function
[autocluster.git] / autocluster
index 77a79a3eeee83a2162f7c95771f2282ad34f2a8d..3c8219f150cc338d394da426d31690e207a94449 100755 (executable)
@@ -54,7 +54,7 @@ EOF
   commands:
      base [ create | boot ] ...
 
-     cluster create
+     cluster [ build | destroy | create | update_hosts | boot | configure ] ...
 
      create base
            create a base image
@@ -88,6 +88,39 @@ die () {
     fi
 }
 
+announce ()
+{
+    echo "######################################################################"
+    printf "# %-66s #\n" "$*"
+    echo "######################################################################"
+    echo ""
+}
+
+waitfor ()
+{
+    local file="$1"
+    local msg="$2"
+    local timeout="$3"
+
+    local tmpfile=$(mktemp)
+
+    cat <<EOF >"$tmpfile"
+spawn tail -n 10000 -f $file
+expect -timeout $timeout -re "$msg"
+EOF
+
+    export LANG=C
+    expect "$tmpfile"
+    rm -f "$tmpfile"
+
+    if ! grep -E "$msg" "$file" > /dev/null; then
+       echo "Failed to find \"$msg\" in \"$file\""
+       return 1
+    fi
+
+    return 0
+}
+
 ###############################
 
 # Indirectly call a function named by ${1}_${2}
@@ -474,6 +507,7 @@ cluster_create ()
 {
     # Use $1.  If not set then use value from configuration file.
     CLUSTER="${1:-${CLUSTER}}"
+    announce "cluster create \"${CLUSTER}\""
     [ -n "$CLUSTER" ] || die "\$CLUSTER not set"
 
     sanity_check_cluster_name
@@ -501,6 +535,101 @@ cluster_created_hosts_message ()
 
 register_hook cluster_created_hooks cluster_created_hosts_message
 
+cluster_destroy ()
+{
+    announce "cluster destroy \"${CLUSTER}\""
+    [ -n "$CLUSTER" ] || die "\$CLUSTER not set"
+
+    vircmd destroy "$CLUSTER" || true
+}
+
+cluster_update_hosts ()
+{
+    announce "cluster update_hosts \"${CLUSTER}\""
+    [ -n "$CLUSTER" ] || die "\$CLUSTER not set"
+
+    [ -n "$hosts_file" ] || hosts_file="tmp/hosts.${CLUSTER}"
+    [ -r "$hosts_file" ] || die "Missing hosts file \"${hosts_file}\""
+
+    local pat="# autocluster ${CLUSTER}\$|[[:space:]]${CLUSTER}(n|base)[[:digit:]]+"
+
+    local t="/etc/hosts.${CLUSTER}"
+    grep -E "$pat" /etc/hosts >"$t" || true
+    if diff -B "$t" "$hosts_file" >/dev/null ; then
+       rm "$t"
+       return
+    fi
+
+    local old=/etc/hosts.old.autocluster
+    cp /etc/hosts "$old"
+    local new=/etc/hosts.new
+    grep -Ev "$pat" "$old" |
+    cat -s - "$hosts_file" >"$new"
+
+    mv "$new" /etc/hosts
+
+    echo "Made these changes to /etc/hosts:"
+    diff -u "$old" /etc/hosts || true
+}
+
+cluster_boot ()
+{
+    [ -n "$CLUSTER_PATTERN" ] || CLUSTER_PATTERN="$CLUSTER"
+    announce "cluster boot \"${CLUSTER_PATTERN}\""
+    [ -n "$CLUSTER_PATTERN" ] || die "\$CLUSTER_PATTERN not set"
+
+    vircmd start "$CLUSTER_PATTERN"
+
+    local nodes=$(vircmd dominfo "$CLUSTER_PATTERN" 2>/dev/null | \
+       sed -n -e 's/Name: *//p')
+
+    # Wait for each node
+    local i
+    for i in $nodes ; do
+       waitfor "${KVMLOG}/serial.$i" "login:" 300 || {
+           vircmd destroy "$CLUSTER_PATTERN"
+           die "Failed to create cluster"
+       }
+    done
+
+    # Move past the last line of log output
+    echo ""
+}
+
+cluster_configure ()
+{
+    announce "cluster configure \"${CLUSTER}\""
+    [ -n "$CLUSTER" ] || die "\$CLUSTER not set"
+
+    local n1="${CLUSTER}n1"
+    local ssh="ssh -o StrictHostKeyChecking=no"
+
+    case "$CLUSTER_TYPE" in
+       "build")
+           $ssh "$n1" ./scripts/install_packages.sh clusterfs build
+           $ssh "$n1" ./scripts/setup_cluster.sh build
+           ;;
+
+       "ad")
+           $ssh "$n1" ./scripts/install_packages.sh ad_server
+           $ssh "$n1" ./scripts/configure_cluster.sh ad_server
+           ;;
+
+       "samba")
+           [ -n "$CLUSTER_PATTERN" ] || CLUSTER_PATTERN="$CLUSTER"
+
+           local nodes=$(vircmd dominfo "$CLUSTER_PATTERN" 2>/dev/null | \
+               sed -n -e 's/Name: *//p')
+
+           for i in $nodes ; do
+               $ssh "$i" ./scripts/install_packages.sh clusterfs nas
+           done
+
+           $ssh "$n1" ./scripts/setup_cluster.sh clusterfs nas
+           ;;
+    esac
+}
+
 create_one_node ()
 {
     CLUSTER="$1"
@@ -1287,7 +1416,13 @@ case "$t" in
        actions_init
        for t in "$@" ; do
            case "$t" in
-               create) actions_add "cluster_${t}" ;;
+               destroy|create|update_hosts|boot|configure)
+                   actions_add "cluster_${t}" ;;
+               build)
+                   for t in destroy create update_hosts boot configure ; do
+                       actions_add "cluster_${t}"
+                   done
+                   ;;
                *) usage ;;
            esac
        done