diff --git a/Makefile b/Makefile index dd93d12..1eb835c 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ install: $(INSTALL_CMD) ./client/bin/disco-fs-diff $(EXEC_PREFIX)/disco-fs-diff $(INSTALL_CMD) ./client/bin/disco-sh-exec $(EXEC_PREFIX)/disco-sh-exec $(INSTALL_CMD) ./client/bin/disco-sh-shell $(EXEC_PREFIX)/disco-sh-shell + $(INSTALL_CMD) ./client/bin/disco-shutup $(EXEC_PREFIX)/disco-shutup $(INSTALL_CMD) ./client/bin/disco $(EXEC_PREFIX)/disco $(INSTALL_CMD) ./universe/bin/disco-ball $(EXEC_PREFIX)/disco-ball $(INSTALL_CMD) ./universe/bin/disco-param $(EXEC_PREFIX)/disco-param diff --git a/balls/users/scripts/00-makeusers.sh b/balls/users/scripts/00-makeusers.sh new file mode 100644 index 0000000..1f54eb0 --- /dev/null +++ b/balls/users/scripts/00-makeusers.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +######################## +# 00-makeusers.sh +# +# Make linux users for the 'users' disco ball +# Each user is represented as a key under ${HOSTNAME}/users, with the value +# of each key being a list of useradd/usermod compatible command line flags +# that are passed, one each, directly into usermod/useradd +######################## + +HOSTNAME=$(hostname) + +for username in $(disco-param keys ${HOSTNAME}/users) +do + NAME=$username + PARAMS=$(disco-param get ${HOSTNAME}/users/${NAME}) + getent passwd | grep "^${NAME}" 2>&1 | disco-shutup + RETVAL=$? + if [ $RETVAL -eq 0 ] && [ "$PARAMS" == "" ]; then + userdel ${NAME} + elif [ $RETVAL -ne 0 ]; then + usermod ${PARAMS} ${NAME} + elif [ "$PARAMS" != "" ]; then + useradd ${PARAMS} ${NAME} + fi +done diff --git a/client/bin/disco b/client/bin/disco index 03b2c07..bd3e6a5 100755 --- a/client/bin/disco +++ b/client/bin/disco @@ -18,7 +18,12 @@ function colorize() { } function report() { - for module in $(ls /var/disco/reports/) + if [ "$1" != "" ]; then + MODULELIST="$1" + else + MODULELIST=$(ls /var/disco/reports/) + fi + for module in $MODULELIST; do BASE="report: $module:" for file in $(ls /var/disco/reports/${module}) @@ -51,18 +56,7 @@ function dance() { for module in $(cat /tmp/$$.tsort | tsort | tac) do - echo "info: Processing ${module}" - NOOP="true" disco-ball template $module - NOOP=true /usr/bin/time -f "$TIME" -o /var/disco/reports/${module}/diff disco-fs-diff - if [ "$NOOP" == "" ]; then - rsync -aWH /var/disco/testfs/noop/scratchfs/. /. - fi - NOOP="$NOOP" disco-ball exec $module - RETVAL=$? - rm -rf /var/disco/testfs/noop/scratchfs/* - if [ $RETVAL -ne 0 ]; then - echo "error: Failed to apply $module." - fi + disco-ball spin ${module} done if [ "$REPORT" != "" ]; then diff --git a/client/bin/disco-fs-diff b/client/bin/disco-fs-diff index 68d3fcb..29177d1 100755 --- a/client/bin/disco-fs-diff +++ b/client/bin/disco-fs-diff @@ -23,7 +23,7 @@ while read LINE do FNAME=$(echo $LINE | cut -d : -f 4 | sed s/"^ *"/""/ | sed s/" *$"/""/) MD5_NEW=$(md5sum ${DISCOROOT}/scratchfs${FNAME} 2>/dev/null| cut -d " " -f 1) - STAT_NEW=$(stat --format "owner='%G:%U', selinux='%C', md5='${MD5_NEW}'" ${DISCOROOT}/scratchfs/${FNAME} 2>/dev/null) + STAT_NEW=$(chroot ${DISCOROOT}/chroot stat --format "owner='%G:%U', selinux='%C', md5='${MD5_NEW}'" /${FNAME} 2>/dev/null) if [ ! -d ${FNAME} ] && [ ! -d ${DISCOROOT}/scratchfs${FNAME} ]; then diff -N ${FNAME} ${DISCOROOT}/scratchfs${FNAME} 2>/dev/null > /tmp/$$.diff fi diff --git a/client/bin/disco-fs-init b/client/bin/disco-fs-init index 8bcc00c..bd4c90d 100755 --- a/client/bin/disco-fs-init +++ b/client/bin/disco-fs-init @@ -1,6 +1,7 @@ #!/bin/bash DISCOCFG=/etc/disco + if [ "$NOOP" != "" ]; then DISCOROOT=/var/disco/testfs/noop else diff --git a/client/bin/disco-sh-exec b/client/bin/disco-sh-exec index 43fb8e1..86e17b1 100755 --- a/client/bin/disco-sh-exec +++ b/client/bin/disco-sh-exec @@ -8,7 +8,7 @@ fi mount | grep $DISCOROOT >/dev/null 2>&1 if [ $? -ne 0 ]; then - ./disco-fs-mount || exit 1 + echo "disco filesystem is not mounted; please mount it and try again." fi # Strip out any shebang and put the script in the root diff --git a/universe/bin/disco-ball b/universe/bin/disco-ball index 8e3699b..b76d498 100755 --- a/universe/bin/disco-ball +++ b/universe/bin/disco-ball @@ -11,7 +11,7 @@ mkdir -p ${DISCOROOT}/reports/_internal function init() { if [ "$1" == "" ]; then echo "Must enter a path to initialize" >&2 - exit 1 + return 1 fi mkdir -p $1/templates mkdir -p $1/scripts @@ -28,34 +28,39 @@ function fetch_params() { /usr/bin/time -f "$TIME" -o ${DISCOROOT}/reports/_internal/fetch_params /bin/bash /tmp/$$.sh RETVAL=$? rm -f /tmp/$$.sh - exit $RETVAL + return $RETVAL } function fetch() { if [ "$1" == "" ]; then echo "Must pass a module name to fetch" - exit 1 + return 1 + fi + if [ "$NOOP" == "" ]; then + DEST=/var/disco/testfs/real/scratchfs + else + DEST=/var/disco/testfs/noop/scratchfs fi rm -rf ${STORAGE}/${1} mkdir -p ${DISCOROOT}/reports/$1 rm -f ${DISCOROOT}/reports/${1}/fetch # Sometimes there's some shell escaping voodoo and rsync doesn't like the command args some people will pass it straight on # the command line; so we wrap it in a little bash script, and everyone's happy. - echo ${RSYNC} ${SERVERURI}::${1}/files/* / > /tmp/$$.sh + echo ${RSYNC} ${SERVERURI}::${1}/files/* ${DEST} > /tmp/$$.sh echo ${RSYNC} --delete ${SERVERURI}::${1}/requires ${SERVERURI}::${1}/scripts ${SERVERURI}::${1}/parameters ${SERVERURI}::${1}/templates ${STORAGE}/${1} >> /tmp/$$.sh echo 'exit $?' >> /tmp/$$.sh - /usr/bin/time -f "$TIME" -o ${DISCOROOT}/reports/${1}/fetch /bin/bash /tmp/$$.sh 2>/tmp/$$.errors | sed s/"^"/"info: ${1}: "/g + /usr/bin/time -f "$TIME" -o ${DISCOROOT}/reports/${1}/fetch /tmp/$$.sh 2>/tmp/$$.errors | sed s/"^"/"info: ${1}: "/g cat /tmp/$$.errors | grep -v "some files/attrs were not transferred" | sed s/"^"/"error: ${1}: "/g RETVAL=$? rm -f /tmp/$$.sh - exit $RETVAL + return $RETVAL } function requires() { if [ "$1" == "" ]; then echo "Must pass a module name for requirements" - exit 1 + return 1 fi cat ${STORAGE}/${1}/requires | sed s/"^"/"${1} "/g } @@ -73,13 +78,13 @@ function exec() { cat /tmp/$$.exec.time | sed s/"^"/" "/g >> ${DISCOROOT}/reports/${1}/exec done rm -f /tmp/$$.exec.time - exit $RETVAL + return $RETVAL } function template() { if [ "$1" == "" ]; then echo "Must pass a module name to template" - exit 1 + return 1 fi mkdir -p ${DISCOROOT}/reports/$1 rm -f ${DISCOROOT}/reports/${1}/template @@ -87,6 +92,9 @@ function template() { if [ "$NOOP" != "" ]; then DESTROOT=/var/disco/testfs/noop/scratchfs fi + if [ ! -d ${STORAGE}/${1}/templates ]; then + return 0; + fi cd ${STORAGE}/${1}/templates RETVAL=0 for file in $(find . -type f | sed s/"^\.\/"//g) @@ -103,7 +111,32 @@ function template() { fi done rm -f /tmp/$$.template.time - exit $RETVAL + return $RETVAL +} + +function spin() { + module=$1 + echo "info: Processing ${module}" + NOOP="true" template $module + if [ "$NOOP" == "" ]; then + # We rsync all the configs and files into the 'real' scratchfs so that we can + # just do one big diff at the very end, capturing every single disk change, + # including ones made by the scripts. + rsync -aWH /var/disco/testfs/noop/scratchfs/. /var/disco/testfs/real/scratchfs/ + fi + NOOP="$NOOP" exec $module + RETVAL=$? + /usr/bin/time -f "$TIME" -o /var/disco/reports/${module}/diff disco-fs-diff + if [ "$NOOP" == "" ]; then + # Now for the real rsync back home + rsync -aWH /var/disco/testfs/real/scratchfs/. / + fi + rm -rf /var/disco/testfs/noop/scratchfs/* + rm -rf /var/disco/testfs/real/scratchfs/* + if [ $RETVAL -ne 0 ]; then + echo "error: Failed to apply $module." + fi + return $? } $1 $2