mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Lots of changes to do with redundancy
This commit is contained in:
parent
62d586e2af
commit
279f1a2741
@ -61,6 +61,9 @@ class CsCmdLine(CsDataBag):
|
||||
return self.idata()['router_pr']
|
||||
return 99
|
||||
|
||||
def set_priority(self, val):
|
||||
self.idata()['router_pr'] = val
|
||||
|
||||
def is_redundant(self):
|
||||
if "redundant_router" in self.idata():
|
||||
return self.idata()['redundant_router'] == "true"
|
||||
|
||||
@ -68,8 +68,8 @@ class CsDhcp(CsDataBag):
|
||||
line = "dhcp-option=tag:interface-%s,15,%s" % (device, gn.get_domain())
|
||||
self.conf.search(sline, line)
|
||||
# DNS search order
|
||||
sline = "dhcp-option=tag:interface-%s,119" % device
|
||||
line = "dhcp-option=tag:interface-%s,119,%s" % (device, ','.join(gn.get_dns()))
|
||||
sline = "dhcp-option=tag:interface-%s,6" % device
|
||||
line = "dhcp-option=tag:interface-%s,6,%s" % (device, ','.join(gn.get_dns()))
|
||||
self.conf.search(sline, line)
|
||||
# Gateway
|
||||
gateway = ''
|
||||
@ -103,7 +103,7 @@ class CsDhcp(CsDataBag):
|
||||
"del": False
|
||||
}
|
||||
changed.append(to)
|
||||
|
||||
|
||||
for v in changed:
|
||||
if v['mac'] == to['mac'] or v['ip'] == to['ip'] or v['host'] == to['host']:
|
||||
to['del'] = True
|
||||
|
||||
@ -37,29 +37,29 @@ class CsGuestNetwork:
|
||||
|
||||
def get_dns(self):
|
||||
if not self.guest:
|
||||
return self.config.get_dns()
|
||||
# Can a router provide dhcp but not dns?
|
||||
return self.config.get_dns()
|
||||
# Can a router provide dhcp but not dns?
|
||||
if 'dns' in self.data:
|
||||
return [ self.data['router_guest_gateway'] ] + self.data['dns'].split(',')
|
||||
return [self.data['router_guest_gateway']] + self.data['dns'].split(',')
|
||||
elif "router_guest_gateway" in self.data:
|
||||
return [ self.data['router_guest_gateway'] ]
|
||||
return [self.data['router_guest_gateway']]
|
||||
else:
|
||||
return [""]
|
||||
|
||||
def set_dns(self, val):
|
||||
self.data['dns'] = val
|
||||
self.data['dns'] = val
|
||||
|
||||
def set_router(self, val):
|
||||
self.data['router_guest_gateway'] = val
|
||||
self.data['router_guest_gateway'] = val
|
||||
|
||||
def get_netmask(self):
|
||||
#We need to fix it properly. I just added the if, as Ian did in some other files, to avoid the exception.
|
||||
# We need to fix it properly. I just added the if, as Ian did in some other files, to avoid the exception.
|
||||
if 'router_guest_netmask' in self.data:
|
||||
return self.data['router_guest_netmask']
|
||||
return ''
|
||||
|
||||
def get_gateway(self):
|
||||
#We need to fix it properly. I just added the if, as Ian did in some other files, to avoid the exception.
|
||||
# We need to fix it properly. I just added the if, as Ian did in some other files, to avoid the exception.
|
||||
if 'router_guest_gateway' in self.data:
|
||||
return self.data['router_guest_gateway']
|
||||
return ''
|
||||
|
||||
@ -50,4 +50,4 @@ class CsProcess(object):
|
||||
|
||||
def find(self):
|
||||
has_pid = len(self.find_pid()) > 0
|
||||
return has_pid
|
||||
return has_pid
|
||||
|
||||
@ -43,6 +43,8 @@ from CsConfig import CsConfig
|
||||
class CsRedundant(object):
|
||||
|
||||
CS_RAMDISK_DIR = "/ramdisk"
|
||||
CS_PRIO_UP = 1
|
||||
CS_PRIO_DOWN = -1
|
||||
CS_ROUTER_DIR = "%s/rrouter" % CS_RAMDISK_DIR
|
||||
CS_TEMPLATES = [
|
||||
"heartbeat.sh.templ", "check_heartbeat.sh.templ",
|
||||
@ -50,9 +52,10 @@ class CsRedundant(object):
|
||||
]
|
||||
CS_TEMPLATES_DIR = "/opt/cloud/templates"
|
||||
CONNTRACKD_BIN = "/usr/sbin/conntrackd"
|
||||
CONNTRACKD_LOCK = "/var/lock/conntrack.lock"
|
||||
CONNTRACKD_CONFIG = "/etc/conntrackd/conntrackd.conf"
|
||||
CONNTRACKD_KEEPALIVED_CONFLOCK = "/var/lock/conntrack.lock"
|
||||
CONNTRACKD_CONF = "/etc/conntrackd/conntrackd.conf"
|
||||
RROUTER_LOG = "/var/log/cloud.log"
|
||||
KEEPALIVED_CONF = "/etc/keepalived/keepalived.conf"
|
||||
|
||||
def __init__(self, config):
|
||||
self.cl = config.cmdline()
|
||||
@ -71,8 +74,8 @@ class CsRedundant(object):
|
||||
CsHelper.service("keepalived", "stop")
|
||||
CsHelper.umount_tmpfs(self.CS_RAMDISK_DIR)
|
||||
CsHelper.rmdir(self.CS_RAMDISK_DIR)
|
||||
CsHelper.rm("/etc/conntrackd/conntrackd.conf")
|
||||
CsHelper.rm("/etc/keepalived/keepalived.conf")
|
||||
CsHelper.rm(self.CONNTRACKD_CONF)
|
||||
CsHelper.rm(self.KEEPALIVED_CONF)
|
||||
|
||||
def _redundant_on(self):
|
||||
CsHelper.mkdir(self.CS_RAMDISK_DIR, 0755, False)
|
||||
@ -83,17 +86,18 @@ class CsRedundant(object):
|
||||
if s.endswith(".templ"):
|
||||
d = s.replace(".templ", "")
|
||||
CsHelper.copy_if_needed("%s/%s" % (self.CS_TEMPLATES_DIR, s), "%s/%s" % (self.CS_ROUTER_DIR, d))
|
||||
CsHelper.copy_if_needed("%s/%s" % (self.CS_TEMPLATES_DIR, "keepalived.conf.templ"), "/etc/keepalived/keepalived.conf")
|
||||
CsHelper.copy_if_needed("%s/%s" % (self.CS_TEMPLATES_DIR, "conntrackd.conf.templ"), "/etc/conntrackd/conntrackd.conf")
|
||||
CsHelper.copy_if_needed("%s/%s" % (self.CS_TEMPLATES_DIR, "keepalived.conf.templ"), self.KEEPALIVED_CONF)
|
||||
CsHelper.copy_if_needed("%s/%s" % (self.CS_TEMPLATES_DIR, "conntrackd.conf.templ"), self.CONNTRACKD_CONF)
|
||||
CsHelper.copy_if_needed("%s/%s" % (self.CS_TEMPLATES_DIR, "checkrouter.sh.templ"), "/opt/cloud/bin/checkrouter.sh")
|
||||
|
||||
CsHelper.execute('sed -i "s/--exec\ \$DAEMON;/--exec\ \$DAEMON\ --\ --vrrp;/g" /etc/init.d/keepalived')
|
||||
# checkrouter.sh configuration
|
||||
file = CsFile("/opt/cloud/bin/checkrouter.sh")
|
||||
file.greplace("[RROUTER_LOG]", self.RROUTER_LOG)
|
||||
file.commit()
|
||||
|
||||
# keepalived configuration
|
||||
file = CsFile("/etc/keepalived/keepalived.conf")
|
||||
file = CsFile(self.KEEPALIVED_CONF)
|
||||
file.search(" router_id ", " router_id %s" % self.cl.get_name())
|
||||
file.search(" priority ", " priority %s" % self.cl.get_priority())
|
||||
file.search(" weight ", " weight %s" % 2)
|
||||
@ -103,7 +107,7 @@ class CsRedundant(object):
|
||||
|
||||
# conntrackd configuration
|
||||
guest = self.address.get_guest_if()
|
||||
connt = CsFile("/etc/conntrackd/conntrackd.conf")
|
||||
connt = CsFile(self.CONNTRACKD_CONF)
|
||||
connt.section("Multicast {", "}", [
|
||||
"IPv4_address 225.0.0.50\n",
|
||||
"Group 3780\n",
|
||||
@ -139,7 +143,7 @@ class CsRedundant(object):
|
||||
ads = [o for o in self.address.get_ips() if o.needs_vrrp()]
|
||||
for o in ads:
|
||||
CsHelper.execute("ifconfig %s down" % o.get_device())
|
||||
cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONFIG)
|
||||
cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
|
||||
CsHelper.execute("%s -s" % cmd)
|
||||
CsHelper.service("ipsec", "stop")
|
||||
CsHelper.service("xl2tpd", "stop")
|
||||
@ -163,14 +167,15 @@ class CsRedundant(object):
|
||||
ads = [o for o in self.address.get_ips() if o.is_public()]
|
||||
for o in ads:
|
||||
CsHelper.execute("ifconfig %s down" % o.get_device())
|
||||
cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONFIG)
|
||||
cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
|
||||
CsHelper.execute("%s -d" % cmd)
|
||||
CsHelper.service("ipsec", "stop")
|
||||
CsHelper.service("xl2tpd", "stop")
|
||||
CsHelper.service("cloud-passwd-srvr", "stop")
|
||||
CsHelper.service("dnsmasq", "stop")
|
||||
self._set_priority(self.CS_PRIO_DOWN)
|
||||
self.cl.dbag['config']['redundant_master'] = "false"
|
||||
CsHelper.service("keepalived", "restart")
|
||||
#CsHelper.service("keepalived", "restart")
|
||||
self.cl.save()
|
||||
logging.info("Router switched to backup mode")
|
||||
|
||||
@ -192,7 +197,7 @@ class CsRedundant(object):
|
||||
CsHelper.execute("arping -I %s -A %s -c 1" % (o.get_device(), o.get_ip()))
|
||||
# FIXME Need to add in the default routes but I am unsure what the gateway is
|
||||
# ip route add default via $gw table Table_$dev proto static
|
||||
cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONFIG)
|
||||
cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
|
||||
CsHelper.execute("%s -c" % cmd)
|
||||
CsHelper.execute("%s -f" % cmd)
|
||||
CsHelper.execute("%s -R" % cmd)
|
||||
@ -202,10 +207,17 @@ class CsRedundant(object):
|
||||
CsHelper.service("cloud-passwd-srvr", "restart")
|
||||
CsHelper.service("dnsmasq", "restart")
|
||||
self.cl.dbag['config']['redundant_master'] = "true"
|
||||
self._set_priority(self.CS_PRIO_UP)
|
||||
self.cl.save()
|
||||
CsHelper.service("keepalived", "restart")
|
||||
#CsHelper.service("keepalived", "restart")
|
||||
logging.info("Router switched to master mode")
|
||||
|
||||
def _set_priority(self, dir):
|
||||
self.cl.set_priority(int(self.cl.get_priority()) + dir)
|
||||
file = CsFile(self.KEEPALIVED_CONF)
|
||||
file.search(" priority ", " priority %s" % self.cl.get_priority())
|
||||
file.commit()
|
||||
|
||||
def _collect_ignore_ips(self):
|
||||
"""
|
||||
This returns a list of ip objects that should be ignored
|
||||
@ -232,4 +244,14 @@ class CsRedundant(object):
|
||||
if o.needs_vrrp():
|
||||
str = " %s brd %s dev %s\n" % (o.get_gateway_cidr(), o.get_broadcast(), o.get_device())
|
||||
lines.append(str)
|
||||
# This is wrong set_master and set_backup need to do this
|
||||
self.check_is_up(o.get_device())
|
||||
return lines
|
||||
|
||||
def check_is_up(self, device):
|
||||
""" Ensure device is up """
|
||||
cmd = "ip link show %s | grep 'state DOWN'" % device
|
||||
for i in CsHelper.execute(cmd):
|
||||
if " DOWN " in i:
|
||||
cmd2 = "ip link set %s up" % device
|
||||
CsHelper.execute(cmd2)
|
||||
|
||||
@ -19,11 +19,12 @@ from pprint import pprint
|
||||
|
||||
keys = ['eth1', 'eth2', 'eth3', 'eth4', 'eth5', 'eth6', 'eth7', 'eth8', 'eth9']
|
||||
|
||||
|
||||
def merge(dbag, gn):
|
||||
device = gn['device']
|
||||
|
||||
|
||||
if not gn['add'] and device in dbag:
|
||||
|
||||
|
||||
if dbag[device]:
|
||||
device_to_die = dbag[device][0]
|
||||
try:
|
||||
@ -33,8 +34,8 @@ def merge(dbag, gn):
|
||||
del(dbag[device])
|
||||
else:
|
||||
del(dbag[device])
|
||||
|
||||
|
||||
else:
|
||||
dbag.setdefault(device, []).append(gn)
|
||||
|
||||
return dbag
|
||||
|
||||
return dbag
|
||||
|
||||
10
systemvm/patches/debian/config/opt/cloud/bin/ian.py
Normal file
10
systemvm/patches/debian/config/opt/cloud/bin/ian.py
Normal file
@ -0,0 +1,10 @@
|
||||
from cs.CsGuestNetwork import CsGuestNetwork
|
||||
import merge
|
||||
|
||||
merge.DataBag.DPATH = "."
|
||||
csguestnetwork = CsGuestNetwork({}, {})
|
||||
csguestnetwork.guest = True
|
||||
csguestnetwork.set_dns("1.1.1.1,2.2.2.2")
|
||||
csguestnetwork.set_router("3.3.3.3")
|
||||
dns = csguestnetwork.get_dns()
|
||||
print dns
|
||||
@ -126,7 +126,6 @@ class updateDataBag:
|
||||
|
||||
def processGuestNetwork(self, dbag):
|
||||
d = self.qFile.data
|
||||
|
||||
dp = {}
|
||||
dp['public_ip'] = d['router_guest_ip']
|
||||
dp['netmask'] = d['router_guest_netmask']
|
||||
|
||||
@ -38,11 +38,13 @@ jsonPath = "/var/cache/cloud/%s"
|
||||
jsonCmdConfigPath = jsonPath % sys.argv[1]
|
||||
currentGuestNetConfig = "/etc/cloudstack/guestnetwork.json"
|
||||
|
||||
|
||||
def finish_config():
|
||||
# Converge
|
||||
returncode = configure.main([])
|
||||
sys.exit(returncode)
|
||||
|
||||
|
||||
def process_file():
|
||||
print "[INFO] Processing JSON file %s" % sys.argv[1]
|
||||
qf = QueueFile()
|
||||
@ -51,59 +53,60 @@ def process_file():
|
||||
# Converge
|
||||
finish_config()
|
||||
|
||||
|
||||
def is_guestnet_configured(guestnet_dict, keys):
|
||||
|
||||
|
||||
existing_keys = []
|
||||
new_eth_key = None
|
||||
|
||||
|
||||
for k1, v1 in guestnet_dict.iteritems():
|
||||
if k1 in keys and len(v1) > 0:
|
||||
existing_keys.append(k1)
|
||||
|
||||
|
||||
if not existing_keys:
|
||||
'''
|
||||
It seems all the interfaces have been removed. Let's allow a new configuration to come in.
|
||||
'''
|
||||
print "[WARN] update_config.py :: Reconfiguring guest network..."
|
||||
return False
|
||||
|
||||
|
||||
file = open(jsonCmdConfigPath)
|
||||
new_guestnet_dict = json.load(file)
|
||||
|
||||
|
||||
if not new_guestnet_dict['add']:
|
||||
'''
|
||||
Guest network has to be removed.
|
||||
'''
|
||||
print "[INFO] update_config.py :: Removing guest network..."
|
||||
return False
|
||||
|
||||
|
||||
'''
|
||||
Check if we have a new guest network ready to be setup
|
||||
'''
|
||||
device = new_guestnet_dict['device']
|
||||
|
||||
|
||||
if device in existing_keys:
|
||||
'''
|
||||
Device already configured, ignore.
|
||||
'''
|
||||
return True
|
||||
|
||||
|
||||
exists = False
|
||||
|
||||
|
||||
for key in existing_keys:
|
||||
for interface in guestnet_dict[key]:
|
||||
new_mac = new_guestnet_dict["mac_address"].encode('utf-8')
|
||||
old_mac = interface["mac_address"].encode('utf-8')
|
||||
new_ip = new_guestnet_dict["router_guest_ip"].encode('utf-8')
|
||||
old_ip = interface["router_guest_ip"].encode('utf-8')
|
||||
|
||||
|
||||
if (new_mac == old_mac) and (new_ip == old_ip):
|
||||
exists = True
|
||||
break
|
||||
|
||||
|
||||
if exists:
|
||||
break
|
||||
|
||||
|
||||
return exists
|
||||
|
||||
if not (os.path.isfile(jsonCmdConfigPath) and os.access(jsonCmdConfigPath, os.R_OK)):
|
||||
@ -122,7 +125,7 @@ if sys.argv[1] == "guest_network.json":
|
||||
if os.path.isfile(currentGuestNetConfig):
|
||||
file = open(currentGuestNetConfig)
|
||||
guestnet_dict = json.load(file)
|
||||
|
||||
|
||||
if not is_guestnet_configured(guestnet_dict, ['eth1', 'eth2', 'eth3', 'eth4', 'eth5', 'eth6', 'eth7', 'eth8', 'eth9']):
|
||||
print "[INFO] update_config.py :: Processing Guest Network."
|
||||
process_file()
|
||||
@ -133,5 +136,5 @@ if sys.argv[1] == "guest_network.json":
|
||||
print "[INFO] update_config.py :: No GuestNetwork configured yet. Configuring first one now."
|
||||
process_file()
|
||||
else:
|
||||
print "[INFO] update_config.py :: Processing incoming file => %s" % sys.argv[1]
|
||||
process_file()
|
||||
print "[INFO] update_config.py :: Processing incoming file => %s" % sys.argv[1]
|
||||
process_file()
|
||||
|
||||
@ -52,7 +52,7 @@ vrrp_instance inside_network {
|
||||
}
|
||||
|
||||
!That's the correct path of the master.py file.
|
||||
!notify_master "/opt/cloud/bin/master.py --master"
|
||||
!notify_backup "/opt/cloud/bin/master.py --backup"
|
||||
!notify_fault "/opt/cloud/bin/master.py --fault"
|
||||
notify_master "/opt/cloud/bin/master.py --master"
|
||||
notify_backup "/opt/cloud/bin/master.py --backup"
|
||||
notify_fault "/opt/cloud/bin/master.py --fault"
|
||||
}
|
||||
|
||||
@ -18,6 +18,10 @@ class TestCsCmdLine(unittest.TestCase):
|
||||
def test_get_priority(self):
|
||||
self.assertTrue(self.cscmdline.get_priority() == 99)
|
||||
|
||||
def test_set_priority(self):
|
||||
self.cscmdline.set_priority(100)
|
||||
self.assertTrue(self.cscmdline.get_priority() == 100)
|
||||
|
||||
def test_is_redundant(self):
|
||||
self.assertTrue(self.cscmdline.is_redundant() is False)
|
||||
self.cscmdline.set_redundant()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user