165 lines
3.9 KiB
Python
165 lines
3.9 KiB
Python
"""
|
|
ucarp.py: defines high-availability IP address controlled by ucarp
|
|
"""
|
|
|
|
from core.nodes.base import CoreNode
|
|
from core.services.coreservices import CoreService
|
|
|
|
UCARP_ETC = "/usr/local/etc/ucarp"
|
|
|
|
|
|
class Ucarp(CoreService):
|
|
name: str = "ucarp"
|
|
group: str = "Utility"
|
|
dirs: tuple[str, ...] = (UCARP_ETC,)
|
|
configs: tuple[str, ...] = (
|
|
UCARP_ETC + "/default.sh",
|
|
UCARP_ETC + "/default-up.sh",
|
|
UCARP_ETC + "/default-down.sh",
|
|
"ucarpboot.sh",
|
|
)
|
|
startup: tuple[str, ...] = ("bash ucarpboot.sh",)
|
|
shutdown: tuple[str, ...] = ("killall ucarp",)
|
|
validate: tuple[str, ...] = ("pidof ucarp",)
|
|
|
|
@classmethod
|
|
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
|
"""
|
|
Return the default file contents
|
|
"""
|
|
if filename == cls.configs[0]:
|
|
return cls.generate_ucarp_conf(node)
|
|
elif filename == cls.configs[1]:
|
|
return cls.generate_vip_up(node)
|
|
elif filename == cls.configs[2]:
|
|
return cls.generate_vip_down(node)
|
|
elif filename == cls.configs[3]:
|
|
return cls.generate_ucarp_boot(node)
|
|
else:
|
|
raise ValueError
|
|
|
|
@classmethod
|
|
def generate_ucarp_conf(cls, node: CoreNode) -> str:
|
|
"""
|
|
Returns configuration file text.
|
|
"""
|
|
ucarp_bin = node.session.options.get("ucarp_bin", "/usr/sbin/ucarp")
|
|
return f"""\
|
|
#!/bin/sh
|
|
# Location of UCARP executable
|
|
UCARP_EXEC={ucarp_bin}
|
|
|
|
# Location of the UCARP config directory
|
|
UCARP_CFGDIR={UCARP_ETC}
|
|
|
|
# Logging Facility
|
|
FACILITY=daemon
|
|
|
|
# Instance ID
|
|
# Any number from 1 to 255
|
|
INSTANCE_ID=1
|
|
|
|
# Password
|
|
# Master and Backup(s) need to be the same
|
|
PASSWORD="changeme"
|
|
|
|
# The failover application address
|
|
VIRTUAL_ADDRESS=127.0.0.254
|
|
VIRTUAL_NET=8
|
|
|
|
# Interface for IP Address
|
|
INTERFACE=lo
|
|
|
|
# Maintanence address of the local machine
|
|
SOURCE_ADDRESS=127.0.0.1
|
|
|
|
# The ratio number to be considered before marking the node as dead
|
|
DEAD_RATIO=3
|
|
|
|
# UCARP base, lower number will be preferred master
|
|
# set to same to have master stay as long as possible
|
|
UCARP_BASE=1
|
|
SKEW=0
|
|
|
|
# UCARP options
|
|
# -z run shutdown script on exit
|
|
# -P force preferred master
|
|
# -n don't run down script at start up when we are backup
|
|
# -M use broadcast instead of multicast
|
|
# -S ignore interface state
|
|
OPTIONS="-z -n -M"
|
|
|
|
# Send extra parameter to down and up scripts
|
|
#XPARAM="-x <enter param here>"
|
|
XPARAM="-x ${{VIRTUAL_NET}}"
|
|
|
|
# The start and stop scripts
|
|
START_SCRIPT=${{UCARP_CFGDIR}}/default-up.sh
|
|
STOP_SCRIPT=${{UCARP_CFGDIR}}/default-down.sh
|
|
|
|
# These line should not need to be touched
|
|
UCARP_OPTS="$OPTIONS -b $UCARP_BASE -k $SKEW -i $INTERFACE -v $INSTANCE_ID -p $PASSWORD -u $START_SCRIPT -d $STOP_SCRIPT -a $VIRTUAL_ADDRESS -s $SOURCE_ADDRESS -f $FACILITY $XPARAM"
|
|
|
|
${{UCARP_EXEC}} -B ${{UCARP_OPTS}}
|
|
"""
|
|
|
|
@classmethod
|
|
def generate_ucarp_boot(cls, node: CoreNode) -> str:
|
|
"""
|
|
Generate a shell script used to boot the Ucarp daemons.
|
|
"""
|
|
return f"""\
|
|
#!/bin/sh
|
|
# Location of the UCARP config directory
|
|
UCARP_CFGDIR={UCARP_ETC}
|
|
|
|
chmod a+x ${{UCARP_CFGDIR}}/*.sh
|
|
|
|
# Start the default ucarp daemon configuration
|
|
${{UCARP_CFGDIR}}/default.sh
|
|
|
|
"""
|
|
|
|
@classmethod
|
|
def generate_vip_up(cls, node: CoreNode) -> str:
|
|
"""
|
|
Generate a shell script used to start the virtual ip
|
|
"""
|
|
return """\
|
|
#!/bin/bash
|
|
|
|
# Should be invoked as "default-up.sh <dev> <ip>"
|
|
exec 2> /dev/null
|
|
|
|
IP="${2}"
|
|
NET="${3}"
|
|
if [ -z "$NET" ]; then
|
|
NET="24"
|
|
fi
|
|
|
|
/sbin/ip addr add ${IP}/${NET} dev "$1"
|
|
|
|
|
|
"""
|
|
|
|
@classmethod
|
|
def generate_vip_down(cls, node: CoreNode) -> str:
|
|
"""
|
|
Generate a shell script used to stop the virtual ip
|
|
"""
|
|
return """\
|
|
#!/bin/bash
|
|
|
|
# Should be invoked as "default-down.sh <dev> <ip>"
|
|
exec 2> /dev/null
|
|
|
|
IP="${2}"
|
|
NET="${3}"
|
|
if [ -z "$NET" ]; then
|
|
NET="24"
|
|
fi
|
|
|
|
/sbin/ip addr del ${IP}/${NET} dev "$1"
|
|
|
|
|
|
"""
|