Page MenuHomeVyOS Platform

keepalived.py
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

keepalived.py

# Copyright 2018 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
import re
import os
import signal
import json
import vyos.util
pid_file = '/var/run/keepalived.pid'
state_file = '/tmp/keepalived.data'
stats_file = '/tmp/keepalived.stats'
json_file = '/tmp/keepalived.json'
state_dir = '/var/run/vyos/vrrp/'
def vrrp_running():
if not os.path.exists(vyos.keepalived.pid_file) \
or not vyos.util.process_running(vyos.keepalived.pid_file):
return False
else:
return True
def keepalived_running():
return vyos.util.process_running(pid_file)
def force_state_data_dump():
pid = vyos.util.read_file(pid_file)
os.kill(int(pid), signal.SIGUSR1)
def force_stats_dump():
pid = vyos.util.read_file(pid_file)
os.kill(int(pid), signal.SIGUSR2)
def force_json_dump():
pid = vyos.util.read_file(pid_file)
os.kill(int(pid), signal.SIGRTMIN+2)
def get_json_data():
with open(json_file, 'r') as f:
j = json.load(f)
return j
def get_statistics():
return vyos.util.read_file(stats_file)
def get_state_data():
return vyos.util.read_file(state_file)
def decode_state(code):
state = None
if code == 0:
state = "INIT"
elif code == 1:
state = "BACKUP"
elif code == 2:
state = "MASTER"
elif code == 3:
state = "FAULT"
else:
state = "UNKNOWN"
return state
## The functions are mainly for transition script wrappers
## to compensate for the fact that keepalived doesn't keep persistent
## state between reloads.
def get_old_state(group):
file = os.path.join(state_dir, "{0}.state".format(group))
if os.path.exists(file):
with open(file, 'r') as f:
data = f.read().strip()
return data
else:
return None
def save_state(group, state):
if not os.path.exists(state_dir):
os.makedirs(state_dir)
file = os.path.join(state_dir, "{0}.state".format(group))
with open(file, 'w') as f:
f.write(state)
## These functions are for the old, and hopefully obsolete plaintext
## (non machine-readable) data format introduced by Vyatta back in the days
## They are kept here just in case, if JSON output option turns out or becomes
## insufficient.
def read_state_data():
with open(state_file, 'r') as f:
lines = f.readlines()
return lines
def parse_keepalived_data(data_lines):
vrrp_groups = {}
# Scratch variable
group_name = None
# Sadly there is no explicit end marker in that format, so we have
# only two states, one before the first VRRP instance is encountered
# and one after an instance/"group" was encountered
# We'll set group_name once the first group is encountered,
# and assume we are inside a group if it's set afterwards
#
# It may not be necessary since the keywords found inside groups and before
# the VRRP Topology section seem to have no intersection,
# but better safe than sorry.
for line in data_lines:
if re.match(r'^\s*VRRP Instance', line, re.IGNORECASE):
# Example: "VRRP Instance = Foo"
name = re.match(r'^\s*VRRP Instance\s+=\s+(.*)$', line, re.IGNORECASE).groups()[0].strip()
group_name = name
vrrp_groups[name] = {}
elif re.match(r'^\s*State', line, re.IGNORECASE) and group_name:
# Example: " State = MASTER"
group_state = re.match(r'^\s*State\s+=\s+(.*)$', line, re.IGNORECASE).groups()[0].strip()
vrrp_groups[group_name]["state"] = group_state
elif re.match(r'^\s*Last transition', line, re.IGNORECASE) and group_name:
# Example: " Last transition = 1532043820 (Thu Jul 19 23:43:40 2018)"
trans_time = re.match(r'^\s*Last transition\s+=\s+(\d+)\s', line, re.IGNORECASE).groups()[0]
vrrp_groups[group_name]["last_transition"] = trans_time
elif re.match(r'^\s*Interface', line, re.IGNORECASE) and group_name:
# Example: " Interface = eth0.30"
interface = re.match(r'\s*Interface\s+=\s+(.*)$', line, re.IGNORECASE).groups()[0].strip()
vrrp_groups[group_name]["interface"] = interface
elif re.match(r'^\s*Virtual Router ID', line, re.IGNORECASE) and group_name:
# Example: " Virtual Router ID = 14"
vrid = re.match(r'^\s*Virtual Router ID\s+=\s+(.*)$', line, re.IGNORECASE).groups()[0].strip()
vrrp_groups[group_name]["vrid"] = vrid
elif re.match(r'^\s*------< Interfaces', line, re.IGNORECASE):
# Interfaces section appears to always be present,
# and there's nothing of interest for us below that section,
# so we use it as an end of input marker
break
return vrrp_groups

File Metadata

Mime Type
text/x-script.python
Expires
Sat, Oct 17, 12:53 AM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4354565
Default Alt Text
keepalived.py (5 KB)

Event Timeline