From b9dd67c383874ef7273205e0eac831de497bb02d Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Thu, 18 Jun 2015 16:42:08 +0200 Subject: [PATCH] =?UTF-8?q?CLOUDSTACK-8545=20port=20of=20the=20fix=20to=20?= =?UTF-8?q?not=20reboot=20routers=20on=20out=20of=20band=20migration=20per?= =?UTF-8?q?s=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VirtualNetworkApplianceManager.java | 7 ++ .../VirtualNetworkApplianceManagerImpl.java | 64 ++++++++++++------- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index a5020182bf2..20ee2a17898 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -44,6 +44,7 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA static final String RouterTemplateOvm3CK = "router.template.ovm3"; static final String SetServiceMonitorCK = "network.router.EnableServiceMonitoring"; static final String RouterAlertsCheckIntervalCK = "router.alerts.check.interval"; + static final String RouterReprovisionOnOutOfBandMigrationCK = "router.reboot.when.outofband.migrated"; static final ConfigKey RouterTemplateXen = new ConfigKey(String.class, RouterTemplateXenCK, "Advanced", "SystemVM Template (XenServer)", "Name of the default router template on Xenserver.", true, ConfigKey.Scope.Zone, null); @@ -63,6 +64,12 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA static final ConfigKey RouterAlertsCheckInterval = new ConfigKey(Integer.class, RouterAlertsCheckIntervalCK, "Advanced", "1800", "Interval (in seconds) to check for alerts in Virtual Router.", false, ConfigKey.Scope.Global, null); + static final ConfigKey routerVersionCheckEnabled = new ConfigKey("Advanced", Boolean.class, "router.version.check", "true", + "If true, router minimum required version is checked before sending command", false); + static final ConfigKey UseExternalDnsServers = new ConfigKey(Boolean.class, "use.external.dns", "Advanced", "false", + "Bypass internal dns, use external dns1 and dns2", true, ConfigKey.Scope.Zone, null); + static final ConfigKey RouterReprovisionOnOutOfBandMigration = new ConfigKey(Boolean.class, RouterReprovisionOnOutOfBandMigrationCK, "Advanced", "false", + "Reboot routers when they are migrated out of band in order to reprovision", true, ConfigKey.Scope.Zone, null); public static final int DEFAULT_ROUTER_VM_RAMSIZE = 256; // 256M public static final int DEFAULT_ROUTER_CPU_MHZ = 500; // 500 MHz diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 2a518e46e61..8dab44d1c4e 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -2604,7 +2604,7 @@ Configurable, StateListener { @Override public ConfigKey[] getConfigKeys() { - return new ConfigKey[] { UseExternalDnsServers, routerVersionCheckEnabled, SetServiceMonitor, RouterAlertsCheckInterval }; + return new ConfigKey[] { UseExternalDnsServers, routerVersionCheckEnabled, SetServiceMonitor, RouterAlertsCheckInterval, RouterReprovisionOnOutOfBandMigration }; } @Override @@ -2615,34 +2615,50 @@ Configurable, StateListener { @Override public boolean postStateTransitionEvent(final StateMachine2.Transition transition, final VirtualMachine vo, final boolean status, final Object opaque) { + final State oldState = transition.getCurrentState(); final State newState = transition.getToState(); final VirtualMachine.Event event = transition.getEvent(); - if (event == VirtualMachine.Event.FollowAgentPowerOnReport && newState == State.Running) { - if (vo.getType() == VirtualMachine.Type.DomainRouter) { - // opaque -> - if (opaque != null && opaque instanceof Pair) { - final Pair pair = (Pair)opaque; - final Object first = pair.first(); - final Object second = pair.second(); - // powerHostId cannot be null in case of out-of-band VM movement - if (second != null && second instanceof Long) { - final Long powerHostId = (Long)second; - Long hostId = null; - if (first != null && first instanceof Long) { - hostId = (Long)first; - } - // The following scenarios are due to out-of-band VM movement - // 1. If VM is in stopped state in CS due to 'PowerMissing' report from old host (hostId is null) and then there is a 'PowerOn' report from new host - // 2. If VM is in running state in CS and there is a 'PowerOn' report from new host - if (hostId == null || hostId.longValue() != powerHostId.longValue()) { - s_logger.info("Schedule a router reboot task as router " + vo.getId() + " is powered-on out-of-band, need to reboot to refresh network rules"); - _rebootRouterExecutor.execute(new RebootTask(vo.getId())); - } - } + boolean reprovision_out_of_band = RouterReprovisionOnOutOfBandMigration.value(); + if ( + (vo.getType() == VirtualMachine.Type.DomainRouter) && + ((oldState == State.Stopped) || (reprovision_out_of_band && isOutOfBandMigrated(opaque))) && + (event == VirtualMachine.Event.FollowAgentPowerOnReport) && + (newState == State.Running)) { + s_logger.info("Schedule a router reboot task as router " + vo.getId() + " is powered-on out-of-band. we need to reboot to refresh network rules"); + _rebootRouterExecutor.execute(new RebootTask(vo.getId())); + } else { + if (isOutOfBandMigrated(opaque)) { + final String title = "Router has been migrated out of band: " + vo.getInstanceName(); + final String context = + "An out of band migration of router " + vo.getInstanceName() + "(" + vo.getUuid() + ") was detected. No automated action was performed."; + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, vo.getDataCenterId(), vo.getPodIdToDeployIn(), title, context); + } + } + + return true; + } + + private boolean isOutOfBandMigrated(final Object opaque) { + if (opaque != null && opaque instanceof Pair) { + final Pair pair = (Pair)opaque; + final Object first = pair.first(); + final Object second = pair.second(); + // powerHostId cannot be null in case of out-of-band VM movement + if (second != null && second instanceof Long) { + final Long powerHostId = (Long)second; + Long hostId = null; + if (first != null && first instanceof Long) { + hostId = (Long)first; + } + // The following scenarios are due to out-of-band VM movement + // 1. If VM is in stopped state in CS due to 'PowerMissing' report from old host (hostId is null) and then there is a 'PowerOn' report from new host + // 2. If VM is in running state in CS and there is a 'PowerOn' report from new host + if (hostId == null || hostId.longValue() != powerHostId.longValue()) { + return true; } } } - return true; + return false; } protected class RebootTask extends ManagedContextRunnable {