#!/bin/bash # Author: An-Cheng Huang # Date: 2007 # Description: command wrapper # **** License **** # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # # 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. # # This code was originally developed by Vyatta, Inc. # Portions created by Vyatta are Copyright (C) 2006, 2007, 2008 Vyatta, Inc. # All Rights Reserved. # **** End License **** if grep -q union=aufs /proc/cmdline || grep -q aufs /proc/filesystems ; then export UNIONFS=aufs else export UNIONFS=unionfs fi # permissions ## note: this script should be running as the vyattacfg group, e.g., with "sg". ## otherwise there may be permission problems with the files created. UMASK_SAVE=`umask` umask 0002 export VYATTA_EDIT_LEVEL=/; export VYATTA_TEMPLATE_LEVEL=/; export VYATTA_ACTIVE_CONFIGURATION_DIR=/opt/vyatta/config/active; # allow env variable to override default session id (ppid). this enables # the script to handle cases where the invocations can come from # different parents. SID=$PPID if [ -n "$CMD_WRAPPER_SESSION_ID" ]; then SID=$CMD_WRAPPER_SESSION_ID fi export VYATTA_CHANGES_ONLY_DIR=/tmp/changes_only_$SID; export VYATTA_TEMP_CONFIG_DIR=/opt/vyatta/config/tmp/new_config_$SID; export VYATTA_CONFIG_TMP=/opt/vyatta/config/tmp/tmp_$SID; vyatta_escape () { # copied over from /etc/bash_completion.d/20vyatta-cfg # $1: \$original # $2: \$escaped eval "$2=\${$1//\%/%25}" eval "$2=\${$2//\*/%2A}" eval "$2=\${$2//\//%2F}" } mvcp () { # copied over from /etc/bash_completion.d/20vyatta-cfg local str=$1 shift local Str=$1 shift local cmd=$1 shift local _otag=$1 local _ovalu=$2 local _to=$3 local _ntag=$4 local _nvalu=$5 local _oval='' local _nval='' local _mpath=${VYATTA_TEMP_CONFIG_DIR}/${VYATTA_EDIT_LEVEL} local _tpath=${VYATTA_CONFIG_TEMPLATE}/${VYATTA_TEMPLATE_LEVEL} vyatta_escape _ovalu _oval vyatta_escape _nvalu _nval if [ "$_to" != 'to' ] || [ -z "$_ntag" ] || [ -z "$_nval" ]; then echo "Invalid $str command" return 1 fi if [ "$_otag" != "$_ntag" ]; then echo "Cannot $str from \"$_otag\" to \"$_ntag\"" return 1 fi if [ ! -d "$_tpath/$_otag/$VYATTA_TAG_NAME" ]; then echo "Cannot $str under \"$_otag\"" return 1 fi if [ ! -d "$_mpath/$_otag/$_oval" ]; then echo "Configuration \"$_otag $_ovalu\" does not exist" return 1 fi if [ -d "$_mpath/$_ntag/$_nval" ]; then echo "Configuration \"$_ntag $_nvalu\" already exists" return 1 fi if ! /opt/vyatta/sbin/my_set $_ntag "$_nvalu"; then echo "$Str failed" return 1 fi /opt/vyatta/sbin/my_delete $_ntag "$_nvalu" >&/dev/null 3>&1 $cmd "$_mpath/$_otag/$_oval" "$_mpath/$_ntag/$_nval" return 0 } do_move () { local -a args=("$@") local pargc (( pargc = ${#args[@]} - 4 )) if (( pargc < 1 )); then echo "Invalid move command \"move $@\"" return 1 fi local -a pargs=("${args[@]:0:$pargc}") args=("${args[@]:$pargc}") local tag=${args[0]} local oval=${args[1]} local to=${args[2]} local nval=${args[3]} if [ -z "$tag" ] || [ -z "$oval" ] || [ "$to" != 'to' ] \ || [ -z "$nval" ]; then echo "Invalid move command \"move $@\"" return 1 fi local _mpath=${VYATTA_TEMP_CONFIG_DIR}/${VYATTA_EDIT_LEVEL} local _tpath=${VYATTA_CONFIG_TEMPLATE}/${VYATTA_TEMPLATE_LEVEL} local idx for (( idx = 0; idx < pargc; idx++ )); do local comp=${pargs[$idx]} vyatta_escape comp comp _mpath="$_mpath/$comp" _tpath="$_tpath/$comp" if [ ! -d $_mpath ]; then # node doesn't exist break fi if [ -d $_tpath ]; then # found non-tag node continue fi # check if it's tag node _tpath=$(dirname $_tpath)/node.tag if [ -d $_tpath ]; then # found tag node continue fi # invalid node break done if (( idx != pargc )); then # invalid node echo "Invalid node path \"${pargs[@]}\"" return 1 fi if [[ "$_tpath" != */node.tag ]]; then # path doesn't end with a tag value. must not have "type". if [ ! -f "$_tpath/node.def" ]; then echo "Invalid node path \"${pargs[@]}\"" return 1 fi if grep -q '^type: ' "$_tpath/node.def"; then echo "Invalid move command \"move $@\"" return 1 fi fi # set edit level VYATTA_EDIT_LEVEL="${_mpath#$VYATTA_TEMP_CONFIG_DIR}/" VYATTA_TEMPLATE_LEVEL="${_tpath#$VYATTA_CONFIG_TEMPLATE}/" mvcp rename Rename mv "$tag" "$oval" 'to' "$tag" "$nval" } RET_STATUS=0 case "$1" in begin) # set up the environment/directories mkdir -p $VYATTA_ACTIVE_CONFIGURATION_DIR mkdir -p $VYATTA_CHANGES_ONLY_DIR if [ ! -d $VYATTA_TEMP_CONFIG_DIR ]; then mkdir -p $VYATTA_TEMP_CONFIG_DIR sudo mount -t $UNIONFS -o dirs=${VYATTA_CHANGES_ONLY_DIR}=rw:${VYATTA_ACTIVE_CONFIGURATION_DIR}=ro $UNIONFS ${VYATTA_TEMP_CONFIG_DIR} fi mkdir -p $VYATTA_CONFIG_TMP ;; end) # tear down the environment/directories sudo umount ${VYATTA_TEMP_CONFIG_DIR} rm -rf ${VYATTA_CHANGES_ONLY_DIR} rm -rf ${VYATTA_CONFIG_TMP} rm -rf ${VYATTA_TEMP_CONFIG_DIR} ;; cleanup|discard) sudo umount ${VYATTA_TEMP_CONFIG_DIR} rm -rf $VYATTA_CHANGES_ONLY_DIR/* $VYATTA_CHANGES_ONLY_DIR/.modified sudo mount -t $UNIONFS -o dirs=${VYATTA_CHANGES_ONLY_DIR}=rw:${VYATTA_ACTIVE_CONFIGURATION_DIR}=ro $UNIONFS ${VYATTA_TEMP_CONFIG_DIR} ;; set) /opt/vyatta/sbin/my_set "${@:2}" RET_STATUS=$? ;; delete) /opt/vyatta/sbin/my_delete "${@:2}" RET_STATUS=$? ;; commit) # debug file /tmp/bar should be deleted before release /opt/vyatta/sbin/my_commit -a >> /tmp/bar /opt/vyatta/sbin/my_commit -s >> /tmp/bar /opt/vyatta/sbin/my_commit -e -d >> /tmp/bar RET_STATUS=$? ;; save) /opt/vyatta/sbin/vyatta-save-config.pl "${@:2}" RET_STATUS=$? ;; load) export vyatta_sysconfdir=/opt/vyatta/etc export vyatta_sbindir=/opt/vyatta/sbin /opt/vyatta/sbin/vyatta-load-config.pl "${@:2}" RET_STATUS=$? ;; rule-rename) # this option is to be used for renaming firewall and nat rules only # usage for this option specified on the next two lines - # rule-rename firewall $firewall_ruleset rule $rule_num to rule $rename_rulenum # rule-rename nat rule $rule_num to rule $rename_rulenum if [ "$2" == "firewall" ]; then VYATTA_TEMPLATE_LEVEL=/firewall/name/node.tag; VYATTA_EDIT_LEVEL="/firewall/name/$3"; elif [ "$2" == "nat" ]; then VYATTA_TEMPLATE_LEVEL=/service/nat; VYATTA_EDIT_LEVEL=/service/nat; fi _mpath=${VYATTA_TEMP_CONFIG_DIR}/${VYATTA_EDIT_LEVEL} _tpath=${VYATTA_CONFIG_TEMPLATE}/${VYATTA_TEMPLATE_LEVEL} VYATTA_EDIT_LEVEL="${_mpath#$VYATTA_TEMP_CONFIG_DIR}/" VYATTA_TEMPLATE_LEVEL="${_tpath#$VYATTA_CONFIG_TEMPLATE}/" if [ $2 == "firewall" ]; then mvcp rename Rename mv "${@:4}" elif [ $2 == "nat" ]; then mvcp rename Rename mv "${@:3}" fi RET_STATUS=$? ;; move) # this is similar to the CLI edit+rename command. # e.g., "move interfaces ethernet eth2 vif 100 to 200" # is similar to "edit interfaces ethernet eth2" plus # "rename vif 100 to vif 200". do_move "${@:2}" RET_STATUS=$? ;; *) echo "Invalid command \"$1\" for vyatta-cfg-cmd-wrapper" RET_STATUS=1 ;; esac umask ${UMASK_SAVE} exit $RET_STATUS