#!/bin/sh # $Id: pbulk-cluster.sh,v 5.16 2016/02/18 23:53:52 asau Stab $ set -e usage="usage: ${0##*/} [-a agent-script] [-n] [-c mk.conf.fragment] [-l limited-list] [-N node-list] [-p PKGSRCDIR] [-d DISTDIR] [-P PACKAGES] [-R report-base] [basedir]" while getopts "a:nc:l:N:p:d:P:R:" opt; do case $opt in n) native=yes;; c) mk_fragment="${OPTARG}";; l) limited_list="${OPTARG}";; N) node_list="${OPTARG}";; a) agent_script="${OPTARG}";; p) PKGSRCDIR="${OPTARG}";; d) DISTDIR="${OPTARG}";; P) PACKAGES="${OPTARG}";; R) REPORTBASE="${OPTARG}";; \?) echo "$usage" 1>&2; exit 1;; esac done shift $(expr $OPTIND - 1) if [ $# -gt 1 ]; then echo "$usage" 1>&2; exit 1; fi case "$1" in */*) CLUSTERBASE="$1";; # path *) CLUSTERNAME="$1";; # name esac : ${CLUSTERNAME:=pbulk-cluster} : ${JAILBASE:=/usr/jail} : ${CLUSTERBASE:=${JAILBASE}/${CLUSTERNAME}} export JAILBASE="${CLUSTERBASE}/nodes" # from now on NODES="${JAILBASE}" : ${PKGSRCDIR:=${CLUSTERBASE}/pkgsrc} : ${DISTDIR:=${CLUSTERBASE}/mnt/distfiles} : ${PACKAGES:=${CLUSTERBASE}/packages} : ${REPORTBASE:=${CLUSTERBASE}/mnt} : ${agent_script:=${PKGSRCDIR}/mk/pbulk/pbulk.sh} # Unset variables to prevent capturing them from user environment: unset TMP unset TEMP unset TMPDIR if [ ! -d ${PKGSRCDIR} ]; then # require pkgsrc tree echo "${0##*/}: pkgsrc tree required" 1>&2; exit 1 fi if [ ! -f "${agent_script}" ]; then # require pbulk deployment script echo "${0##*/}: pbulk.sh script required" 1>&2; exit 1 fi mkdir -p ${CLUSTERBASE} mkdir -p ${CLUSTERBASE}/mnt mkdir -p ${DISTDIR} mkdir -p ${PACKAGES} mkdir -p ${REPORTBASE} hosts=${CLUSTERBASE}/hosts if [ -r "${node_list}" ]; then cat "${node_list}" > "${hosts}" elif [ ! -r "${hosts}" ]; then echo "${0##*/}: node list is required" 1>&2; exit 1 fi nodes=""; while read addr name; do nodes="${nodes:+$nodes }${name}"; done < ${hosts} if [ ! -e ${CLUSTERBASE}/pbulk.sh ]; then cat "${agent_script}" > ${CLUSTERBASE}/pbulk.sh; fi if [ -n "$limited_list" ]; then cat "$limited_list" > ${CLUSTERBASE}/pbulk.list; fi if [ -n "${mk_fragment}" ]; then cat "${mk_fragment}" > ${CLUSTERBASE}/mk.conf.frag; fi for node in ${nodes}; do JAIL=${NODES}/${node} if [ ! -x ${JAIL}/bin/sh ]; then # create node, if missing create-root ${JAIL} fi start-root ${JAIL} mkdir -p ${JAIL}/usr/pkgsrc && mount -t null -o ro ${PKGSRCDIR} ${JAIL}/usr/pkgsrc mount -t null ${DISTDIR} ${JAIL}/usr/pkgsrc/distfiles mount -t null -o rw ${PACKAGES} ${JAIL}/usr/pkgsrc/packages mount -t null -o rw ${REPORTBASE} ${JAIL}/mnt cat ${CLUSTERBASE}/pbulk.sh > ${JAIL}/root/pbulk.sh if [ -n "${mk_fragment}" ]; then cat ${CLUSTERBASE}/mk.conf.frag > ${JAIL}/root/mk.conf.frag; fi cp /etc/resolv.conf ${JAIL}/etc/resolv.conf cp ${hosts} ${JAIL}/etc/hosts if [ ! -f ${JAIL}/usr/pbulk/etc/mk.conf ]; then (unset PKGSRCDIR; unset DISTDIR; PACKAGES=/usr/pkgsrc/packages exec chroot ${JAIL} /bin/sh /root/pbulk.sh ${native:+-n} ${limited_list:+-l} ${mk_fragment:+-c /root/mk.conf.frag} -d "${nodes}" >/tmp/${CLUSTERBASE##*/}-${node}.out 2>&1); fi { echo PACKAGES=/usr/pkgsrc/packages; echo WRKOBJDIR=/tmp; } > ${JAIL}/etc/profile; mkdir -p ${JAIL}/etc/rc.conf.d; { echo sshd=yes; echo sshd_flags="\"-oPort=122 -oListenAddress=${node} -oPermitRootLogin=yes -oAcceptEnv=WRKOBJDIR -oAcceptEnv=PACKAGES -oAcceptEnv=DISTDIR -oAcceptEnv=FETCH_TIMEOUT\""; } > ${JAIL}/etc/rc.conf.d/sshd; # Create keys and ssh client configuration: # - generate key on master node; # - generate client configuration; # - make slave nodes accept the key. master_node="${nodes%% *}" if [ "${node}" = "${master_node}" ]; then # master node chroot ${JAIL} /bin/sh -c "yes | ssh-keygen -t rsa -b 2048 -N \"\" -C \"root@localhost\" -f /root/.ssh/id_rsa && { echo Port 122; echo StrictHostKeyChecking no; echo SendEnv WRKOBJDIR PACKAGES DISTDIR FETCH_TIMEOUT; } > /root/.ssh/config" else # slave node mkdir -p -m 700 ${JAIL}/root/.ssh && cp -v ${NODES}/${master_node}/root/.ssh/id_rsa.pub ${JAIL}/root/.ssh/authorized_keys; fi done for node in ${nodes}; do JAIL=${NODES}/${node}; chroot ${JAIL} /bin/sh -c "ifconfig lo0 alias ${node}"; chroot ${JAIL} /etc/rc.d/sshd start; done if [ -n "$limited_list" ]; then JAIL=${NODES}/${master_node}; cat ${CLUSTERBASE}/pbulk.list > ${JAIL}/usr/pbulk/etc/pbulk.list; fi # Do it! JAIL=${NODES}/${master_node}; (unset PKGSRCDIR; unset DISTDIR; FETCH_TIMEOUT=600 WRKOBJDIR=/tmp PACKAGES=/usr/pkgsrc/packages exec chroot ${JAIL} /usr/pbulk/bin/bulkbuild >/tmp/${CLUSTERBASE##*/}.out) 2>&1 ||: for node in ${nodes}; do JAIL=${NODES}/${node}; chroot ${JAIL} /etc/rc.d/sshd stop; chroot ${JAIL} /bin/sh -c "ifconfig lo0 -alias ${node}"; done # destructing: for node in ${nodes}; do JAIL=${NODES}/${node} umount ${JAIL}/usr/pkgsrc/packages umount ${JAIL}/usr/pkgsrc/distfiles umount ${JAIL}/usr/pkgsrc umount ${JAIL}/mnt stop-root ${JAIL} done