Merge pull request #19374 from jempatel/improve_keepalived-uci-sync
keepalived: high-availability files and data sync
This commit is contained in:
commit
05b0d3fc12
18 changed files with 912 additions and 15 deletions
|
@ -274,4 +274,103 @@ endif
|
|||
|
||||
endef
|
||||
|
||||
define Package/keepalived-sync
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=Keepalived Master and Backup Synchronization
|
||||
DEPENDS:= +keepalived +rsync +inotifywait +sudo +@BUSYBOX_CUSTOM +@BUSYBOX_CONFIG_TIMEOUT
|
||||
endef
|
||||
|
||||
define Package/keepalived-sync/description
|
||||
Keepalived HA with Master to Backup files and data Synchronization
|
||||
endef
|
||||
|
||||
define Package/keepalived-sync/conffiles
|
||||
/etc/keepalived/scripts
|
||||
/etc/keepalived/keys
|
||||
endef
|
||||
|
||||
define Package/keepalived-sync/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/etc/init.d/keepalived-inotify \
|
||||
$(1)/etc/init.d/keepalived-inotify
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/share/keepalived/scripts
|
||||
$(INSTALL_BIN) ./files/usr/share/keepalived/scripts/rsync.sh \
|
||||
$(1)/usr/share/keepalived/scripts/rsync.sh
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/keepalived/scripts
|
||||
$(LN) /usr/share/keepalived/scripts/rsync.sh \
|
||||
$(1)/etc/keepalived/scripts/rsync.sh
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) ./files/usr/bin/keepalived-rsync-inotify \
|
||||
$(1)/usr/bin/keepalived-rsync-inotify
|
||||
|
||||
$(INSTALL_DIR) $(1)/lib/functions/keepalived
|
||||
$(INSTALL_DATA) ./files/lib/functions/keepalived/hotplug.sh \
|
||||
$(1)/lib/functions/keepalived/hotplug.sh
|
||||
$(INSTALL_DATA) ./files/lib/functions/keepalived/common.sh \
|
||||
$(1)/lib/functions/keepalived/common.sh
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/libexec/keepalived/rpc
|
||||
$(INSTALL_DATA) ./files/usr/libexec/keepalived/rpc/sync.sh \
|
||||
$(1)/usr/libexec/keepalived/rpc/sync.sh
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/keepalived
|
||||
$(CP) ./files/etc/hotplug.d/keepalived/* \
|
||||
$(1)/etc/hotplug.d/keepalived
|
||||
endef
|
||||
|
||||
USER=keepalived
|
||||
USER_ID=60001
|
||||
USER_HOME=/usr/share/keepalived/rsync
|
||||
SUDO_DIR=/etc/sudoers.d
|
||||
SUDO_FILE=$(SUDO_DIR)/$(USER)
|
||||
KEYS_DIR=/etc/keepalived/keys
|
||||
|
||||
define Package/keepalived-sync/postinst
|
||||
#!/bin/sh
|
||||
|
||||
mkdir -p "$${IPKG_INSTROOT}/etc/uci-defaults"
|
||||
DEFAULT_SCRIPT="$${IPKG_INSTROOT}/etc/uci-defaults/99-keepalived-sync"
|
||||
|
||||
cat << EOF > $${DEFAULT_SCRIPT}
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
mkdir -p $(KEYS_DIR)
|
||||
|
||||
group_add "$(USER)" "$(USER_ID)"
|
||||
user_add "$(USER)" "$(USER_ID)" "$(USER_ID)" "$(USER)" "$(USER_HOME)" "/bin/ash"
|
||||
|
||||
mkdir -m 700 -p "$(USER_HOME)"
|
||||
mkdir -m 700 -p "$(USER_HOME)/.ssh"
|
||||
chown "$(USER)":"$(USER)" "$(USER_HOME)" -R
|
||||
|
||||
[ ! -d "$(SUDO_DIR)" ] && mkdir "$(SUDO_DIR)"
|
||||
echo "$(USER) ALL= NOPASSWD:/usr/bin/rsync" > "$(SUDO_FILE)"
|
||||
EOF
|
||||
|
||||
[ -z "$${IPKG_INSTROOT}" ] && [ -f "$${DEFAULT_SCRIPT}" ] && sh "$${DEFAULT_SCRIPT}"
|
||||
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/keepalived-sync/postrm
|
||||
#!/bin/sh
|
||||
|
||||
[ -n "$${IPKG_INSTROOT}" ] && exit 0
|
||||
|
||||
[ -d "$(KEYS_DIR)" ] && rm -rf "$(KEYS_DIR)"
|
||||
[ -d "$(USER_HOME)" ] && rm -rf "$(USER_HOME)"
|
||||
[ -f "$(SUDO_FILE)" ] && rm -f "$(SUDO_FILE)"
|
||||
|
||||
sed -i -e "/^$(USER):/d" /etc/passwd /etc/shadow /etc/group
|
||||
|
||||
exit 0
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,keepalived))
|
||||
$(eval $(call BuildPackage,keepalived-sync))
|
||||
|
|
12
net/keepalived/files/etc/hotplug.d/keepalived/501-rpcd
Normal file
12
net/keepalived/files/etc/hotplug.d/keepalived/501-rpcd
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions/keepalived/hotplug.sh
|
||||
|
||||
set_service_name rpcd
|
||||
|
||||
set_reload_if_sync
|
||||
|
||||
add_sync_file /etc/config/rpcd
|
||||
|
||||
keepalived_hotplug
|
12
net/keepalived/files/etc/hotplug.d/keepalived/505-system
Normal file
12
net/keepalived/files/etc/hotplug.d/keepalived/505-system
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions/keepalived/hotplug.sh
|
||||
|
||||
set_service_name system
|
||||
|
||||
set_reload_if_sync
|
||||
|
||||
add_sync_file /etc/config/system
|
||||
|
||||
keepalived_hotplug
|
12
net/keepalived/files/etc/hotplug.d/keepalived/509-ucitrack
Normal file
12
net/keepalived/files/etc/hotplug.d/keepalived/509-ucitrack
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions/keepalived/hotplug.sh
|
||||
|
||||
set_service_name ucitrack
|
||||
|
||||
set_reload_if_sync
|
||||
|
||||
add_sync_file /etc/config/ucitrack
|
||||
|
||||
keepalived_hotplug
|
12
net/keepalived/files/etc/hotplug.d/keepalived/511-firewall
Normal file
12
net/keepalived/files/etc/hotplug.d/keepalived/511-firewall
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions/keepalived/hotplug.sh
|
||||
|
||||
set_service_name firewall
|
||||
|
||||
set_reload_if_sync
|
||||
|
||||
add_sync_file /etc/config/firewall
|
||||
|
||||
keepalived_hotplug
|
15
net/keepalived/files/etc/hotplug.d/keepalived/551-dnsmasq
Normal file
15
net/keepalived/files/etc/hotplug.d/keepalived/551-dnsmasq
Normal file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions/keepalived/hotplug.sh
|
||||
|
||||
set_service_name dnsmasq
|
||||
|
||||
set_restart_if_master
|
||||
set_stop_if_backup
|
||||
set_reload_if_sync
|
||||
|
||||
add_sync_file /etc/config/dhcp
|
||||
add_sync_file /tmp/dhcp.leases
|
||||
|
||||
keepalived_hotplug
|
15
net/keepalived/files/etc/hotplug.d/keepalived/555-dropbear
Normal file
15
net/keepalived/files/etc/hotplug.d/keepalived/555-dropbear
Normal file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions/keepalived/hotplug.sh
|
||||
|
||||
set_service_name dropbear
|
||||
|
||||
set_reload_if_backup
|
||||
set_reload_if_sync
|
||||
|
||||
add_sync_file /etc/config/dropbear
|
||||
add_sync_file /etc/dropbear/dropbear_ed25519_host_key
|
||||
add_sync_file /etc/dropbear/dropbear_rsa_host_key
|
||||
|
||||
keepalived_hotplug
|
14
net/keepalived/files/etc/hotplug.d/keepalived/600-uhttpd
Normal file
14
net/keepalived/files/etc/hotplug.d/keepalived/600-uhttpd
Normal file
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions/keepalived/hotplug.sh
|
||||
|
||||
set_service_name uhttpd
|
||||
|
||||
set_restart_if_sync
|
||||
|
||||
add_sync_file /etc/config/uhttpd
|
||||
add_sync_file /etc/uhttpd.crt
|
||||
add_sync_file /etc/uhttpd.key
|
||||
|
||||
keepalived_hotplug
|
8
net/keepalived/files/etc/hotplug.d/keepalived/700-luci
Normal file
8
net/keepalived/files/etc/hotplug.d/keepalived/700-luci
Normal file
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions/keepalived/hotplug.sh
|
||||
|
||||
add_sync_file /etc/config/luci
|
||||
|
||||
keepalived_hotplug
|
18
net/keepalived/files/etc/hotplug.d/keepalived/810-files
Normal file
18
net/keepalived/files/etc/hotplug.d/keepalived/810-files
Normal file
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions/keepalived/hotplug.sh
|
||||
|
||||
add_sync_file /etc/group
|
||||
add_sync_file /etc/hosts
|
||||
add_sync_file /etc/inittab
|
||||
add_sync_file /etc/passwd
|
||||
add_sync_file /etc/rc.local
|
||||
add_sync_file /etc/profile
|
||||
add_sync_file /etc/shadow
|
||||
add_sync_file /etc/shell
|
||||
add_sync_file /etc/shinit
|
||||
add_sync_file /etc/sysctl.conf
|
||||
add_sync_file /tmp/dhcp.leases
|
||||
|
||||
keepalived_hotplug
|
65
net/keepalived/files/etc/init.d/keepalived-inotify
Normal file
65
net/keepalived/files/etc/init.d/keepalived-inotify
Normal file
|
@ -0,0 +1,65 @@
|
|||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
USE_PROCD=1
|
||||
PROG="/usr/bin/keepalived-rsync-inotify"
|
||||
|
||||
KEEPALIVED_USER=keepalived
|
||||
KEEPALIVED_HOME=$(awk -F: "/^$KEEPALIVED_USER/{print \$6}" /etc/passwd)
|
||||
|
||||
start_instance() {
|
||||
local cfg=$1
|
||||
local vrrp_instance=$2
|
||||
local peer=$3
|
||||
|
||||
config_get name $cfg name
|
||||
[ -z "$name" ] && return
|
||||
|
||||
[ "$name" != "$peer" ] && return
|
||||
|
||||
config_get sync $cfg sync 0
|
||||
[ "$sync" = "0" ] && return
|
||||
|
||||
config_get sync_mode $cfg sync_mode
|
||||
[ "$sync_mode" != "receive" ] && return
|
||||
|
||||
config_get sync_dir $cfg sync_dir $KEEPALIVED_HOME
|
||||
[ -z "$sync_dir" ] && return
|
||||
|
||||
[ ! -d "$sync_dir" ] && mkdir -m 755 -p "$sync_dir"
|
||||
|
||||
procd_open_instance "$name"
|
||||
procd_set_param command /bin/sh "$PROG" "$vrrp_instance" "$name" "$sync_dir"
|
||||
procd_set_param pidfile /var/run/keepalived-inotify-$name.pid
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
process_unicast_peer() {
|
||||
local peer=$1
|
||||
local vrrp_instance=$2
|
||||
|
||||
config_foreach start_instance peer "$vrrp_instance" "$peer"
|
||||
}
|
||||
|
||||
process_vrrp_instance() {
|
||||
local cfg=$1
|
||||
local peer_instance=$2
|
||||
local name unicast_peer
|
||||
|
||||
config_get name $cfg name
|
||||
config_get unicast_peer $cfg unicast_peer
|
||||
|
||||
if [ -n "$peer_instance" ]; then
|
||||
list_contains unicast_peer "$peer_instance" || return
|
||||
process_unicast_peer "$peer_instance" "$name"
|
||||
else
|
||||
config_list_foreach $cfg unicast_peer process_unicast_peer "$name"
|
||||
fi
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local peer_instance=$1
|
||||
|
||||
config_load keepalived
|
||||
config_foreach process_vrrp_instance vrrp_instance "$peer_instance"
|
||||
}
|
|
@ -256,6 +256,21 @@ print_track_bfd_indent() {
|
|||
printf '\n' >> "$KEEPALIVED_CONF"
|
||||
}
|
||||
|
||||
print_unicast_peer_indent() {
|
||||
local section="$1"
|
||||
local curr_track_elem="$2"
|
||||
local indent="$3"
|
||||
local name address
|
||||
|
||||
config_get name "$section" name
|
||||
[ "$name" != "$curr_track_elem" ] && return 0
|
||||
|
||||
config_get address "$section" address
|
||||
[ -z "$address" ] && return 0
|
||||
|
||||
printf '%b%s\n' "${indent}" "$address">> "$KEEPALIVED_CONF"
|
||||
}
|
||||
|
||||
static_routes() {
|
||||
local route
|
||||
config_get route "$1" route
|
||||
|
@ -403,7 +418,13 @@ vrrp_instance() {
|
|||
# Handle simple lists of strings (with no spaces in between)
|
||||
for opt in unicast_peer; do
|
||||
config_get "$opt" "$1" "$opt"
|
||||
print_list_indent "$opt"
|
||||
eval optval=\$$opt
|
||||
[ -z "$optval" ] && continue
|
||||
printf '%b%s {\n' "${INDENT_1}" "$opt" >> "$KEEPALIVED_CONF"
|
||||
for t in $optval; do
|
||||
config_foreach print_unicast_peer_indent peer "$t" "$INDENT_2"
|
||||
done
|
||||
printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
|
||||
done
|
||||
unset optval
|
||||
|
||||
|
|
47
net/keepalived/files/lib/functions/keepalived/common.sh
Normal file
47
net/keepalived/files/lib/functions/keepalived/common.sh
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
|
||||
__FILE__="$(basename "$0")"
|
||||
|
||||
KEEPALIVED_USER=keepalived
|
||||
KEEPALIVED_DEBUG=0
|
||||
|
||||
__function__() {
|
||||
type "$1" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
log() {
|
||||
local facility=$1
|
||||
shift
|
||||
logger -t "${__FILE__}[$$]" -p "$facility" "$*"
|
||||
}
|
||||
|
||||
log_info() {
|
||||
log info "$*"
|
||||
}
|
||||
|
||||
log_debug() {
|
||||
[ "$KEEPALIVED_DEBUG" = "0" ] && return
|
||||
log debug "$*"
|
||||
}
|
||||
|
||||
log_notice() {
|
||||
log notice "$*"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
log warn "$*"
|
||||
}
|
||||
|
||||
log_err() {
|
||||
log err "$*"
|
||||
}
|
||||
|
||||
get_rsync_user() {
|
||||
echo "$KEEPALIVED_USER"
|
||||
}
|
||||
|
||||
get_rsync_user_home() {
|
||||
awk -F: "/^$KEEPALIVED_USER/{print \$6}" /etc/passwd
|
||||
}
|
257
net/keepalived/files/lib/functions/keepalived/hotplug.sh
Normal file
257
net/keepalived/files/lib/functions/keepalived/hotplug.sh
Normal file
|
@ -0,0 +1,257 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions/keepalived/common.sh
|
||||
|
||||
set_var() {
|
||||
export "$1=$2"
|
||||
}
|
||||
|
||||
get_var() {
|
||||
eval echo "\"\${${1}}\""
|
||||
}
|
||||
|
||||
get_var_flag() {
|
||||
local value
|
||||
|
||||
value=$(get_var "$1")
|
||||
value=${value:-0}
|
||||
[ "$value" = "0" ] && return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_service() {
|
||||
[ -z "$SERVICE_NAME" ] && return
|
||||
|
||||
local rc="/etc/init.d/$SERVICE_NAME"
|
||||
|
||||
[ ! -x "$rc" ] && return
|
||||
|
||||
case $1 in
|
||||
start) $rc running || $rc start ;;
|
||||
stop) $rc running && $rc stop ;;
|
||||
reload)
|
||||
if $rc running; then
|
||||
$rc reload
|
||||
else
|
||||
$rc start
|
||||
fi
|
||||
;;
|
||||
restart)
|
||||
if $rc running; then
|
||||
$rc restart
|
||||
else
|
||||
$rc start
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_start_service() {
|
||||
_service start
|
||||
}
|
||||
|
||||
_stop_service() {
|
||||
_service stop
|
||||
}
|
||||
|
||||
_restart_service() {
|
||||
_service restart
|
||||
}
|
||||
|
||||
_reload_service() {
|
||||
_service reload
|
||||
}
|
||||
|
||||
set_service_name() {
|
||||
set_var SERVICE_NAME "$1"
|
||||
}
|
||||
|
||||
add_sync_file() {
|
||||
append SYNC_FILES_LIST "$1"
|
||||
}
|
||||
|
||||
is_sync_file() {
|
||||
list_contains SYNC_FILES_LIST "$1"
|
||||
}
|
||||
|
||||
set_update_target() {
|
||||
set_var UPDATE_TARGET "${1:-1}"
|
||||
}
|
||||
|
||||
get_update_target() {
|
||||
get_var UPDATE_TARGET
|
||||
}
|
||||
|
||||
unset_update_target() {
|
||||
set_var UPDATE_TARGET
|
||||
}
|
||||
|
||||
is_update_target() {
|
||||
get_var_flag UPDATE_TARGET
|
||||
}
|
||||
|
||||
set_master_cb() {
|
||||
set_var MASTER_CB "$1"
|
||||
}
|
||||
|
||||
get_master_cb() {
|
||||
get_var MASTER_CB
|
||||
}
|
||||
|
||||
set_backup_cb() {
|
||||
set_var BACKUP_CB "$1"
|
||||
}
|
||||
|
||||
get_backup_cb() {
|
||||
get_var BACKUP_CB
|
||||
}
|
||||
|
||||
set_fault_cb() {
|
||||
set_var FAULT_CB "$1"
|
||||
}
|
||||
|
||||
get_fault_cb() {
|
||||
get_var FAULT_CB
|
||||
}
|
||||
|
||||
set_sync_cb() {
|
||||
set_var SYNC_CB "$1"
|
||||
}
|
||||
|
||||
get_sync_cb() {
|
||||
get_var SYNC_CB
|
||||
}
|
||||
|
||||
set_reload_if_master() {
|
||||
set_var NOTIFY_MASTER_RELOAD 1
|
||||
}
|
||||
|
||||
master_and_reload() {
|
||||
get_var_flag NOTIFY_MASTER_RELOAD
|
||||
}
|
||||
|
||||
set_restart_if_master() {
|
||||
set_var NOTIFY_MASTER_RESTART 1
|
||||
}
|
||||
|
||||
master_and_restart() {
|
||||
get_var_flag NOTIFY_MASTER_RESTART
|
||||
}
|
||||
|
||||
set_reload_if_backup() {
|
||||
set_var NOTIFY_BACKUP_RELOAD 1
|
||||
}
|
||||
|
||||
backup_and_reload() {
|
||||
get_var_flag NOTIFY_BACKUP_RELOAD
|
||||
}
|
||||
|
||||
set_stop_if_backup() {
|
||||
set_var NOTIFY_BACKUP_STOP 1
|
||||
}
|
||||
|
||||
backup_and_stop() {
|
||||
get_var_flag NOTIFY_BACKUP_STOP 1
|
||||
}
|
||||
|
||||
set_reload_if_sync() {
|
||||
set_var NOTIFY_SYNC_RELOAD "${1:-1}"
|
||||
}
|
||||
|
||||
get_reload_if_sync() {
|
||||
get_var NOTIFY_SYNC_RELOAD
|
||||
}
|
||||
|
||||
sync_and_reload() {
|
||||
get_var_flag NOTIFY_SYNC_RELOAD
|
||||
}
|
||||
|
||||
set_restart_if_sync() {
|
||||
set_var NOTIFY_SYNC_RESTART 1
|
||||
}
|
||||
|
||||
sync_and_restart() {
|
||||
get_var_flag NOTIFY_SYNC_RESTART
|
||||
}
|
||||
|
||||
_notify_master() {
|
||||
if master_and_reload; then
|
||||
log_debug "reload service $SERVICE_NAME"
|
||||
_reload_service
|
||||
elif master_and_restart; then
|
||||
log_debug "restart service $SERVICE_NAME"
|
||||
_restart_service
|
||||
fi
|
||||
}
|
||||
|
||||
_notify_backup() {
|
||||
if backup_and_stop; then
|
||||
log_debug "stop service $SERVICE_NAME"
|
||||
_stop_service
|
||||
elif backup_and_reload; then
|
||||
log_debug "restart service $SERVICE_NAME"
|
||||
_restart_service
|
||||
fi
|
||||
}
|
||||
|
||||
_notify_fault() {
|
||||
return 0
|
||||
}
|
||||
|
||||
_notify_sync() {
|
||||
[ -z "$RSYNC_SOURCE" ] && return
|
||||
[ -z "$RSYNC_TARGET" ] && return
|
||||
|
||||
if ! is_update_target; then
|
||||
log_notice "skip $RSYNC_TARGET. Update target not set. To set use \"set_update_target 1\""
|
||||
return
|
||||
fi
|
||||
|
||||
is_sync_file "$RSYNC_TARGET" || return
|
||||
|
||||
if ! cp -a "$RSYNC_SOURCE" "$RSYNC_TARGET"; then
|
||||
log_err "can not copy $RSYNC_SOURCE => $RSYNC_TARGET"
|
||||
return
|
||||
fi
|
||||
|
||||
log_debug "updated $RSYNC_SOURCE to $RSYNC_TARGET"
|
||||
|
||||
if sync_and_reload; then
|
||||
log_debug "reload service $SERVICE_NAME"
|
||||
_reload_service
|
||||
elif sync_and_restart; then
|
||||
log_debug "restart service $SERVICE_NAME"
|
||||
_restart_service
|
||||
fi
|
||||
}
|
||||
|
||||
call_cb() {
|
||||
[ $# -eq 0 ] && return
|
||||
if __function__ "$1"; then
|
||||
log_debug "calling function \"$1\""
|
||||
"$1"
|
||||
else
|
||||
log_err "function \"$1\" not defined"
|
||||
fi
|
||||
}
|
||||
|
||||
keepalived_hotplug() {
|
||||
[ -z "$(get_master_cb)" ] && set_master_cb _notify_master
|
||||
[ -z "$(get_backup_cb)" ] && set_backup_cb _notify_backup
|
||||
[ -z "$(get_fault_cb)" ] && set_fault_cb _notify_fault
|
||||
[ -z "$(get_sync_cb)" ] && set_sync_cb _notify_sync
|
||||
|
||||
[ -z "$(get_update_target)" ] && set_update_target "$@"
|
||||
[ -z "$(get_reload_if_sync)" ] && set_reload_if_sync "$@"
|
||||
|
||||
case $ACTION in
|
||||
NOTIFY_MASTER) call_cb "$(get_master_cb)" ;;
|
||||
NOTIFY_BACKUP) call_cb "$(get_backup_cb)" ;;
|
||||
NOTIFY_FAULT) call_cb "$(get_fault_cb)" ;;
|
||||
NOTIFY_SYNC) call_cb "$(get_sync_cb)" ;;
|
||||
esac
|
||||
}
|
54
net/keepalived/files/usr/bin/keepalived-rsync-inotify
Normal file
54
net/keepalived/files/usr/bin/keepalived-rsync-inotify
Normal file
|
@ -0,0 +1,54 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck shell=ash
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions/keepalived/common.sh
|
||||
|
||||
if [ $# -lt 3 ]; then
|
||||
echo "$0 <vrrp_instance> <peer> <rsync_dir>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VRRP_INSTANCE=$1
|
||||
PEER=$2
|
||||
RSYNC_DIR=$3
|
||||
|
||||
INOTIFY_ACTIONS="create,delete,modify,move,moved_to,moved_from"
|
||||
INOTIFY_PID=""
|
||||
TMP_DIR=/tmp/keepalived
|
||||
FIFO_FILE="$TMP_DIR"/inotifywait-$PEER.fifo
|
||||
|
||||
daemonize_inotifywait() {
|
||||
/usr/bin/inotifywait -q -r --exclude '/\..+' -o "$FIFO_FILE" -m "$RSYNC_DIR" -e ${INOTIFY_ACTIONS} 2> /dev/null &
|
||||
INOTIFY_PID="$!"
|
||||
}
|
||||
|
||||
main() {
|
||||
local inotify_action inotify_dir inotify_file
|
||||
local source_file target_file
|
||||
|
||||
[ ! -d "$TMP_DIR" ] && mkdir "$TMP_DIR"
|
||||
mkfifo "${FIFO_FILE}" || exit 1
|
||||
|
||||
daemonize_inotifywait
|
||||
|
||||
while read -r inotify_dir inotify_action inotify_file; do
|
||||
source_file="${inotify_dir}${inotify_file}"
|
||||
target_file=$(echo "${inotify_dir}" | sed -e "s:${RSYNC_DIR}::g")"${inotify_file}"
|
||||
|
||||
log_debug "received $target_file ($inotify_action) in $source_file"
|
||||
|
||||
ACTION=NOTIFY_SYNC TYPE=peer NAME=$PEER INSTANCE=$VRRP_INSTANCE \
|
||||
RSYNC_SOURCE="${source_file}" RSYNC_TARGET="${target_file}" \
|
||||
/sbin/hotplug-call keepalived
|
||||
done < "$FIFO_FILE"
|
||||
}
|
||||
|
||||
TRAP() {
|
||||
[ -n "$INOTIFY_PID" ] && kill "$INOTIFY_PID"
|
||||
[ -e "$FIFO_FILE" ] && rm -f "$FIFO_FILE"
|
||||
}
|
||||
|
||||
trap TRAP TERM INT
|
||||
main "$@"
|
59
net/keepalived/files/usr/libexec/keepalived/rpc/sync.sh
Normal file
59
net/keepalived/files/usr/libexec/keepalived/rpc/sync.sh
Normal file
|
@ -0,0 +1,59 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /usr/share/libubox/jshn.sh
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions.sh
|
||||
|
||||
peer() {
|
||||
local cfg=$1
|
||||
local c_name=$2
|
||||
local name last_sync_time last_sync_status
|
||||
|
||||
config_get name "$cfg" name
|
||||
[ "$name" != "$c_name" ] && return
|
||||
|
||||
config_get last_sync_time "$cfg" last_sync_time 0
|
||||
config_get last_sync_status "$cfg" last_sync_status NA
|
||||
|
||||
json_add_object unicast_peer
|
||||
json_add_string name "$name"
|
||||
json_add_int time "$last_sync_time"
|
||||
json_add_string status "$last_sync_status"
|
||||
json_close_array
|
||||
}
|
||||
|
||||
unicast_peer() {
|
||||
config_foreach peer peer "$1"
|
||||
}
|
||||
|
||||
vrrp_instance() {
|
||||
local cfg=$1
|
||||
local name
|
||||
|
||||
config_get name "$cfg" name
|
||||
|
||||
json_add_object vrrp_instance
|
||||
json_add_string name "$name"
|
||||
json_add_array unicast_peer
|
||||
config_list_foreach "$cfg" unicast_peer unicast_peer
|
||||
json_close_array
|
||||
json_close_object
|
||||
}
|
||||
|
||||
rsync_status() {
|
||||
config_load keepalived
|
||||
|
||||
json_init
|
||||
json_add_array vrrp_instance
|
||||
config_foreach vrrp_instance vrrp_instance
|
||||
json_close_array
|
||||
json_dump
|
||||
}
|
||||
|
||||
sync_help() {
|
||||
json_add_object rsync_status
|
||||
json_close_object
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions.sh
|
||||
# shellcheck source=/dev/null
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
RPC_SCRIPTS=/usr/libexec/keepalived/rpc
|
||||
|
@ -16,21 +20,22 @@ foreach_extra() {
|
|||
|
||||
[ ! -d $RPC_SCRIPTS ] && return
|
||||
|
||||
for file in $RPC_SCRIPTS/*; do
|
||||
for file in "$RPC_SCRIPTS"/*; do
|
||||
obj="${file##*/}"
|
||||
$1 "${obj%%.*}"
|
||||
done
|
||||
}
|
||||
|
||||
keepalived_dump() {
|
||||
local stats_file="/tmp/keepalived.json"
|
||||
local pids
|
||||
local stats_file pids
|
||||
|
||||
stats_file="/tmp/keepalived.json"
|
||||
|
||||
[ -f "$stats_file" ] && rm -f "$stats_file"
|
||||
|
||||
pids=$(pidof /usr/sbin/keepalived)
|
||||
if [ -n "$pids" ]; then
|
||||
kill -37 $pids > /dev/null 2>&1
|
||||
kill -37 "$pids" > /dev/null 2>&1
|
||||
json_load "{ \"status\" : $(cat $stats_file) }"
|
||||
else
|
||||
json_init
|
||||
|
@ -50,21 +55,28 @@ call_extra() {
|
|||
}
|
||||
|
||||
call_method() {
|
||||
case "$1" in
|
||||
local cmd=$1
|
||||
|
||||
case "$cmd" in
|
||||
dump)
|
||||
keepalived_dump
|
||||
;;
|
||||
*)
|
||||
call_extra $1
|
||||
call_extra "$cmd"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
list_extra() {
|
||||
if __function__ "${1}_help"; then
|
||||
${1}_help
|
||||
local arg func
|
||||
|
||||
arg=$1
|
||||
func="${arg}_help"
|
||||
|
||||
if __function__ "$func"; then
|
||||
$func
|
||||
else
|
||||
json_add_object "$1"
|
||||
json_add_object "$arg"
|
||||
json_close_object
|
||||
fi
|
||||
}
|
||||
|
@ -77,18 +89,21 @@ list_methods() {
|
|||
json_add_object dump
|
||||
json_close_object
|
||||
|
||||
foreach_extra list_extra ${1}
|
||||
foreach_extra list_extra "${1}"
|
||||
|
||||
json_dump
|
||||
}
|
||||
|
||||
main () {
|
||||
case "$1" in
|
||||
main() {
|
||||
local cmd=$1
|
||||
shift
|
||||
|
||||
case "$cmd" in
|
||||
list)
|
||||
list_methods
|
||||
list_methods "$@"
|
||||
;;
|
||||
call)
|
||||
call_method $2
|
||||
call_method "$@"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
|
162
net/keepalived/files/usr/share/keepalived/scripts/rsync.sh
Normal file
162
net/keepalived/files/usr/share/keepalived/scripts/rsync.sh
Normal file
|
@ -0,0 +1,162 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions.sh
|
||||
# shellcheck source=/dev/null
|
||||
. /lib/functions/keepalived/common.sh
|
||||
|
||||
RSYNC_USER=$(get_rsync_user)
|
||||
RSYNC_HOME=$(get_rsync_user_home)
|
||||
|
||||
utc_timestamp() {
|
||||
date -u +%s
|
||||
}
|
||||
|
||||
update_last_sync_time() {
|
||||
uci_revert_state keepalived "$1" last_sync_time
|
||||
uci_set_state keepalived "$1" last_sync_time "$(utc_timestamp)"
|
||||
}
|
||||
|
||||
update_last_sync_status() {
|
||||
local cfg="$1"
|
||||
shift
|
||||
local status="$*"
|
||||
|
||||
uci_revert_state keepalived "$cfg" last_sync_status
|
||||
uci_set_state keepalived "$cfg" last_sync_status "$status"
|
||||
}
|
||||
|
||||
ha_sync_send() {
|
||||
local cfg=$1
|
||||
local address ssh_key ssh_port sync_list sync_dir sync_file count
|
||||
local ssh_options ssh_remote dirs_list files_list
|
||||
local changelog="/tmp/changelog"
|
||||
|
||||
config_get address "$cfg" address
|
||||
[ -z "$address" ] && return 0
|
||||
|
||||
config_get ssh_port "$cfg" ssh_port 22
|
||||
config_get sync_dir "$cfg" sync_dir "$RSYNC_HOME"
|
||||
[ -z "$sync_dir" ] && return 0
|
||||
config_get ssh_key "$cfg" ssh_key "$sync_dir"/.ssh/id_rsa
|
||||
config_get sync_list "$cfg" sync_list
|
||||
|
||||
for sync_file in $sync_list $(sysupgrade -l); do
|
||||
[ -f "$sync_file" ] && {
|
||||
dir="${sync_file%/*}"
|
||||
list_contains files_list "${sync_file}" || append files_list "${sync_file}"
|
||||
}
|
||||
[ -d "$sync_file" ] && dir="${sync_file}"
|
||||
list_contains dirs_list "${sync_dir}${dir}" || append dirs_list "${sync_dir}${dir}"
|
||||
done
|
||||
|
||||
ssh_options="-y -y -i $ssh_key -p $ssh_port"
|
||||
ssh_remote="$RSYNC_USER@$address"
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
timeout 10 ssh $ssh_options $ssh_remote mkdir -m 755 -p "$dirs_list /tmp" || {
|
||||
log_err "can not connect to $address. check key or connection"
|
||||
update_last_sync_time "$cfg"
|
||||
update_last_sync_status "$cfg" "SSH Connection Failed"
|
||||
return 0
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
if rsync --out-format='%n' --dry-run -a --relative ${files_list} -e "ssh $ssh_options" --rsync-path="sudo rsync" "$ssh_remote":"$sync_dir" > "$changelog"; then
|
||||
count=$(wc -l "$changelog")
|
||||
if [ "${count%% *}" = "0" ]; then
|
||||
log_debug "all files are up to date"
|
||||
update_last_sync_time "$cfg"
|
||||
update_last_sync_status "$cfg" "Up to Date"
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
log_err "rsync dry run failed for $address"
|
||||
update_last_sync_time "$cfg"
|
||||
update_last_sync_status "$cfg" "Rsync Detection Failed"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
rsync -a --relative ${files_list} ${changelog} -e "ssh $ssh_options" --rsync-path="sudo rsync" "$ssh_remote":"$sync_dir" || {
|
||||
log_err "rsync transfer failed for $address"
|
||||
update_last_sync_time "$cfg"
|
||||
update_last_sync_status "$cfg" "Rsync Transfer Failed"
|
||||
}
|
||||
|
||||
log_info "keepalived sync is compeleted for $address"
|
||||
update_last_sync_time "$cfg"
|
||||
update_last_sync_status "$cfg" "Successful"
|
||||
}
|
||||
|
||||
ha_sync_receive() {
|
||||
local cfg=$1
|
||||
local ssh_pubkey
|
||||
local name auth_file home_dir
|
||||
|
||||
config_get name "$cfg" name
|
||||
config_get sync_dir "$cfg" sync_dir "$RSYNC_HOME"
|
||||
[ -z "$sync_dir" ] && return 0
|
||||
config_get ssh_pubkey "$cfg" ssh_pubkey
|
||||
[ -z "$ssh_pubkey" ] && return 0
|
||||
|
||||
home_dir=$sync_dir
|
||||
auth_file="$home_dir/.ssh/authorized_keys"
|
||||
|
||||
if ! grep -q "^$ssh_pubkey$" "$auth_file" 2> /dev/null; then
|
||||
log_notice "public key not found. Updating"
|
||||
echo "$ssh_pubkey" > "$auth_file"
|
||||
chown "$RSYNC_USER":"$RSYNC_USER" "$auth_file"
|
||||
fi
|
||||
|
||||
/etc/init.d/keepalived-inotify enabled || /etc/init.d/keepalived-inotify enable
|
||||
/etc/init.d/keepalived-inotify running "$name" || /etc/init.d/keepalived-inotify start "$name"
|
||||
}
|
||||
|
||||
ha_sync_each_peer() {
|
||||
local cfg="$1"
|
||||
local c_name="$2"
|
||||
local name sync sync_mode
|
||||
|
||||
config_get name "$cfg" name
|
||||
[ "$name" != "$c_name" ] && return 0
|
||||
|
||||
config_get sync "$cfg" sync 0
|
||||
[ "$sync" = "0" ] && return 0
|
||||
|
||||
config_get sync_mode "$cfg" sync_mode
|
||||
[ -z "$sync_mode" ] && return 0
|
||||
|
||||
case "$sync_mode" in
|
||||
send) ha_sync_send "$cfg" ;;
|
||||
receive) ha_sync_receive "$cfg" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
ha_sync_peers() {
|
||||
config_foreach ha_sync_each_peer peer "$1"
|
||||
}
|
||||
|
||||
ha_sync() {
|
||||
config_list_foreach "$1" unicast_peer ha_sync_peers
|
||||
}
|
||||
|
||||
main() {
|
||||
local lockfile="/var/lock/keepalived-rsync.lock"
|
||||
|
||||
if ! lock -n "$lockfile" > /dev/null 2>&1; then
|
||||
log_info "another process is already running"
|
||||
return 1
|
||||
fi
|
||||
|
||||
config_load keepalived
|
||||
config_foreach ha_sync vrrp_instance
|
||||
|
||||
lock -u "$lockfile"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
main "$@"
|
Loading…
Reference in a new issue