Lots of changes to do with redundancy
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/61490196 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/61490196 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/61490196 Branch: refs/heads/feature/systemvm-persistent-config Commit: 614901969b7816da3e86657798e1686954dc77e9 Parents: 7f6fb1f Author: Ian Southam <isout...@schubergphilis.com> Authored: Mon Jan 26 14:17:25 2015 +0100 Committer: wilderrodrigues <wrodrig...@schubergphilis.com> Committed: Mon Feb 16 16:08:37 2015 +0100 ---------------------------------------------------------------------- .../debian/config/opt/cloud/bin/cs/CsDatabag.py | 3 ++ .../debian/config/opt/cloud/bin/cs/CsDhcp.py | 6 +-- .../config/opt/cloud/bin/cs/CsGuestNetwork.py | 16 +++---- .../debian/config/opt/cloud/bin/cs/CsProcess.py | 2 +- .../config/opt/cloud/bin/cs/CsRedundant.py | 48 ++++++++++++++------ .../config/opt/cloud/bin/cs_guestnetwork.py | 11 +++-- .../patches/debian/config/opt/cloud/bin/ian.py | 10 ++++ .../debian/config/opt/cloud/bin/merge.py | 1 - .../config/opt/cloud/bin/update_config.py | 33 ++++++++------ .../opt/cloud/templates/keepalived.conf.templ | 6 +-- systemvm/test/python/TestCsCmdLine.py | 4 ++ 11 files changed, 91 insertions(+), 49 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/61490196/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDatabag.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDatabag.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDatabag.py index 0f19a7c..fbafad2 100644 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDatabag.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDatabag.py @@ -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" http://git-wip-us.apache.org/repos/asf/cloudstack/blob/61490196/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py index 173be47..7278785 100644 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py @@ -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 http://git-wip-us.apache.org/repos/asf/cloudstack/blob/61490196/systemvm/patches/debian/config/opt/cloud/bin/cs/CsGuestNetwork.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsGuestNetwork.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsGuestNetwork.py index f9ecbfc..4010007 100644 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsGuestNetwork.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsGuestNetwork.py @@ -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 '' http://git-wip-us.apache.org/repos/asf/cloudstack/blob/61490196/systemvm/patches/debian/config/opt/cloud/bin/cs/CsProcess.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsProcess.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsProcess.py index e768852..afa6310 100644 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsProcess.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsProcess.py @@ -50,4 +50,4 @@ class CsProcess(object): def find(self): has_pid = len(self.find_pid()) > 0 - return has_pid \ No newline at end of file + return has_pid http://git-wip-us.apache.org/repos/asf/cloudstack/blob/61490196/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRedundant.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRedundant.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRedundant.py index aca10b2..d9d36e2 100644 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRedundant.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRedundant.py @@ -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) http://git-wip-us.apache.org/repos/asf/cloudstack/blob/61490196/systemvm/patches/debian/config/opt/cloud/bin/cs_guestnetwork.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs_guestnetwork.py b/systemvm/patches/debian/config/opt/cloud/bin/cs_guestnetwork.py index 6cb29a1..31c0796 100644 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs_guestnetwork.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs_guestnetwork.py @@ -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 \ No newline at end of file + + return dbag http://git-wip-us.apache.org/repos/asf/cloudstack/blob/61490196/systemvm/patches/debian/config/opt/cloud/bin/ian.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/ian.py b/systemvm/patches/debian/config/opt/cloud/bin/ian.py new file mode 100644 index 0000000..17cc466 --- /dev/null +++ b/systemvm/patches/debian/config/opt/cloud/bin/ian.py @@ -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 http://git-wip-us.apache.org/repos/asf/cloudstack/blob/61490196/systemvm/patches/debian/config/opt/cloud/bin/merge.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/merge.py b/systemvm/patches/debian/config/opt/cloud/bin/merge.py index 7229254..4999757 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/merge.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/merge.py @@ -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'] http://git-wip-us.apache.org/repos/asf/cloudstack/blob/61490196/systemvm/patches/debian/config/opt/cloud/bin/update_config.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/update_config.py b/systemvm/patches/debian/config/opt/cloud/bin/update_config.py index e84fd09..77557f9 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/update_config.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/update_config.py @@ -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() \ No newline at end of file + print "[INFO] update_config.py :: Processing incoming file => %s" % sys.argv[1] + process_file() http://git-wip-us.apache.org/repos/asf/cloudstack/blob/61490196/systemvm/patches/debian/config/opt/cloud/templates/keepalived.conf.templ ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/templates/keepalived.conf.templ b/systemvm/patches/debian/config/opt/cloud/templates/keepalived.conf.templ index a79f207..9f3c24b 100644 --- a/systemvm/patches/debian/config/opt/cloud/templates/keepalived.conf.templ +++ b/systemvm/patches/debian/config/opt/cloud/templates/keepalived.conf.templ @@ -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" } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/61490196/systemvm/test/python/TestCsCmdLine.py ---------------------------------------------------------------------- diff --git a/systemvm/test/python/TestCsCmdLine.py b/systemvm/test/python/TestCsCmdLine.py index 8b954d8..87d0471 100644 --- a/systemvm/test/python/TestCsCmdLine.py +++ b/systemvm/test/python/TestCsCmdLine.py @@ -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()