#!/bin/bash # ------- # File: lliurex-cap # Description: LliureX-cap Services manager # Authors: Raul Rodrigo Segura , # Luis Garcia Gisbert # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA # -------- # # Resources Path # DATAC2PATH="" STATUSC2PATH="" LOCKC2PATH="" CAPIP="" CONFDIR="lliurex-cap/" INSTALLDIR="" # # Templates Path # DATAC2TEMPLATEPATH="" STATUSC2TEMPLATEPATH="" LOCKC2TEMPLATEPATH="" function eval_lliurex_vars() { eval $(llxcfg-showvars $LLX_VARS ) } function cap_global_vars() { eval_lliurex_vars CAP_VAR_DIR="/var/lib/lliurex-cap/$CAPNAME" CAP_VAR_CFG_DIR="$CAP_VAR_DIR/config" CAP_STATUS_DIR="$CAP_VAR_DIR/status" CAP_HOSTS="${CAP_VAR_CFG_DIR}/hosts.cap" CAP_ETC_DIR="/etc/lliurex-cap/$CAPNAME" RSYNC_SECRET="$CAP_ETC_DIR/rsync.secrets" CSYNC2_SECRET="$CAP_ETC_DIR/csync2.key" checkasign=0 REPLICANT_SECRET="$(llxcfg-passgen $LDAP_REPLICATOR_NAME show)" || checkasign=1 [ $checkasign -eq 0 ] || REPLICANT_SECRET="" CAP_SECRETS="$RSYNC_SECRET $CSYNC2_SECRET $REPLICANT_SECRET" CAP_CFG_FILE="$CAP_ETC_DIR/lliurex-cap.cfg" CAP_STATUS_FILE="$CAP_STATUS_DIR/${CAP_FQDN}.cap" [ ! -r "$CAP_CFG_FILE" ] || . $CAP_CFG_FILE # FQDN and other variables are required for everything ... [ "$CAP_FQDN" ] || die "Empty CAP_FQDN" [ "$CAP_CLONES_ROOT" ] || die "Empty CAP_CLONES_ROOT" rsync_credentials } function rsync_credentials() { if [ -s $RSYNC_SECRET ] ; then CAP_RSYNCUSER="$(head -1 $RSYNC_SECRET | cut -d ":" -f 1 )" CAP_RSYNCPASS="$(head -1 $RSYNC_SECRET | cut -d ":" -f 2 )" fi } function st_self_fix() { [ "$1" ] || exit 1 LINE="$1" shift [ "$1" ] || exit 1 VALUE="$1" sed -e "$LINE s/.*/$VALUE/" $CAP_STATUS_FILE } function rsync_credentials_test() { [ "$CAP_RSYNCUSER" ] || return 1 [ "$CAP_RSYNCPASS" ] || return 1 return 0 } function cap_create() { if capname_test ; then echo "This cap already exist" return 1 fi cap_populate || return $? cap_configure || return $? cap_create_secrets || return $? llxcfg-rsyncd update chg_rank 7 if [ -s $CAP_CFG_FILE ]; then . $CAP_CFG_FILE fi st_new_status st_self_fix 5 1 } function chg_rank() { [ "$1" ] || die "new rank not especified" [ -s $CAP_CFG_FILE ] || die "Config file not exist" sed -i -e "/^CAP_RANK=/d;\$aCAP_RANK=$1" $CAP_CFG_FILE } function cap_populate() { mkdir -p "$CAP_VAR_CFG_DIR" rsync --ignore-existing --exclude=etc $RSYNC_OPTIONS /usr/share/lliurex-cap/ $CAP_VAR_DIR/ touch "$CAP_HOSTS" CAP_HOST_ID=$(cap_host_add 254) cap_host_activate $CAP_HOST_ID } function cap_remove_config() { rm -fr "$CAP_VAR_DIR" "$CAP_ETC_DIR" } function next_cap_id() { local NEXT_HOST MAX_HOST NEXT_HOST=$FIRST_AUTO_HOST_ID MAX_HOST=$(sed -ne "/$CAP_HOST_REGEXP/s%$CAP_HOST_REGEXP%\2%p" "$CAP_HOSTS" |sort -u |tail -1) [ -z "$MAX_HOST" -o $MAX_HOST -lt $NEXT_HOST ] || NEXT_HOST=$(($MAX_HOST + 1)) echo $NEXT_HOST } function cap_host_add() { local NEXT_HOST NEXT_HOST="$1" [ "$NEXT_HOST" ] || NEXT_HOST=$(next_cap_id) TMP_FILE="$(tempfile -m 644)" cat "$CAP_HOSTS" > "$TMP_FILE" echo -e "1\t${NEXT_HOST}\tNODE-${1}.${CAPNAME}.cap" >> "$TMP_FILE" mv -f "$TMP_FILE" "$CAP_HOSTS" echo $NEXT_HOST } function cap_host_del() { cap_host_change "$1" 9 } function cap_host_change() { # HOST_ID HOST_STATUS sed -i -e "/^[[:digit:]]\+[[:blank:]]\+${1}[[:blank:]]/s%^[[:digit:]]\+%${2}%" "$CAP_HOSTS" } function cap_host_activate() { cap_host_change $1 0 } function cap_host_available() { CAP_LIST="" i=1 while [ $i -lt $CAP_HOST_MAX_ID ] ; do cap_host_search_id "$i" || CAP_LIST="$CAP_LIST $i" i=$(($i + 1)) done #echo "${CAP_COUNT_MSG}${CAP_LIST}" echo "{CAP_LIST}" } function cap_host_list() { sed -ne "/$CAP_HOST_REGEXP_ACTIVE/{s%^0[[:blank:]]\+$CAP_HOST_ID[[:blank:]]\+%$(hostname)@%;s%^0[[:blank:]]\+\([[:digit:]]\+\)[[:blank:]]\+%caphost\1@%;p}" "$CAP_HOSTS" |tr '\n' ' ' } function cap_host_id_test() { [ "$1" ] || return 1 echo "$1" |grep -q "^[[:digit:]]\+$" || return 1 [ $1 -gt 0 ] || return 1 [ $1 -lt $CAP_HOST_MAX_ID -o $1 -eq 254 ] || return 1 return 0 } function cap_host_search_id() { cap_host_id_test "$1" || return 1 grep -q -e "^[[:digit:]]\+[[:blank:]]\+${1}[[:blank:]]" $CAP_HOSTS || return 1 return 0 } function cap_accept() { # some test to accept new members ??? cap_host_add "$1" echo "${CAP_ACCEPT_MSG}${2}" return 0 } function cap_configure() { cap_create_conf ##Check perm . "$CAP_ETC_DIR/lliurex-cap.cfg" # csync2 gen_c2cfg rsync_configure_base rsync_configure_modules return 0 } function cap_reconfigure() { gen_c2cfg rsync_configure_modules llxcfg-rsyncd update llxcfg-cap-scripts reconfigure "$CAPNAME" "$@" || true } function cap_create_conf() { mkdir -p "$CAP_ETC_DIR" TMP_FILE="$(tempfile -m 644)" sed -e "/^[[:blank:]]*CAP_PRINCIPAL=/d" /etc/lliurex-cap/lliurex-cap.cfg > "$TMP_FILE" [ ! -r "$CAP_CFG_FILE" ] || cat "$CAP_CFG_FILE" > "$TMP_FILE" sed -i -e "/^[[:blank:]]*CAP_HOST_ID=/d" "$TMP_FILE" echo "CAP_HOST_ID=$CAP_HOST_ID" >> "$TMP_FILE" # TODO: add more vars mv -f "$TMP_FILE" "$CAP_CFG_FILE" return 0 } function clones_list() { sed -ne "$CLONES_REGEXP" $CAP_VAR_CFG_DIR/clones.cap } function rsync_configure_modules() { ## ## Modules rsync ## # remove old modules BASE_DIR="rsyncd/modules/lliurex-cap/${CAPNAME}/data" for t in $(llxcfg-config list "$BASE_DIR") ; do llxcfg-config delete "$BASE_DIR/$t" done clones_list |while read CAP_CLONE ; do # clones.cap lines are: JUST SHARE_RELATIVE_PATH export CAP_CLONE CAP_RSYNCUSER llxcfg-config read "$CONFDIR/rsyncd/clone.conf" | llxcfg-template - | llxcfg-config write "$BASE_DIR/${CAPNAME}_data_${CAP_CLONE}" done return 0 } function rsync_configure_base() { # config , lock, status ... in "one shot" (full dir /var/lib/lliurex-cap/CAPNAME) llxcfg-config read "$CONFDIR/rsyncd/config.conf" |llxcfg-template - |llxcfg-config write "rsyncd/modules/lliurex-cap/${CAPNAME}/config/${CAPNAME}_config" return 0 } function cap_create_secrets() { echo "##### Generating rsync pass" llxcfg-passgen $CAP_RSYNCUSER gen || return $? echo "##### Generating password file" echo "$CAP_RSYNCUSER:$(cat /etc/lliurex-secrets/passgen/$CAP_RSYNCUSER.secret)" > $RSYNC_SECRET chmod 600 "$RSYNC_SECRET" rsync_credentials llxcfg-passgen $CAP_RSYNCUSER remove || return $? echo "##### Generating csync secret" csync2-key $CSYNC2_SECRET || return $? echo "##### Generating secret file" echo "rsync_secret:$RSYNC_SECRET" > $CAP_VAR_CFG_DIR/secrets.cap echo "csync_secret:$CSYNC2_SECRET" >> $CAP_VAR_CFG_DIR/secrets.cap echo "Done" return 0 } function cap_export_secrets() { for s in $CAP_SECRETS; do [ -r "$s" ] || return 1 done if tar cvzf "$CAP_TARBALL" $CAP_SECRETS ; then echo "${CAP_EXPORT_MSG}${CAP_TARBALL}" else rm -f "$CAP_TARBALL" return 1 fi return 0 } function cap_join() { local rsync_rc # please, I "wannabe" ... # cap_request cap_import_id "$1" || die "Invalid ID from remote host" cap_confirm 2 || die "Unable to confirm host-level 2" cap_import_secrets || die "Unable to import secrets from remote host" cap_confirm 3 || die "Unable to confirm host-level 3" CAP_RSYNCUSER="$(cat $RSYNC_SECRET | cut -d ':' -f1)" [ -n $CAP_RSYNCUSER ] || return 1 # rsync substitutes "populate" [ -d $CAP_VAR_DIR ] || mkdir -p $CAP_VAR_DIR rsync_credentials_test || die "invalid rsync credentials" RSYNC_PASS_FILE=$(tempfile) echo $CAP_RSYNCPASS > $RSYNC_PASS_FILE rsync $RSYNC_OPTIONS --password-file=$RSYNC_PASS_FILE rsync://$CAP_RSYNCUSER@$CAP_REMOTE_HOST/${CAPNAME}_config $CAP_VAR_DIR/ || die "Unable to rsync cap configuratin from remote host" cap_confirm 4 || die "Unable to confirm host-level 4" # activate self locally to generate correct configuration cap_host_activate $CAP_HOST_ID cap_configure llxcfg-rsyncd update # ok, all the configuration is done, so rsync the shares rsync_rc=0 for CAP_CLONE in $(clones_list) ; do if ! rsync $RSYNC_OPTIONS --password-file=$RSYNC_PASS_FILE rsync://$CAP_RSYNCUSER@$CAP_REMOTE_HOST/${CAPNAME}_data_${CAP_CLONE}/${CAP_CLONE} ${CAP_CLONES_ROOT}/ &> /dev/null ; then rsync_rc=1 break fi done rm -f $RSYNC_PASS_FILE if [ $rsync_rc -ne 0 ] ; then cap_host_change $CAP_HOST_ID 4 die "Unable to do initial rsync of cap shares" fi # request activation from remote host if ! cap_confirm 0 ; then cap_host_change $CAP_HOST_ID 0 die "Unable to confirm remote activation of this host" fi # generate status and start challenge sleep 2 st_new_status csync2_status return 0 } function cap_import_secrets() { local rc rc=1 ## tiene que tener el rsync.secret, csync2.key REMOTE_SECRETS="$(sshpass -f "$PASS_FILE" ssh $SSHOPTIONS "${CAP_REMOTE_USER}@${CAP_REMOTE_HOST}" cap-export-secrets "$CAPNAME" |sed -ne "/^$CAP_EXPORT_MSG/{s%^$CAP_EXPORT_MSG%%;p}")" [ "$REMOTE_SECRETS" ] || return 1 LOCAL_SECRETS="$(tempfile -s ".tgz")" if sshpass -f "$PASS_FILE" scp $SSHOPTIONS "${CAP_REMOTE_USER}@${CAP_REMOTE_HOST}:${REMOTE_SECRETS}" "$LOCAL_SECRETS" ; then if [ -s "$LOCAL_SECRETS" ] ; then # TODO: replace this code and extract only "well-know" secret files if tar -C "/" -xvzf "$LOCAL_SECRETS"; then rc=0 rsync_credentials fi fi fi rm -f "$LOCAL_SECRETS" # try to rm remote file sshpass -f "$PASS_FILE" ssh $SSHOPTIONS "${CAP_REMOTE_USER}@${CAP_REMOTE_HOST}" rm -f "${REMOTE_SECRETS}" || true return $rc } function cap_import_id() { CAP_HOST_ID="$(sshpass -f "$PASS_FILE" ssh $SSHOPTIONS "${CAP_REMOTE_USER}@${CAP_REMOTE_HOST}" cap-request "${CAPNAME}" $1 |sed -ne "/^${CAP_ACCEPT_MSG}/{s%^$CAP_ACCEPT_MSG%%;p}")" [ "$CAP_HOST_ID" ] || return 1 return 0 } function cap_confirm() { if sshpass -f "$PASS_FILE" ssh $SSHOPTIONS "${CAP_REMOTE_USER}@${CAP_REMOTE_HOST}" cap-change-level "${CAPNAME}" "$CAP_HOST_ID" "$1" |grep -q "^${CAP_CONFIRM_MSG}$" ; then return 0 fi return 1 } function cap_revokeme() { if sshpass -f "$PASS_FILE" ssh $SSHOPTIONS "${CAP_REMOTE_USER}@${CAP_REMOTE_HOST}" cap-revoke "${CAPNAME}" "$CAP_HOST_ID" |grep -q "^${CAP_REVOKE_MSG}$" ; then return 0 fi return 1 } function gen_c2cfg() { CAP_LISTSERVERS="$(cap_host_list)" TMP_CLONES="$(tempfile)" clones_list |while read CAP_CLONE ; do echo -e " include $CAP_CLONES_ROOT/$CAP_CLONE;" | sed -e "s%/\+%/%g" >> "$TMP_CLONES" done CAP_CLONES_FILE="$TMP_CLONES" export CAP_LISTSERVERS CAP_CLONES_FILE CAP_RSYNCUSER llxcfg-config listfiles "$CONFDIR/csync2" | while read F ; do f="csync2_${CAPNAME}$(basename "$F")" llxcfg-install --cmd=llxcfg-template "$F" "/etc/$f" done rm -f "$TMP_CLONES" # RUN csync2 -C -xr } function add_rsyncresource() { return 0 } function st_status() { if [ -s "$CAP_STATUS_FILE" ] ; then sed -ne "5p" "$CAP_STATUS_FILE" else echo 0 fi } function st_self_ts() { if [ -s "$CAP_STATUS_FILE" ] ; then SELF_TIMESTAMP="$(sed -ne "${1}p" "$CAP_STATUS_FILE")" fi [ "$SELF_TIMESTAMP" ] || SELF_TIMESTAMP=100000000000000 echo $SELF_TIMESTAMP } function is_zero_terminated() { if echo "$1" |grep -q "0$" ; then return 0 fi return 1 } function st_cap_ts() { MAX_TIMESTAMP="$(find "$CAP_STATUS_DIR" -type f -name "*.cap" -exec sed -ne "${1}p" {} \; |sort -u |tail -1)" [ "$MAX_TIMESTAMP" ] || MAX_TIMESTAMP=100000000000000 echo $MAX_TIMESTAMP } function st_update_status() { MUST_UPDATE="" SELF_STATUS=$(st_status) SELF_NEW_TS=$(st_self_ts 1) CAP_NEW_TS=$(st_cap_ts 1) SELF_OLD_TS=$(st_self_ts 2) CAP_OLD_TS=$(st_cap_ts 2) if [ $(( SELF_NEW_TS / 10)) -lt $(( CAP_NEW_TS /10 )) ] ; then MUST_UPDATE="Y" if [ $SELF_STATUS -ne 0 ] ; then SELF_OLD_TS=$SELF_NEW_TS fi SELF_NEW_TS=$CAP_NEW_TS if is_zero_terminated "$CAP_NEW_TS" ; then SELF_NEW_TS=$(($SELF_NEW_TS + 1)) fi fi if [ $SELF_STATUS -ne 0 ] ; then if [ $SELF_OLD_TS -lt $CAP_OLD_TS ] && ! is_zero_terminated "$CAP_OLD_TS" ; then MUST_UPDATE="Y" SELF_STATUS=0 fi fi if [ "$MUST_UPDATE" ] ; then TMP_FILE="$(tempfile -m 644)" RANDOM=$$ cat <"$TMP_FILE" $SELF_NEW_TS $SELF_OLD_TS $CAP_RANK $(($RANDOM%10)) $SELF_STATUS EOF mv -f "$TMP_FILE" "$CAP_STATUS_FILE" csync2_status fi } function st_new_status() { TMP_FILE="$(tempfile -m 644)" RANDOM=$$ cat <"$TMP_FILE" $(date +%Y%m%d%H%M%S)0 $(st_self_ts 1) $CAP_RANK $(($RANDOM%10)) $(st_status) EOF mv -f "$TMP_FILE" "$CAP_STATUS_FILE" csync2_status } function csync2_status() { csync2 -C "${CAPNAME}status" -xr || true } function csync2_config() { csync2 -C "${CAPNAME}config" -xr || true } function csync2_all() { for F in $(find /etc -maxdepth 1 -mindepth 1 -xtype f -name "csync2_${CAPNAME}*") ; do f="$(basename "$F")" c=${f#csync2_} csync2 -C "$c" || true done } function usage() { while [ "$1" ] ; do echo -e "$1" >&2 shift done die "Usage: $(basename "$0") {create} CAP_NAME [SECRET_USER]\n\ $(basename "$0") export-secrets CAP_TARBALL [CAP_NAME]\n\ $(basename "$0") request CAP_NAME HOST_ID\n\ $(basename "$0") revoke CAP_NAME HOST_ID\n\ $(basename "$0") change-level CAP_NAME HOST_ID NEW_STATUS\n\ $(basename "$0") reconfigure CAP_NAME [FILES ...]\n\ $(basename "$0") update-status CAP_NAME [FILES ...]\n\ $(basename "$0") set-default VAR_NAME=VAR_VALUE ... \n\ $(basename "$0") hosts-available CAP_NAME\n\ $(basename "$0") add-config CAP_NAME FILES ...\n\ $(basename "$0") remote REMOTE_USER@REMOTE_HOST[:PASSWD_FILE] COMMAND ... \n\ $(basename "$0") join CAP_NAME [HOST_ID] REMOTE_USER@REMOTE_HOST[:PASSWD_FILE]\n\ $(basename "$0") list-servers CAP_NAME \n\ $(basename "$0") sync-by-rsync CAP_NAME \n\ $(basename "$0") leave CAP_NAME REMOTE_USER@REMOTE_HOST[:PASSWD_FILE]" >&2 } function die() { echo -e "$@" >&2 [ -z "$PASS_FILE" ] || rm -f "$PASS_FILE" [ -z "$RSYNC_PASS_FILE" ] || rm -f "$RSYNC_PASS_FILE" exit 1 } function create_main_conf() { cp "/usr/share/lliurex-cap/lliurex-cap.cfg" "/etc/lliurex-cap/lliurex-cap.cfg" } function capname_test() { [ "$CAPNAME" ] || return 1 [ -d "$CAP_ETC_DIR" ] || return 1 return 0 } function is_user_at_host() { echo "$1" |grep -q "^.\+@.\+$" || return 1 return 0 } function is_host_colon_file() { echo "$1" |grep -q "^.\+:.\+$" || return 1 return 0 } function get_remote_credentials() { is_user_at_host "$1" || usage CAP_REMOTE_USER="${1%@*}" CAP_REMOTE_HOST="${1#*@}" CAP_REMOTE_PASSFILE="" CAP_REMOTE_PASS="" if is_host_colon_file "$CAP_REMOTE_HOST" ; then CAP_REMOTE_PASSFILE="${CAP_REMOTE_HOST#*:}" CAP_REMOTE_HOST="${CAP_REMOTE_HOST%:*}" fi if [ -z "$CAP_REMOTE_PASSFILE" ] ; then read -p "Enter password for user $CAP_REMOTE_USER:" -s CAP_REMOTE_PASS else [ -r "$CAP_REMOTE_PASSFILE" ] || usage CAP_REMOTE_PASS="$(head -1 "$2")" fi [ "$CAP_REMOTE_PASS" ] || die "Invalid Password" PASS_FILE="$(tempfile)" echo "$CAP_REMOTE_PASS" > "$PASS_FILE" } function get_rsync_sync() { rsync_credentials rsync_credentials_test || exit 1 RSYNC_PASS_FILE=$(tempfile -m 600) echo $CAP_RSYNCPASS > $RSYNC_PASS_FILE rsync $RSYNC_OPTIONS --password-file=$RSYNC_PASS_FILE rsync://$CAP_RSYNCUSER@$CAP_REMOTE_HOST/${CAPNAME}_config $CAP_VAR_DIR/ || die "Unable to rsync cap configuratin from remote host" rsync_rc=0 for CAP_CLONE in $(clones_list) ; do if ! rsync $RSYNC_OPTIONS --password-file=$RSYNC_PASS_FILE rsync://$CAP_RSYNCUSER@$CAP_REMOTE_HOST/${CAPNAME}_data_${CAP_CLONE}/${CAP_CLONE} ${CAP_CLONES_ROOT}/ &> /dev/null ; then rsync_rc=1 break fi done rm -f $RSYNC_PASS_FILE } # main # cap-'action' wrapper CMD0="$(basename $0)" if [ "$CMD0" != "lliurex-cap" ] ; then if echo "$CMD0" |grep -q "^cap\-.*$" ; then ARG0="${CMD0#cap-}" exec pe --no-interactive lliurex-cap $ARG0 "$@" fi fi ACTION="$1" # some tests [ "$ACTION" ] || usage shift # global vars CAP_EXPORT_MSG="I am your father:" CAP_ACCEPT_MSG="Join me, and I will complete your training:" CAP_CONFIRM_MSG="You have done well, my apprentice:" CAP_COUNT_MSG="I need a midichlorian count:" CAP_REVOKE_MSG="You cannot hide forever, Luke" CAPNAME="" CAP_SECRETS="" RSYNC_SECRET="" CSYNC2_SECRET="" CAP_ETC_DIR="" CAP_VAR_DIR="" CAP_STATUS_DIR="" CAP_VAR_CFG_DIR="" CAP_HOSTS="" CAP_TARBALL="" CAP_HOST_ID="" CAP_HOST_REGEXP="^\([[:digit:]]\+\)[[:blank:]]\+\([[:digit:]]\+\)[[:blank:]]\+\([^[:blank:]]\+\).*$" CAP_HOST_REGEXP_ACTIVE="^\(0\)[[:blank:]]\+\([^[:blank:]]\+\).*$" CAP_CFG_FILE="/etc/lliurex-cap/$CAP_PRINCIPAL/lliurex-cap.cfg" CAP_FQDN="" CAP_RANK="" CAP_STATUS_FILE="" CAP_RSYNCUSER="C3PO" CAP_RSYNCPASS="" CAP_CLONES_ROOT="/net/" SSHOPTIONS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" RSYNC_OPTIONS="-axA" FIRST_AUTO_HOST_ID=100 CLONES_REGEXP="s%/%%g;/^[[:blank:]]*$/d;/^[[:blank:]]*#/d;p" RSYNC_PASS_FILE="" CAP_HOST_MAX_ID=220 CAP_REMOTE_USER="" CAP_REMOTE_HOST="" PASS_FILE="" # read configuration [ -r "/etc/lliurex-cap/lliurex-cap.cfg" ] || create_main_conf . "/etc/lliurex-cap/lliurex-cap.cfg" [ -z "$CAP_PRINCIPAL" ] || CAPNAME="$CAP_PRINCIPAL" LLX_VARS="LDAP_REPLICATOR_NAME" # [ ! -r "/etc/lliurex-cap/$CAP_PRINCIPAL/lliurex-cap.cfg" ] || . "/etc/lliurex-cap/$CAP_PRINCIPAL/lliurex-cap.cfg" # export some vars. The following vars will be available in templates and scripts export CAPNAME CAP_CLONES_ROOT CAP_ETC_DIR CAP_VAR_DIR CAP_STATUS_DIR CAP_VAR_CFG_DIR CAP_HOST_ID CAP_CFG_FILE CAP_FQDN CAP_RANK CAP_STATUS_FILE rc=0 case "$ACTION" in create) CAPNAME="$1" [ "$CAPNAME" ] || usage [ ! "${2}" ] || CAP_RSYNCUSER="${2}" cap_global_vars cap_create || rc=$? if [ $rc -ne 0 ]; then die "### ERROR ON CREATE CAP ###" fi llxcfg-cap-scripts --stop-on-error create "$CAPNAME" || rc=$? ;; export-secrets) [ -n "$1" ] || usage CAP_TARBALL="$1" shift [ -n "$1" ] || usage CAPNAME="$1" cap_global_vars capname_test || die "Invalid CAPNAME" cap_export_secrets || die "Error exporting secrets" ;; join) [ "$1" ] || usage CAPNAME="$1" ! capname_test || die "CAPNAME already joined" shift [ "$1" ] || usage CAP_NEWHOST_ID="" if ! is_user_at_host "$1" ; then CAP_NEWHOST_ID="$1" shift fi get_remote_credentials "$1" cap_global_vars cap_join "$CAP_NEWHOST_ID" || rc=$? llxcfg-cap-scripts join "$CAPNAME" || rc=$? ;; leave) [ "$1" ] || usage CAPNAME="$1" capname_test || die "Invalid CAPNAME" shift [ "$1" ] || usage get_remote_credentials "$1" cap_global_vars # propagate pending changes csync2_all if cap_revokeme ; then llxcfg-cap-scripts leave "$CAPNAME" || true cap_remove_config else die "Error leaving $CAPNMAE" fi ;; request) [ "$1" ] || usage CAPNAME="$1" shift [ "$1" ] || usage CAP_NEW_HOST="$1" shift CAP_NEWHOST_ID="$1" cap_global_vars [ "$CAP_NEWHOST_ID" ] || CAP_NEWHOST_ID=$(next_cap_id) ! cap_host_search_id $CAP_NEWHOST_ID || die "Invalid HOST_ID" capname_test || die "Invalid CAPNAME" cap_accept "$CAP_NEWHOST_ID" || die "$CAP_NEW_HOST NOT accepted in $CAPNAME" ;; revoke) [ "$1" ] || usage CAPNAME="$1" shift [ "$1" ] || usage CAP_NEWHOST_ID="$1" cap_global_vars cap_host_search_id $CAP_NEWHOST_ID || die "Invalid HOST_ID" # remove host cap_host_del "$CAP_NEWHOST_ID" # reconfigure cap_reconfigure # propagate config csync2_config sleep 2 # start a challenge st_new_status csync2_status # send reply to host echo "$CAP_REVOKE_MSG" ;; change-level) [ "$1" ] || usage "You need CAPNAME\n" CAPNAME="$1" shift [ "$1" ] || usage "You need host id (second param on hosts.cap file)\n" CAP_NEWHOST_ID="$1" shift [ "$1" ] || usage "You need host-level\n" CAP_NEW_STATUS="$1" cap_global_vars capname_test || die "Invalid CAPNAME" cap_host_search_id $CAP_NEWHOST_ID || die "Invalid HOST_ID" cap_host_change $CAP_NEWHOST_ID $CAP_NEW_STATUS if [ $CAP_NEW_STATUS -eq 0 ] ; then # reconfigure cap_reconfigure # propagate config csync2_config # status will be propagated by the new member fi echo "$CAP_CONFIRM_MSG" ;; reconfigure) [ "$1" ] || usage "You need CAPNAME\n" CAPNAME="$1" shift cap_global_vars CFG_REQUIRED="" for f in hosts.cap clones.cap ; do if echo "$*" |grep -q "$f" ; then CFG_REQUIRED="Y" break fi done if [ "$CFG_REQUIRED" ] ; then cap_reconfigure else # only run reconfigure scripts llxcfg-cap-scripts reconfigure "$CAPNAME" "$@" || true fi ;; update-status) [ "$1" ] || usage "You need CAPNAME\n" CAPNAME="$1" shift [ -n "$1" ] || CAP_CHALLENGE_LAUNCHER="$1" cap_global_vars st_update_status ;; set-default) while [ "$1" ] ; do echo "$1" |grep -q "^.\+=.\+$" || usage VAR_NAME="${1%%=*}" sed -i -e "/^[[:blank:]]*${VAR_NAME}=/s/.*/${1}/" /etc/lliurex-cap/lliurex-cap.cfg shift done ;; hosts-available) [ "$1" ] || usage "You need CAPNAME\n" CAPNAME="$1" shift cap_global_vars cap_hosts_available ;; remote) [ "$1" ] || usage "You need REMOTE_USER@RMOTE_HOST\n" get_remote_credentials "$1" shift exec sshpass -f "$PASS_FILE" ssh $SSHOPTIONS "${CAP_REMOTE_USER}@${CAP_REMOTE_HOST}" lliurex-cap "$@" ;; add-config) [ "$1" ] || usage "You need CAPNAME\n" CAPNAME="$1" shift [ "$1" ] || usage "You need some files" cap_global_vars while [ "$1" ] ; do [ -f "$1" ] || usage "$1 is not a valid file" cp "$1" "$CAP_VAR_CFG_DIR" shift done csync2_config ;; list-servers) ##Get all servers without me [ "$1" ] || usage "You need CAPNAME\n" CAPNAME="$1" cap_global_vars [ -r "/etc/lliurex-cap/$CAPNAME/lliurex-cap.cfg" ] || die "This cap no have config" . "/etc/lliurex-cap/$CAPNAME/lliurex-cap.cfg" cap_host_list ;; sync-by-rsync) [ "$1" ] || usage "You need CAPNAME\n" CAPNAME="$1" CAP_REMOTE_HOST="$2" cap_global_vars get_rsync_sync ;; esac exit $rc