From b78c03615fff45e0f9fd328850cd5352df0af8df Mon Sep 17 00:00:00 2001 From: Miguel Ferreira Date: Fri, 22 Jul 2016 16:01:02 +0200 Subject: [PATCH] Refactor libvirt compute resource to use properties pojo --- cosmic-agent/pom.xml | 8 +- .../src/main/java/com/cloud/agent/Agent.java | 34 +- .../java/com/cloud/agent/AgentConstants.java | 16 +- .../java/com/cloud/agent/AgentProperties.java | 26 +- .../main/java/com/cloud/agent/AgentShell.java | 139 +- .../jobs/dao/AsyncJobJoinMapDaoImpl.java | 2 +- .../jobs/impl/AsyncJobManagerImpl.java | 2 +- cosmic-core/plugins/hypervisor/kvm/pom.xml | 8 +- .../resource/LibvirtComputingResource.java | 1115 +++++++---------- .../LibvirtComputingResourceProperties.java | 570 +++++++++ .../hypervisor/kvm/resource/OvsVifDriver.java | 4 +- .../LibvirtModifySshKeysCommandWrapper.java | 4 +- .../LibvirtPvlanSetupCommandWrapper.java | 2 +- .../wrapper/LibvirtStartCommandWrapper.java | 6 +- .../kvm/storage/KvmStorageProcessor.java | 4 +- .../LibvirtComputingResourceTest.java | 17 +- .../kvm/resource/LibvirtVifDriverTest.java | 20 +- .../resource/NfsSecondaryStorageResource.java | 37 +- .../java/com/cloud/utils/CloudConstants.java | 19 + .../java/com/cloud/utils/PropertiesPojo.java | 16 + .../java/com/cloud/utils/PropertiesUtil.java | 30 +- .../com/cloud/utils/PropertiesUtilsTest.java | 52 +- 22 files changed, 1328 insertions(+), 803 deletions(-) create mode 100644 cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceProperties.java create mode 100644 cosmic-core/utils/src/main/java/com/cloud/utils/CloudConstants.java create mode 100644 cosmic-core/utils/src/main/java/com/cloud/utils/PropertiesPojo.java diff --git a/cosmic-agent/pom.xml b/cosmic-agent/pom.xml index 3308360950..dc1b134ee8 100644 --- a/cosmic-agent/pom.xml +++ b/cosmic-agent/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 cloud-agent Cosmic Agent @@ -28,6 +29,11 @@ commons-daemon commons-daemon + + cloud.cosmic + cloud-plugin-hypervisor-kvm + 5.1.0.5-SNAPSHOT + diff --git a/cosmic-agent/src/main/java/com/cloud/agent/Agent.java b/cosmic-agent/src/main/java/com/cloud/agent/Agent.java index 1d2875f1f0..e5cbf05af3 100644 --- a/cosmic-agent/src/main/java/com/cloud/agent/Agent.java +++ b/cosmic-agent/src/main/java/com/cloud/agent/Agent.java @@ -34,8 +34,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.channels.ClosedChannelException; @@ -91,18 +89,12 @@ public class Agent implements HandlerFactory, IAgentControl { private boolean _reconnectAllowed = true; private final ExecutorService _executor; - public Agent(final AgentProperties agentProperties, final BackoffAlgorithm backOffAlgorithm) throws ConfigurationException { + public Agent(final AgentProperties agentProperties, final BackoffAlgorithm backOffAlgorithm, final ServerResource resource) throws ConfigurationException { this.agentProperties = agentProperties; this.backOffAlgorithm = backOffAlgorithm; - resource = loadServerResource(agentProperties.getResource()); + this.resource = resource; resource.setAgentControl(this); - if (!resource.configure(getResourceName(), agentProperties.buildPropertiesMap())) { - throw new ConfigurationException("Unable to configure " + resource.getName()); - } else { - logger.info("Agent resource {} configured", resource.getName()); - } - _connection = new NioClient("Agent", agentProperties.getHost(), agentProperties.getPort(), agentProperties.getWorkers(), this); logger.debug("Adding shutdown hook"); @@ -119,28 +111,6 @@ public Agent(final AgentProperties agentProperties, final BackoffAlgorithm backO + agentProperties.getPod() + " : workers = " + agentProperties.getWorkers() + " : host = " + agentProperties.getHost() + " : port = " + agentProperties.getPort()); } - private ServerResource loadServerResource(final String resourceClassName) throws ConfigurationException { - final String[] names = resourceClassName.split("\\|"); - for (final String name : names) { - final Class impl; - try { - impl = Class.forName(name); - final Constructor constructor = impl.getDeclaredConstructor(); - constructor.setAccessible(true); - return (ServerResource) constructor.newInstance(); - } catch (final ClassNotFoundException - | SecurityException - | NoSuchMethodException - | IllegalArgumentException - | InstantiationException - | IllegalAccessException - | InvocationTargetException e) { - throw new ConfigurationException("Failed to launch agent due to: " + e.getMessage()); - } - } - throw new ConfigurationException("Could not find server resource class to load in: " + resourceClassName); - } - public String getResourceName() { return resource.getClass().getSimpleName(); } diff --git a/cosmic-agent/src/main/java/com/cloud/agent/AgentConstants.java b/cosmic-agent/src/main/java/com/cloud/agent/AgentConstants.java index ec476a805e..bd4d87ad3f 100644 --- a/cosmic-agent/src/main/java/com/cloud/agent/AgentConstants.java +++ b/cosmic-agent/src/main/java/com/cloud/agent/AgentConstants.java @@ -1,27 +1,19 @@ package com.cloud.agent; -public class AgentConstants { - public static final String PROPERTY_KEY_HOST = "host"; - public static final String PROPERTY_KEY_PORT = "port"; - public static final String PROPERTY_KEY_WORKERS = "workers"; - public static final String PROPERTY_KEY_ZONE = "zone"; - public static final String PROPERTY_KEY_POD = "pod"; +import com.cloud.utils.CloudConstants; + +public class AgentConstants extends CloudConstants { public static final String PROPERTY_KEY_PING_RETRIES = "ping.retries"; - public static final String PROPERTY_KEY_DEVELOPER = "developer"; - public static final String PROPERTY_KEY_GUID = "guid"; - public static final String PROPERTY_KEY_RESOURCE = "resource"; public static final String PROPERTY_KEY_IPV6_DISABLED = "ipv6disabled"; public static final String PROPERTY_KEY_IPV6_PREFERRED = "ipv6prefer"; - public static final String PROPERTY_KEY_INSTANCE = "instance"; + public static final String PROPERTY_KEY_WORKERS = "workers"; public static final String PROPERTY_KEY_PID_DIR = "piddir"; public static final String PROPERTY_KEY_CONSOLE_PROXY_HTTP_PORT = "consoleproxy.httpListenPort"; - public static final String PROPERTY_KEY_CONSOLE_VERSION = "version"; public static final int DEFAULT_PORT = 8250; public static final int DEFAULT_CONSOLE_PROXY_HTTP_PORT = 443; public static final int DEFAULT_NUMBER_OF_WORKERS = 5; public static final int DEFAULT_NUMBER_OF_PING_RETRIES = 5; - public static final String DEFAULT_ZONE = "default"; public static final boolean DEFAULT_IPV6_DISABLED = false; public static final boolean DEFAULT_IPV6_PREFERRED = false; public static final String DEFAULT_PID_DIR = "/var/run"; diff --git a/cosmic-agent/src/main/java/com/cloud/agent/AgentProperties.java b/cosmic-agent/src/main/java/com/cloud/agent/AgentProperties.java index 1db826970c..f9c4201874 100644 --- a/cosmic-agent/src/main/java/com/cloud/agent/AgentProperties.java +++ b/cosmic-agent/src/main/java/com/cloud/agent/AgentProperties.java @@ -25,26 +25,28 @@ import static com.cloud.agent.AgentConstants.PROPERTY_KEY_ZONE; import static com.cloud.utils.PropertiesUtil.parse; +import com.cloud.utils.PropertiesPojo; + import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.UUID; -public class AgentProperties { +public class AgentProperties implements PropertiesPojo { private String host = ""; - private int workers = DEFAULT_NUMBER_OF_WORKERS; private int port = DEFAULT_PORT; + private int consoleProxyHttpPort = DEFAULT_CONSOLE_PROXY_HTTP_PORT; private String zone = DEFAULT_ZONE; private String pod = ""; private String guid = ""; + private String resource = ""; + private String instance = ""; + private int workers = DEFAULT_NUMBER_OF_WORKERS; private int pingRetries = DEFAULT_NUMBER_OF_PING_RETRIES; private boolean developer = false; - private String resource = ""; private boolean ipv6Disabled = DEFAULT_IPV6_DISABLED; private boolean ipa6Preferred = DEFAULT_IPV6_PREFERRED; - private String instance = ""; private String pidDir = DEFAULT_PID_DIR; - private int consoleProxyHttpPort = DEFAULT_CONSOLE_PROXY_HTTP_PORT; private String version = ""; public void load(final Properties properties) { @@ -67,12 +69,6 @@ public void load(final Properties properties) { validateValues(); } - public void load(final Map map) { - final Properties properties = new Properties(); - properties.putAll(map); - load(properties); - } - private void validateValues() { workers = workers <= 0 ? DEFAULT_NUMBER_OF_WORKERS : workers; pingRetries = pingRetries <= 0 ? DEFAULT_NUMBER_OF_PING_RETRIES : pingRetries; @@ -148,17 +144,17 @@ public Map buildPropertiesMap() { final HashMap propertiesMap = new HashMap<>(); propertiesMap.put(PROPERTY_KEY_HOST, host); propertiesMap.put(PROPERTY_KEY_PORT, port); - propertiesMap.put(PROPERTY_KEY_WORKERS, workers); propertiesMap.put(PROPERTY_KEY_ZONE, zone); propertiesMap.put(PROPERTY_KEY_POD, pod); propertiesMap.put(PROPERTY_KEY_GUID, guid); + propertiesMap.put(PROPERTY_KEY_RESOURCE, resource); + propertiesMap.put(PROPERTY_KEY_INSTANCE, instance); + propertiesMap.put(PROPERTY_KEY_PID_DIR, pidDir); + propertiesMap.put(PROPERTY_KEY_WORKERS, workers); propertiesMap.put(PROPERTY_KEY_PING_RETRIES, pingRetries); propertiesMap.put(PROPERTY_KEY_DEVELOPER, developer); - propertiesMap.put(PROPERTY_KEY_RESOURCE, resource); propertiesMap.put(PROPERTY_KEY_IPV6_DISABLED, ipv6Disabled); propertiesMap.put(PROPERTY_KEY_IPV6_PREFERRED, ipa6Preferred); - propertiesMap.put(PROPERTY_KEY_INSTANCE, instance); - propertiesMap.put(PROPERTY_KEY_PID_DIR, pidDir); propertiesMap.put(PROPERTY_KEY_CONSOLE_PROXY_HTTP_PORT, consoleProxyHttpPort); return propertiesMap; } diff --git a/cosmic-agent/src/main/java/com/cloud/agent/AgentShell.java b/cosmic-agent/src/main/java/com/cloud/agent/AgentShell.java index 06ddd4a889..e77a698efa 100644 --- a/cosmic-agent/src/main/java/com/cloud/agent/AgentShell.java +++ b/cosmic-agent/src/main/java/com/cloud/agent/AgentShell.java @@ -1,6 +1,9 @@ package com.cloud.agent; +import static java.util.stream.Collectors.toMap; + import com.cloud.agent.Agent.ExitStatus; +import com.cloud.resource.ServerResource; import com.cloud.utils.ProcessUtil; import com.cloud.utils.PropertiesUtil; import com.cloud.utils.backoff.BackoffAlgorithm; @@ -10,8 +13,11 @@ import javax.naming.ConfigurationException; import java.io.File; import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.HashMap; +import java.util.Map; import java.util.Properties; import org.apache.commons.daemon.Daemon; @@ -25,9 +31,40 @@ public class AgentShell implements IAgentShell, Daemon { private static final String FILE_NAME_AGENT_PROPERTIES = "agent.properties"; private final AgentProperties agentProperties = new AgentProperties(); + private final Map allProperties = new HashMap<>(); private Agent agent; private BackoffAlgorithm backOff; + @Override + public String getHost() { + return agentProperties.getHost(); + } + + @Override + public int getPort() { + return agentProperties.getPort(); + } + + @Override + public int getWorkers() { + return agentProperties.getWorkers(); + } + + @Override + public String getGuid() { + return agentProperties.getGuid(); + } + + @Override + public String getZone() { + return agentProperties.getZone(); + } + + @Override + public String getPod() { + return agentProperties.getPod(); + } + public static void main(final String[] args) { try { logger.info("Starting agent shell"); @@ -60,27 +97,16 @@ public void loadProperties() throws ConfigurationException { } logger.info("Found {} at {}", FILE_NAME_AGENT_PROPERTIES, file.getAbsolutePath()); - agentProperties.load(loadPropertiesFromFile(file)); - } - - private Properties loadPropertiesFromFile(final File file) { - final Properties properties = new Properties(); - try { - PropertiesUtil.loadFromFile(properties, file); - logPropertiesFound(properties); - } catch (final IOException e) { - throw new CloudRuntimeException("Can't load agent properties from " + file.getAbsolutePath(), e); - } - return properties; - } - - private void logPropertiesFound(final Properties properties) { - properties.entrySet().forEach(entry -> logger.debug("Found property: {} = {}", entry.getKey(), entry.getValue())); + final Properties properties = loadPropertiesFromFile(file); + allProperties.putAll(convertPropertiesToStringObjectMap(properties)); + agentProperties.load(properties); } protected boolean parseCommand(final String[] args) throws ConfigurationException { final Properties commandLineProperties = PropertiesUtil.parse(Arrays.stream(args)); + logPropertiesFound(commandLineProperties); agentProperties.load(commandLineProperties); + allProperties.putAll(convertPropertiesToStringObjectMap(commandLineProperties)); final String guid = agentProperties.getGuid(); if (guid == null && !agentProperties.isDeveloper()) { @@ -90,47 +116,72 @@ protected boolean parseCommand(final String[] args) throws ConfigurationExceptio return true; } - @Override - public String getHost() { - return agentProperties.getHost(); - } - - @Override - public int getPort() { - return agentProperties.getPort(); + private Map convertPropertiesToStringObjectMap(final Properties properties) { + return properties.entrySet().stream().collect(toMap(entry -> entry.getKey().toString(), Map.Entry::getValue)); } - @Override - public int getWorkers() { - return agentProperties.getWorkers(); - } - - @Override - public String getGuid() { - return agentProperties.getGuid(); - } - - @Override - public String getZone() { - return agentProperties.getZone(); + private Properties loadPropertiesFromFile(final File file) { + final Properties properties = new Properties(); + try { + PropertiesUtil.loadFromFile(properties, file); + logPropertiesFound(properties); + } catch (final IOException e) { + throw new CloudRuntimeException("Can't load agent properties from " + file.getAbsolutePath(), e); + } + return properties; } - @Override - public String getPod() { - return agentProperties.getPod(); + private void logPropertiesFound(final Properties properties) { + properties.entrySet().forEach(entry -> logger.debug("Found property: {} = {}", entry.getKey(), entry.getValue())); } private void launchAgent() throws ConfigurationException { final String resourceClassNames = agentProperties.getResource(); - logger.debug("Launching agent with resource is {}", resourceClassNames); + logger.debug("Launching agent with resource {}", resourceClassNames); if (resourceClassNames != null) { - agent = new Agent(agentProperties, backOff); + final ServerResource serverResource = loadServerResource(agentProperties.getResource()); + configureServerResource(serverResource); + agent = new Agent(agentProperties, backOff, serverResource); agent.start(); } else { throw new ConfigurationException("Cannot launch agent without a agent resource class"); } } + private void configureServerResource(final ServerResource serverResource) throws ConfigurationException { + final String serverResourceName = serverResource.getClass().getSimpleName(); + logger.debug("Configuring agent resource {}", serverResourceName); + + if (!serverResource.configure(serverResourceName, allProperties)) { + throw new ConfigurationException("Unable to configure " + serverResourceName); + } else { + logger.info("Agent resource {} configured", serverResourceName); + } + } + + private ServerResource loadServerResource(final String resourceClassName) throws ConfigurationException { + logger.debug("Loading agent resource from class name {}", resourceClassName); + final String[] names = resourceClassName.split("\\|"); + for (final String name : names) { + final Class impl; + try { + impl = Class.forName(name); + final Constructor constructor = impl.getDeclaredConstructor(); + constructor.setAccessible(true); + return (ServerResource) constructor.newInstance(); + } catch (final ClassNotFoundException + | SecurityException + | NoSuchMethodException + | IllegalArgumentException + | InstantiationException + | IllegalAccessException + | InvocationTargetException e) { + throw new ConfigurationException("Failed to launch agent due to " + e.getClass().getSimpleName() + ": " + e.getMessage()); + } + } + throw new ConfigurationException("Could not find server resource class to load in: " + resourceClassName); + } + @Override public void init(final DaemonContext dc) throws DaemonInitException { logger.debug("Initializing AgentShell from JSVC"); @@ -148,7 +199,9 @@ public void start() { configureIpStack(); checkPidFile(); launchAgent(); - agent.wait(); + synchronized (agent) { + agent.wait(); + } } catch (final ConfigurationException e) { logger.error("Unable to start agent due to bad configuration", e); System.exit(ExitStatus.Configuration.value()); diff --git a/cosmic-core/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java b/cosmic-core/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java index cdef9d4b1d..41f197a779 100644 --- a/cosmic-core/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java +++ b/cosmic-core/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java @@ -152,7 +152,7 @@ public void completeJoin(final long joinJobId, final JobInfo.Status joinStatus, // String sql = "UPDATE async_job SET job_pending_signals=? WHERE id IN " + // "(SELECT job_id FROM async_job_join_map WHERE next_wakeup < ? AND expiration > ?)"; // pstmt = txn.prepareStatement(sql); - // pstmt.setInt(1, AsyncJob.Constants.SIGNAL_MASK_WAKEUP); + // pstmt.setInt(1, AsyncJob.CloudConstants.SIGNAL_MASK_WAKEUP); // pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate)); // pstmt.setString(3, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate)); // pstmt.executeUpdate(); diff --git a/cosmic-core/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java b/cosmic-core/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java index 6396173de2..d66a19195c 100644 --- a/cosmic-core/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java +++ b/cosmic-core/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java @@ -485,7 +485,7 @@ public List doInTransaction(final TransactionStatus status) { for (Long id : wakeupList) { // TODO, we assume that all jobs in this category is API job only AsyncJobVO jobToWakeup = _jobDao.findById(id); - if (jobToWakeup != null && (jobToWakeup.getPendingSignals() & AsyncJob.Constants.SIGNAL_MASK_WAKEUP) != 0) + if (jobToWakeup != null && (jobToWakeup.getPendingSignals() & AsyncJob.CloudConstants.SIGNAL_MASK_WAKEUP) != 0) scheduleExecution(jobToWakeup, false); } */ diff --git a/cosmic-core/plugins/hypervisor/kvm/pom.xml b/cosmic-core/plugins/hypervisor/kvm/pom.xml index d54ab535bf..5982b0454b 100644 --- a/cosmic-core/plugins/hypervisor/kvm/pom.xml +++ b/cosmic-core/plugins/hypervisor/kvm/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 cloud-plugin-hypervisor-kvm Cosmic Plugin - Hypervisor KVM @@ -41,11 +42,6 @@ commons-io commons-io - - cloud.cosmic - cloud-agent - 5.1.0.5-SNAPSHOT - org.libvirt libvirt diff --git a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index d988bd73ec..c910fe73a3 100755 --- a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -1,5 +1,28 @@ package com.cloud.hypervisor.kvm.resource; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResource.BridgeType.OPENVSWITCH; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.FORMAT_NETWORK_SPEED; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PATH_PATCH_DIR; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PATH_SCRIPTS_NETWORK_DOMR; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_CREATE_TEMPLATE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_CREATE_VM; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_KVM_HEART_BEAT; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_LOCAL_GATEWAY; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_MANAGE_SNAPSHOT; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_MODIFY_VLAN; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_OVS_PVLAN_DHCP_HOST; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_OVS_PVLAN_VM; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_OVS_TUNNEL; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_PATCH_VIA_SOCKET; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_PING_TEST; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_RESIZE_VOLUME; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_ROUTER_PROXY; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_SECURITY_GROUP; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_UNAME; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.SCRIPT_VERSIONS; + +import static java.util.UUID.randomUUID; + import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.HostVmStateReportEntry; @@ -119,7 +142,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.google.common.base.Strings; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.libvirt.Connect; @@ -159,7 +181,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected static final String DEFAULT_OVS_VIF_DRIVER_CLASS = "com.cloud.hypervisor.kvm.resource.OvsVifDriver"; protected static final String DEFAULT_BRIDGE_VIF_DRIVER_CLASS = "com.cloud.hypervisor.kvm.resource.BridgeVifDriver"; protected static final HashMap s_powerStatesTable; - private static final Logger LOGGER = LoggerFactory.getLogger(LibvirtComputingResource.class); + private static final Logger logger = LoggerFactory.getLogger(LibvirtComputingResource.class); static { s_powerStatesTable = new HashMap<>(); @@ -171,56 +193,27 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTDOWN, PowerState.PowerOff); } + private final LibvirtComputingResourceProperties libvirtComputingResourceProperties = new LibvirtComputingResourceProperties(); private final Map pifs = new HashMap<>(); private final Map vmStats = new ConcurrentHashMap<>(); private final LibvirtUtilitiesHelper libvirtUtilitiesHelper = new LibvirtUtilitiesHelper(); - protected HypervisorType hypervisorType; - protected String hypervisorUri; - protected long hypervisorLibvirtVersion; - protected long hypervisorQemuVersion; - protected String hypervisorPath; - protected String networkDirectSourceMode; - protected String networkDirectDevice; - protected String sysvmIsoPath; - protected String privNwName; - protected String privBridgeName; - protected String linkLocalBridgeName; - protected String publicBridgeName; - protected String guestBridgeName; - protected String privateIp; - protected String pool; - protected String localGateway; - protected String localStoragePath; - protected String localStorageUuid; - protected boolean noMemBalloon = false; - protected String guestCpuMode; - protected String guestCpuModel; - protected boolean noKvmClock; - protected String videoHw; - protected int videoRam; - protected Pair hostOsVersion; - protected int migrateSpeed; - protected int migrateDowntime; - protected int migratePauseAfter; - protected boolean diskActivityCheckEnabled; - protected long diskActivityCheckFileSizeMin = 10485760; // 10MB - protected int diskActivityCheckTimeoutSeconds = 120; // 120s - protected long diskActivityInactiveThresholdMilliseconds = 30000; // 30s - protected boolean rngEnable = false; - protected RngBackendModel rngBackendModel = RngBackendModel.RANDOM; - protected String rngPath = "/dev/random"; - protected WatchDogAction watchDogAction = WatchDogAction.NONE; - protected WatchDogModel watchDogModel = WatchDogModel.I6300ESB; - protected List cpuFeatures; - protected BridgeType bridgeType; - protected List vmsKilled = new ArrayList<>(); - protected boolean disconnected = true; - protected int cmdsTimeout; - protected int stopTimeout; - protected CpuStat cpuStat = new CpuStat(); - protected MemStat memStat = new MemStat(); - protected StorageSubsystemCommandHandler storageHandler; - String[] ifNamePatterns = { + private long hypervisorLibvirtVersion; + private long hypervisorQemuVersion; + private String hypervisorPath; + private String privateIp; + private String localGateway; + private boolean diskActivityCheckEnabled; + private final long diskActivityCheckFileSizeMin = 10485760; // 10MB + private int diskActivityCheckTimeoutSeconds = 120; // 120s + private long diskActivityInactiveThresholdMilliseconds = 30000; // 30s + private final RngBackendModel rngBackendModel = RngBackendModel.RANDOM; + private final String rngPath = "/dev/random"; + private final WatchDogAction watchDogAction = WatchDogAction.NONE; + private final WatchDogModel watchDogModel = WatchDogModel.I6300ESB; + private final CpuStat cpuStat = new CpuStat(); + private final MemStat memStat = new MemStat(); + private StorageSubsystemCommandHandler storageHandler; + private final String[] ifNamePatterns = { "^eth", "^bond", "^vlan", @@ -233,10 +226,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv "^enx", "^p\\d+p\\d+" }; - private String modifyVlanPath; private String versionstringpath; private String patchViaSocketPath; - private String createVmPath; private String manageSnapshotPath; private String resizeVolumePath; private String createTmplPath; @@ -246,19 +237,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private String ovsPvlanVmPath; private String routerProxyPath; private String ovsTunnelPath; - private String host; - private String dcId; - private String pod; - private String clusterId; private long hvVersion; - private long kernelVersion; - private int timeout; private VirtualRoutingResource virtRouterResource; private String pingTestPath; private String updateHostPasswdPath; - private long dom0MinMem; private KvmHaMonitor monitor; - private String mountPoint = "/mnt"; private StorageLayer storage; private KvmStoragePoolManager storagePoolMgr; private VifDriver defaultVifDriver; @@ -267,12 +250,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv @Override public ExecutionResult executeInVR(final String routerIp, final String script, final String args) { - return executeInVR(routerIp, script, args, timeout / 1000); + return executeInVR(routerIp, script, args, getScriptsTimeout() / 1000); } @Override public ExecutionResult executeInVR(final String routerIp, final String script, final String args, final int timeout) { - final Script command = new Script(routerProxyPath, timeout * 1000, LOGGER); + final Script command = new Script(routerProxyPath, timeout * 1000, logger); final AllLinesParser parser = new AllLinesParser(); command.add(script); command.add(routerIp); @@ -284,7 +267,7 @@ public ExecutionResult executeInVR(final String routerIp, final String script, f details = parser.getLines(); } - LOGGER.debug("Executing script in VR " + script); + logger.debug("Executing script in VR " + script); return new ExecutionResult(command.getExitValue() == 0, details); } @@ -295,12 +278,12 @@ public ExecutionResult createFileInVR(final String routerIp, final String path, final File permKey = new File("/root/.ssh/id_rsa.cloud"); String error = null; - LOGGER.debug("Creating file in VR " + filename); + logger.debug("Creating file in VR " + filename); try { SshHelper.scpTo(routerIp, 3922, "root", permKey, null, path, content.getBytes(), filename, null); } catch (final Exception e) { - LOGGER.warn("Fail to create file " + path + filename + " in VR " + routerIp, e); + logger.warn("Fail to create file " + path + filename + " in VR " + routerIp, e); error = e.getMessage(); } return new ExecutionResult(error == null, error); @@ -340,15 +323,15 @@ protected ExecutionResult cleanupNetworkElementCommand(final IpAssocCommand cmd) try { conn = LibvirtConnection.getConnectionByVmName(routerName); - final List nics = getInterfaces(conn, routerName, guestBridgeName); + final List nics = getInterfaces(conn, routerName, getGuestBridgeName()); final Map broadcastUriAllocatedToVm = new HashMap<>(); Integer nicPos = 0; for (final InterfaceDef nic : nics) { - if (nic.getBrName().equalsIgnoreCase(linkLocalBridgeName)) { + if (nic.getBrName().equalsIgnoreCase(getLinkLocalBridgeName())) { broadcastUriAllocatedToVm.put("LinkLocal", nicPos); } else { - if (nic.getBrName().equalsIgnoreCase(publicBridgeName) || nic.getBrName().equalsIgnoreCase(privBridgeName)) { + if (nic.getBrName().equalsIgnoreCase(getPublicBridgeName()) || nic.getBrName().equalsIgnoreCase(getPrivBridgeName())) { broadcastUriAllocatedToVm.put(BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED).toString(), nicPos); } else { final String broadcastUri = getBroadcastUriFromBridge(nic.getBrName()); @@ -376,10 +359,10 @@ protected ExecutionResult cleanupNetworkElementCommand(final IpAssocCommand cmd) } } } catch (final LibvirtException e) { - LOGGER.error("ipassoccmd failed", e); + logger.error("ipassoccmd failed", e); return new ExecutionResult(false, e.getMessage()); } catch (final InternalErrorException e) { - LOGGER.error("ipassoccmd failed", e); + logger.error("ipassoccmd failed", e); return new ExecutionResult(false, e.getMessage()); } @@ -444,7 +427,7 @@ protected ExecutionResult prepareNetworkElementCommand(final IpAssocVpcCommand c return new ExecutionResult(true, null); } catch (final LibvirtException e) { - LOGGER.error("Ip Assoc failure on applying one ip due to exception: ", e); + logger.error("Ip Assoc failure on applying one ip due to exception: ", e); return new ExecutionResult(false, e.getMessage()); } } @@ -477,10 +460,10 @@ public ExecutionResult prepareNetworkElementCommand(final IpAssocCommand cmd) { } return new ExecutionResult(true, null); } catch (final LibvirtException e) { - LOGGER.error("ipassoccmd failed", e); + logger.error("ipassoccmd failed", e); return new ExecutionResult(false, e.getMessage()); } catch (final InternalErrorException e) { - LOGGER.error("ipassoccmd failed", e); + logger.error("ipassoccmd failed", e); return new ExecutionResult(false, e.getMessage()); } } @@ -509,7 +492,7 @@ private ExecutionResult prepareNetworkElementCommand(final SetupGuestNetworkComm return new ExecutionResult(true, null); } catch (final LibvirtException e) { final String msg = "Creating guest network failed due to " + e.toString(); - LOGGER.warn(msg, e); + logger.warn(msg, e); return new ExecutionResult(false, msg); } } @@ -529,9 +512,9 @@ protected ExecutionResult prepareNetworkElementCommand(final SetSourceNatCommand for (final InterfaceDef pluggedNic : pluggedNics) { final String pluggedVlanBr = pluggedNic.getBrName(); final String pluggedVlanId = getBroadcastUriFromBridge(pluggedVlanBr); - if (pubVlan.equalsIgnoreCase(Vlan.UNTAGGED) && pluggedVlanBr.equalsIgnoreCase(publicBridgeName)) { + if (pubVlan.equalsIgnoreCase(Vlan.UNTAGGED) && pluggedVlanBr.equalsIgnoreCase(getPublicBridgeName())) { break; - } else if (pluggedVlanBr.equalsIgnoreCase(linkLocalBridgeName)) { + } else if (pluggedVlanBr.equalsIgnoreCase(getLinkLocalBridgeName())) { /* skip over, no physical bridge device exists */ } else if (pluggedVlanId == null) { /* this should only be true in the case of link local bridge */ @@ -549,7 +532,7 @@ protected ExecutionResult prepareNetworkElementCommand(final SetSourceNatCommand return new ExecutionResult(true, "success"); } catch (final LibvirtException e) { final String msg = "Ip SNAT failure due to " + e.toString(); - LOGGER.error(msg, e); + logger.error(msg, e); return new ExecutionResult(false, msg); } } @@ -562,7 +545,7 @@ public List getInterfaces(final Connect conn, final String vmName) parser.parseDomainXml(dm.getXMLDesc(0)); return parser.getInterfaces(); } catch (final LibvirtException e) { - LOGGER.debug("Failed to get dom xml: " + e.toString()); + logger.debug("Failed to get dom xml: " + e.toString()); return new ArrayList<>(); } finally { try { @@ -570,7 +553,7 @@ public List getInterfaces(final Connect conn, final String vmName) dm.free(); } } catch (final LibvirtException e) { - LOGGER.trace("Ignoring libvirt error.", e); + logger.trace("Ignoring libvirt error.", e); } } } @@ -580,8 +563,8 @@ private Integer buildBridgeToNicNumHashMap(final Map bridgeToNi for (final InterfaceDef pluggedNic : pluggedNics) { final String pluggedVlan = pluggedNic.getBrName(); - if (pluggedVlan.equalsIgnoreCase(linkLocalBridgeName) || pluggedVlan.equalsIgnoreCase(publicBridgeName) - || pluggedVlan.equalsIgnoreCase(privBridgeName) || pluggedVlan.equalsIgnoreCase(guestBridgeName)) { + if (pluggedVlan.equalsIgnoreCase(getLinkLocalBridgeName()) || pluggedVlan.equalsIgnoreCase(getPublicBridgeName()) + || pluggedVlan.equalsIgnoreCase(getPrivBridgeName()) || pluggedVlan.equalsIgnoreCase(getGuestBridgeName())) { bridgeToNicNum.put(pluggedVlan, devNum); } devNum++; @@ -589,15 +572,23 @@ private Integer buildBridgeToNicNumHashMap(final Map bridgeToNi return devNum; } + private String getPrivBridgeName() { + return libvirtComputingResourceProperties.getPrivateNetworkDevice(); + } + + private String getLinkLocalBridgeName() { + return libvirtComputingResourceProperties.getPrivateBridgeName(); + } + private Integer setIpNicDevId(final Map bridgeToNicNum, final IpAddressTO ip) { - if (ip.getTrafficType().equals(TrafficType.Public) && bridgeToNicNum.containsKey(publicBridgeName)) { - ip.setNicDevId(bridgeToNicNum.get(publicBridgeName)); - } else if (ip.getTrafficType().equals(TrafficType.Management) && bridgeToNicNum.containsKey(privBridgeName)) { - ip.setNicDevId(bridgeToNicNum.get(privBridgeName)); - } else if (ip.getTrafficType().equals(TrafficType.Guest) && bridgeToNicNum.containsKey(guestBridgeName)) { - ip.setNicDevId(bridgeToNicNum.get(guestBridgeName)); - } else if (ip.getTrafficType().equals(TrafficType.Control) && bridgeToNicNum.containsKey(linkLocalBridgeName)) { - ip.setNicDevId(bridgeToNicNum.get(linkLocalBridgeName)); + if (ip.getTrafficType().equals(TrafficType.Public) && bridgeToNicNum.containsKey(getPublicBridgeName())) { + ip.setNicDevId(bridgeToNicNum.get(getPublicBridgeName())); + } else if (ip.getTrafficType().equals(TrafficType.Management) && bridgeToNicNum.containsKey(getPrivBridgeName())) { + ip.setNicDevId(bridgeToNicNum.get(getPrivBridgeName())); + } else if (ip.getTrafficType().equals(TrafficType.Guest) && bridgeToNicNum.containsKey(getGuestBridgeName())) { + ip.setNicDevId(bridgeToNicNum.get(getGuestBridgeName())); + } else if (ip.getTrafficType().equals(TrafficType.Control) && bridgeToNicNum.containsKey(getLinkLocalBridgeName())) { + ip.setNicDevId(bridgeToNicNum.get(getLinkLocalBridgeName())); } return ip.getNicDevId(); } @@ -606,16 +597,16 @@ private String getBridgeNameFromTrafficType(final TrafficType trafficType) { final String bridgeName; switch (trafficType) { case Public: - bridgeName = publicBridgeName; + bridgeName = getPublicBridgeName(); break; case Management: - bridgeName = privBridgeName; + bridgeName = getPrivBridgeName(); break; case Guest: - bridgeName = guestBridgeName; + bridgeName = getGuestBridgeName(); break; case Control: - bridgeName = linkLocalBridgeName; + bridgeName = getLinkLocalBridgeName(); break; default: bridgeName = ""; @@ -641,7 +632,7 @@ private void vifHotPlug(final Connect conn, final String vmName, final String br } public String networkUsage(final String privateIpAddress, final String option, final String vif) { - final Script getUsage = new Script(routerProxyPath, LOGGER); + final Script getUsage = new Script(routerProxyPath, logger); getUsage.add("netusage.sh"); getUsage.add(privateIpAddress); if (option.equals("get")) { @@ -659,7 +650,7 @@ public String networkUsage(final String privateIpAddress, final String option, f final OutputInterpreter.OneLineParser usageParser = new OutputInterpreter.OneLineParser(); final String result = getUsage.execute(usageParser); if (result != null) { - LOGGER.debug("Failed to execute networkUsage:" + result); + logger.debug("Failed to execute networkUsage:" + result); return null; } return usageParser.getLine(); @@ -669,7 +660,7 @@ private String getBroadcastUriFromBridge(final String brName) { final String pif = matchPifFileInDirectory(brName); final Pattern pattern = Pattern.compile("(\\D+)(\\d+)(\\D*)(\\d*)"); final Matcher matcher = pattern.matcher(pif); - LOGGER.debug("getting broadcast uri for pif " + pif + " and bridge " + brName); + logger.debug("getting broadcast uri for pif " + pif + " and bridge " + brName); if (matcher.find()) { if (brName.startsWith("brvx")) { return BroadcastDomainType.Vxlan.toUri(matcher.group(2)).toString(); @@ -678,13 +669,13 @@ private String getBroadcastUriFromBridge(final String brName) { return BroadcastDomainType.Vlan.toUri(matcher.group(4)).toString(); } else { // untagged or not matching (eth|bond|team)#.# - LOGGER.debug("failed to get vNet id from bridge " + brName + logger.debug("failed to get vNet id from bridge " + brName + "attached to physical interface" + pif + ", perhaps untagged interface"); return ""; } } } else { - LOGGER.debug("failed to get vNet id from bridge " + brName + "attached to physical interface" + pif); + logger.debug("failed to get vNet id from bridge " + brName + "attached to physical interface" + pif); return ""; } } @@ -712,7 +703,7 @@ private String matchPifFileInDirectory(final String bridgeName) { // if bridgeName already refers to a pif, return it as-is return bridgeName; } - LOGGER.debug("failing to get physical interface from bridge " + bridgeName + ", does " + brif.getAbsolutePath() + logger.debug("failing to get physical interface from bridge " + bridgeName + ", does " + brif.getAbsolutePath() + "exist?"); return ""; } @@ -721,13 +712,13 @@ private String matchPifFileInDirectory(final String bridgeName) { for (final File interface1 : interfaces) { final String fname = interface1.getName(); - LOGGER.debug("matchPifFileInDirectory: file name '" + fname + "'"); + logger.debug("matchPifFileInDirectory: file name '" + fname + "'"); if (isInterface(fname)) { return fname; } } - LOGGER.debug("failing to get physical interface from bridge " + bridgeName + logger.debug("failing to get physical interface from bridge " + bridgeName + ", did not find an eth*, bond*, team*, vlan*, em*, p*p*, ens*, eno*, enp*, or enx* in " + brif.getAbsolutePath()); return ""; @@ -761,7 +752,7 @@ public VirtualRoutingResource getVirtRouterResource() { } public String getPublicBridgeName() { - return publicBridgeName; + return libvirtComputingResourceProperties.getPublicNetworkDevice(); } public KvmStoragePoolManager getStoragePoolMgr() { @@ -773,15 +764,15 @@ public String getPrivateIp() { } public int getMigrateDowntime() { - return migrateDowntime; + return libvirtComputingResourceProperties.getVmMigrateDowntime(); } public int getMigratePauseAfter() { - return migratePauseAfter; + return libvirtComputingResourceProperties.getVmMigratePauseafter(); } public int getMigrateSpeed() { - return migrateSpeed; + return libvirtComputingResourceProperties.getVmMigrateSpeed(); } public String getPingTestPath() { @@ -792,12 +783,8 @@ public String getUpdateHostPasswdPath() { return updateHostPasswdPath; } - public int getTimeout() { - return timeout; - } - - public String getOvsTunnelPath() { - return ovsTunnelPath; + public int getScriptsTimeout() { + return libvirtComputingResourceProperties.getScriptsTimeout(); } public KvmHaMonitor getMonitor() { @@ -813,7 +800,7 @@ public String createTmplPath() { } public int getCmdsTimeout() { - return cmdsTimeout; + return libvirtComputingResourceProperties.getCmdsTimeout(); } public String manageSnapshotPath() { @@ -821,7 +808,7 @@ public String manageSnapshotPath() { } public String getGuestBridgeName() { - return guestBridgeName; + return libvirtComputingResourceProperties.getGuestNetworkDevice(); } public String getOvsPvlanDhcpHostPath() { @@ -847,302 +834,183 @@ protected String getDefaultScriptsDir() { @Override public boolean configure(final String name, final Map params) throws ConfigurationException { - boolean success = super.configure(name, params); - if (!success) { - return false; - } - - storage = new JavaStorageLayer(); - storage.configure("StorageLayer", params); - - String domrScriptsDir = (String) params.get("domr.scripts.dir"); - if (domrScriptsDir == null) { - domrScriptsDir = getDefaultDomrScriptsDir(); - } - - String hypervisorScriptsDir = (String) params.get("hypervisor.scripts.dir"); - if (hypervisorScriptsDir == null) { - hypervisorScriptsDir = getDefaultHypervisorScriptsDir(); - } - - String kvmScriptsDir = (String) params.get("kvm.scripts.dir"); - if (kvmScriptsDir == null) { - kvmScriptsDir = getDefaultKvmScriptsDir(); - } + libvirtComputingResourceProperties.load(params); - String networkScriptsDir = (String) params.get("network.scripts.dir"); - if (networkScriptsDir == null) { - networkScriptsDir = getDefaultNetworkScriptsDir(); - } + // TODO: Do not use params anymore, it should eventually be removed from the interface definition + // For now we pay the penalty of generating the map every time we need to use it, in the future all methods should accept the pojo - String storageScriptsDir = (String) params.get("storage.scripts.dir"); - if (storageScriptsDir == null) { - storageScriptsDir = getDefaultStorageScriptsDir(); - } - - final String networkBridgeType = (String) params.get("network.bridge.type"); - if (networkBridgeType == null) { - bridgeType = BridgeType.NATIVE; - } else { - bridgeType = BridgeType.valueOf(networkBridgeType.toUpperCase()); - } - - params.put("domr.scripts.dir", domrScriptsDir); - - virtRouterResource = new VirtualRoutingResource(this); - success = virtRouterResource.configure(name, params); + Map propertiesMap = libvirtComputingResourceProperties.buildPropertiesMap(); + final boolean success = super.configure(name, propertiesMap); if (!success) { return false; } - host = (String) params.get("host"); - if (host == null) { - host = "localhost"; - } - - dcId = (String) params.get("zone"); - if (dcId == null) { - dcId = "default"; - } - - pod = (String) params.get("pod"); - if (pod == null) { - pod = "default"; - } - - clusterId = (String) params.get("cluster"); - - updateHostPasswdPath = Script.findScript(hypervisorScriptsDir, VRScripts.UPDATE_HOST_PASSWD); - if (updateHostPasswdPath == null) { - throw new ConfigurationException("Unable to find update_host_passwd.sh"); - } + initStorage(propertiesMap); - modifyVlanPath = Script.findScript(networkScriptsDir, "modifyvlan.sh"); - if (modifyVlanPath == null) { - throw new ConfigurationException("Unable to find modifyvlan.sh"); - } - - versionstringpath = Script.findScript(kvmScriptsDir, "versions.sh"); - if (versionstringpath == null) { - throw new ConfigurationException("Unable to find versions.sh"); - } - - patchViaSocketPath = Script.findScript(kvmScriptsDir + "/patch/", "patchviasocket.pl"); - if (patchViaSocketPath == null) { - throw new ConfigurationException("Unable to find patchviasocket.pl"); - } - - heartBeatPath = Script.findScript(kvmScriptsDir, "kvmheartbeat.sh"); - if (heartBeatPath == null) { - throw new ConfigurationException("Unable to find kvmheartbeat.sh"); + if (initVirtualRoutingResource(name, propertiesMap)) { + return false; } - createVmPath = Script.findScript(storageScriptsDir, "createvm.sh"); - if (createVmPath == null) { - throw new ConfigurationException("Unable to find the createvm.sh"); - } + initScripts(libvirtComputingResourceProperties); - manageSnapshotPath = Script.findScript(storageScriptsDir, "managesnapshot.sh"); - if (manageSnapshotPath == null) { - throw new ConfigurationException("Unable to find the managesnapshot.sh"); + if (libvirtComputingResourceProperties.isDeveloper()) { + libvirtComputingResourceProperties.load(getDeveloperProperties()); } - resizeVolumePath = Script.findScript(storageScriptsDir, "resizevolume.sh"); - if (resizeVolumePath == null) { - throw new ConfigurationException("Unable to find the resizevolume.sh"); - } + initConnectionToLibvirtDaemon(libvirtComputingResourceProperties); + initMonitorThread(); - createTmplPath = Script.findScript(storageScriptsDir, "createtmplt.sh"); - if (createTmplPath == null) { - throw new ConfigurationException("Unable to find the createtmplt.sh"); - } - - securityGroupPath = Script.findScript(networkScriptsDir, "security_group.py"); - if (securityGroupPath == null) { - throw new ConfigurationException("Unable to find the security_group.py"); + initStoragePoolManager(); + if (checkSystemvmIso(libvirtComputingResourceProperties)) { + return false; } - ovsTunnelPath = Script.findScript(networkScriptsDir, "ovstunnel.py"); - if (ovsTunnelPath == null) { - throw new ConfigurationException("Unable to find the ovstunnel.py"); - } + initBridges(); - routerProxyPath = Script.findScript("scripts/network/domr/", "router_proxy.sh"); - if (routerProxyPath == null) { - throw new ConfigurationException("Unable to find the router_proxy.sh"); - } + checkPhysicalInterfaces(); - ovsPvlanDhcpHostPath = Script.findScript(networkScriptsDir, "ovs-pvlan-dhcp-host.sh"); - if (ovsPvlanDhcpHostPath == null) { - throw new ConfigurationException("Unable to find the ovs-pvlan-dhcp-host.sh"); - } + initCanBridgeFirewall(); - ovsPvlanVmPath = Script.findScript(networkScriptsDir, "ovs-pvlan-vm.sh"); - if (ovsPvlanVmPath == null) { - throw new ConfigurationException("Unable to find the ovs-pvlan-vm.sh"); - } + initLocalGateway(); - final boolean isDeveloper = (Boolean) params.get("developer"); + checkVmMigrationSpeed(libvirtComputingResourceProperties); - if (isDeveloper) { - params.putAll(getDeveloperProperties()); - } + // TODO: the next few keys added to the map are not added to the POJO because they are only commuted here and are not needed in the POJO + propertiesMap = libvirtComputingResourceProperties.buildPropertiesMap(); - pool = (String) params.get("pool"); - if (pool == null) { - pool = "/root"; - } - - final String instance = (String) params.get("instance"); - - hypervisorType = HypervisorType.getType((String) params.get("hypervisor.type")); - if (hypervisorType == HypervisorType.None) { - hypervisorType = HypervisorType.KVM; - } + final Map bridges = new HashMap<>(); + bridges.put("linklocal", getLinkLocalBridgeName()); + bridges.put("public", getPublicBridgeName()); + bridges.put("private", getPrivBridgeName()); + bridges.put("guest", getGuestBridgeName()); - hypervisorUri = (String) params.get("hypervisor.uri"); - if (hypervisorUri == null) { - hypervisorUri = LibvirtConnection.getHypervisorUri(hypervisorType.toString()); - } + propertiesMap.put("libvirt.host.bridges", bridges); + propertiesMap.put("libvirt.host.pifs", pifs); + propertiesMap.put("libvirt.computing.resource", this); + propertiesMap.put("libvirtVersion", hypervisorLibvirtVersion); - networkDirectSourceMode = (String) params.get("network.direct.source.mode"); - networkDirectDevice = (String) params.get("network.direct.device"); + configureVifDrivers(propertiesMap); + configureDiskActivityChecks(propertiesMap); - String startMac = (String) params.get("private.macaddr.start"); - if (startMac == null) { - startMac = "00:16:3e:77:e2:a0"; - } + final KvmStorageProcessor storageProcessor = new KvmStorageProcessor(storagePoolMgr, this); + storageProcessor.configure(name, propertiesMap); + storageHandler = new StorageSubsystemCommandHandlerBase(storageProcessor); - String startIp = (String) params.get("private.ipaddr.start"); - if (startIp == null) { - startIp = "192.168.166.128"; - } + final String unameKernelVersion = Script.runSimpleBashScript(SCRIPT_UNAME); + final String[] kernelVersions = unameKernelVersion.split("[\\.\\-]"); + final long kernelVersion = Integer.parseInt(kernelVersions[0]) * 1000 * 1000 + (long) Integer.parseInt(kernelVersions[1]) * 1000 + Integer.parseInt(kernelVersions[2]); - pingTestPath = Script.findScript(kvmScriptsDir, "pingtest.sh"); - if (pingTestPath == null) { - throw new ConfigurationException("Unable to find the pingtest.sh"); - } + return true; + } - linkLocalBridgeName = (String) params.get("private.bridge.name"); - if (linkLocalBridgeName == null) { - if (isDeveloper) { - linkLocalBridgeName = "cloud-" + instance + "-0"; - } else { - linkLocalBridgeName = "cloud0"; + private void initScripts(final LibvirtComputingResourceProperties libvirtComputingResourceProperties) throws ConfigurationException { + final String kvmScriptsDir = libvirtComputingResourceProperties.getHypervisorScriptsDir(); + final String networkScriptsDir = libvirtComputingResourceProperties.getNetworkScriptsDir(); + final String storageScriptsDir = libvirtComputingResourceProperties.getStorageScriptsDir(); + updateHostPasswdPath = findScriptPath(kvmScriptsDir, VRScripts.UPDATE_HOST_PASSWD); + final String modifyVlanPath = findScriptPath(networkScriptsDir, SCRIPT_MODIFY_VLAN); + versionstringpath = findScriptPath(kvmScriptsDir, SCRIPT_VERSIONS); + patchViaSocketPath = findScriptPath(kvmScriptsDir, PATH_PATCH_DIR, SCRIPT_PATCH_VIA_SOCKET); + heartBeatPath = findScriptPath(kvmScriptsDir, SCRIPT_KVM_HEART_BEAT); + final String createVmPath = findScriptPath(storageScriptsDir, SCRIPT_CREATE_VM); + manageSnapshotPath = findScriptPath(storageScriptsDir, SCRIPT_MANAGE_SNAPSHOT); + resizeVolumePath = findScriptPath(storageScriptsDir, SCRIPT_RESIZE_VOLUME); + createTmplPath = findScriptPath(storageScriptsDir, SCRIPT_CREATE_TEMPLATE); + securityGroupPath = findScriptPath(networkScriptsDir, SCRIPT_SECURITY_GROUP); + ovsTunnelPath = findScriptPath(networkScriptsDir, SCRIPT_OVS_TUNNEL); + routerProxyPath = findScriptPath(PATH_SCRIPTS_NETWORK_DOMR, SCRIPT_ROUTER_PROXY); + ovsPvlanDhcpHostPath = findScriptPath(networkScriptsDir, SCRIPT_OVS_PVLAN_DHCP_HOST); + ovsPvlanVmPath = findScriptPath(networkScriptsDir, SCRIPT_OVS_PVLAN_VM); + pingTestPath = findScriptPath(kvmScriptsDir, SCRIPT_PING_TEST); + } + + private void checkVmMigrationSpeed(final LibvirtComputingResourceProperties libvirtComputingResourceProperties) { + int migrateSpeed = libvirtComputingResourceProperties.getVmMigrateSpeed(); + if (migrateSpeed == -1) { + // get guest network device speed + migrateSpeed = 0; + final String speed = Script.runSimpleBashScript(String.format(FORMAT_NETWORK_SPEED, pifs.get("public"))); + if (speed != null) { + final String[] tokens = speed.split("M"); + if (tokens.length == 2) { + try { + migrateSpeed = Integer.parseInt(tokens[0]); + } catch (final NumberFormatException e) { + logger.trace("Ignoring migrateSpeed extraction error.", e); + } + logger.debug("device " + pifs.get("public") + " has speed: " + String.valueOf(migrateSpeed)); + } } + libvirtComputingResourceProperties.setVmMigrateSpeed(migrateSpeed); } + } - publicBridgeName = (String) params.get("public.network.device"); - if (publicBridgeName == null) { - publicBridgeName = "cloudbr0"; - } - - privBridgeName = (String) params.get("private.network.device"); - if (privBridgeName == null) { - privBridgeName = "cloudbr1"; - } - - guestBridgeName = (String) params.get("guest.network.device"); - if (guestBridgeName == null) { - guestBridgeName = privBridgeName; + private void initLocalGateway() { + localGateway = Script.runSimpleBashScript(SCRIPT_LOCAL_GATEWAY); + if (localGateway == null) { + logger.debug("Failed to found the local gateway"); } + } - privNwName = (String) params.get("private.network.name"); - if (privNwName == null) { - if (isDeveloper) { - privNwName = "cloud-" + instance + "-private"; - } else { - privNwName = "cloud-private"; - } - } + private void initCanBridgeFirewall() { + canBridgeFirewall = canBridgeFirewall(pifs.get("public")); + } - localStoragePath = (String) params.get("local.storage.path"); - if (localStoragePath == null) { - localStoragePath = "/var/lib/libvirt/images/"; + private void checkPhysicalInterfaces() throws ConfigurationException { + if (pifs.get("private") == null) { + logger.debug("Failed to get private nic name"); + throw new ConfigurationException("Failed to get private nic name"); } - final File storagePath = new File(localStoragePath); - localStoragePath = storagePath.getAbsolutePath(); - - localStorageUuid = (String) params.get("local.storage.uuid"); - if (localStorageUuid == null) { - localStorageUuid = UUID.randomUUID().toString(); + if (pifs.get("public") == null) { + logger.debug("Failed to get public nic name"); + throw new ConfigurationException("Failed to get public nic name"); } + logger.debug("Found pif: " + pifs.get("private") + " on " + getPrivBridgeName() + ", pif: " + pifs.get("public") + " on " + getPublicBridgeName()); + } - String value = (String) params.get("scripts.timeout"); - timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000; - - value = (String) params.get("stop.script.timeout"); - stopTimeout = NumbersUtil.parseInt(value, 120) * 1000; - - value = (String) params.get("cmds.timeout"); - cmdsTimeout = NumbersUtil.parseInt(value, 7200) * 1000; - - value = (String) params.get("vm.memballoon.disable"); - if (Boolean.parseBoolean(value)) { - noMemBalloon = true; + private void initBridges() { + logger.debug("Initializing bridges"); + switch (getBridgeType()) { + case OPENVSWITCH: + getOvsPifs(); + break; + case NATIVE: + default: + getPifs(); + break; } + } - videoHw = (String) params.get("vm.video.hardware"); - value = (String) params.get("vm.video.ram"); - videoRam = NumbersUtil.parseInt(value, 0); - - value = (String) params.get("host.reserved.mem.mb"); - // Reserve 1GB unless admin overrides - dom0MinMem = NumbersUtil.parseInt(value, 1024) * 1024 * 1024L; + private BridgeType getBridgeType() { + return libvirtComputingResourceProperties.getNetworkBridgeType(); + } - value = (String) params.get("kvmclock.disable"); - if (Boolean.parseBoolean(value)) { - noKvmClock = true; + private boolean checkSystemvmIso(final LibvirtComputingResourceProperties libvirtComputingResourceProperties) { + if (!storage.exists(libvirtComputingResourceProperties.getSystemvmIsoPath())) { + logger.debug("Can't find system vm ISO"); + return true; } + return false; + } - value = (String) params.get("vm.rng.enable"); - if (Boolean.parseBoolean(value)) { - rngEnable = true; - value = (String) params.get("vm.rng.model"); - if (!Strings.isNullOrEmpty(value)) { - rngBackendModel = RngBackendModel.valueOf(value.toUpperCase()); - } - value = (String) params.get("vm.rng.path"); - if (!Strings.isNullOrEmpty(value)) { - rngPath = value; - } - } + private void initStoragePoolManager() { + storagePoolMgr = new KvmStoragePoolManager(storage, monitor); + } - value = (String) params.get("vm.watchdog.model"); - if (!Strings.isNullOrEmpty(value)) { - watchDogModel = WatchDogModel.valueOf(value.toUpperCase()); - } + private void initMonitorThread() { + final String[] info = NetUtils.getNetworkParams(_privateNic); + monitor = new KvmHaMonitor(null, info[0], heartBeatPath); + final Thread ha = new Thread(monitor); + ha.start(); + } - value = (String) params.get("vm.watchdog.action"); - if (!Strings.isNullOrEmpty(value)) { - watchDogAction = WatchDogAction.valueOf(value.toUpperCase()); - } + private void initConnectionToLibvirtDaemon(final LibvirtComputingResourceProperties libvirtComputingResourceProperties) throws ConfigurationException { + LibvirtConnection.initialize(getHypervisorUri()); + final Connect conn = connectToHypervisor(); - LibvirtConnection.initialize(hypervisorUri); - Connect conn = null; - try { - conn = LibvirtConnection.getConnection(); - - if (bridgeType == BridgeType.OPENVSWITCH) { - if (conn.getLibVirVersion() < 10 * 1000 + 0) { - throw new ConfigurationException("Libvirt version 0.10.0 required for openvswitch support, but version " - + conn.getLibVirVersion() + " detected"); - } - } - } catch (final LibvirtException e) { - throw new CloudRuntimeException(e.getMessage()); - } - - if (HypervisorType.KVM == hypervisorType) { - /* Does node support HVM guest? If not, exit */ - if (!isHvmEnabled(conn)) { - throw new ConfigurationException("NO HVM support on this machine, please make sure: " - + "1. VT/SVM is supported by your CPU, or is enabled in BIOS. " - + "2. kvm modules are loaded (kvm, kvm_amd|kvm_intel)"); - } - } + checkIsHvmEnabled(conn); hypervisorPath = getHypervisorPath(conn); try { @@ -1151,165 +1019,74 @@ public boolean configure(final String name, final Map params) th hypervisorLibvirtVersion = conn.getLibVirVersion(); hypervisorQemuVersion = conn.getVersion(); } catch (final LibvirtException e) { - LOGGER.trace("Ignoring libvirt error.", e); + logger.trace("Ignoring libvirt error.", e); } - guestCpuMode = (String) params.get("guest.cpu.mode"); - if (guestCpuMode != null) { - guestCpuModel = (String) params.get("guest.cpu.model"); - + if (libvirtComputingResourceProperties.hasGuestCpuMode()) { if (hypervisorLibvirtVersion < 9 * 1000 + 10) { - LOGGER.warn("Libvirt version 0.9.10 required for guest cpu mode, but version " - + prettyVersion(hypervisorLibvirtVersion) - + " detected, so it will be disabled"); - guestCpuMode = ""; - guestCpuModel = ""; + logger.warn("Libvirt version 0.9.10 required for guest cpu mode, but version {} detected, so it will be disabled", prettyVersion(hypervisorLibvirtVersion)); + libvirtComputingResourceProperties.unsetGuestCpuMode(); + libvirtComputingResourceProperties.unsetGuestCpuModel(); } - params.put("guest.cpu.mode", guestCpuMode); - params.put("guest.cpu.model", guestCpuModel); } + } - final String guestCpuFeatures = (String) params.get("guest.cpu.features"); - if (guestCpuFeatures != null) { - cpuFeatures = new ArrayList<>(); - for (final String feature : guestCpuFeatures.split(" ")) { - if (!feature.isEmpty()) { - cpuFeatures.add(feature); - } - } - } - - final String[] info = NetUtils.getNetworkParams(_privateNic); - - monitor = new KvmHaMonitor(null, info[0], heartBeatPath); - final Thread ha = new Thread(monitor); - ha.start(); - - storagePoolMgr = new KvmStoragePoolManager(storage, monitor); + private String getHypervisorUri() { + return libvirtComputingResourceProperties.getHypervisorUri(); + } - sysvmIsoPath = (String) params.get("systemvm.iso.path"); - if (sysvmIsoPath == null) { - final String[] isoPaths = {"/usr/share/cosmic-common/vms/systemvm.iso"}; - for (final String isoPath : isoPaths) { - if (storage.exists(isoPath)) { - sysvmIsoPath = isoPath; - break; - } - } - if (sysvmIsoPath == null) { - LOGGER.debug("Can't find system vm ISO"); - } - } + private boolean initVirtualRoutingResource(final String name, final Map propertiesMap) throws ConfigurationException { + virtRouterResource = new VirtualRoutingResource(this); - switch (bridgeType) { - case OPENVSWITCH: - getOvsPifs(); - break; - case NATIVE: - default: - getPifs(); - break; + if (!virtRouterResource.configure(name, propertiesMap)) { + return true; } + return false; + } - if (pifs.get("private") == null) { - LOGGER.debug("Failed to get private nic name"); - throw new ConfigurationException("Failed to get private nic name"); - } + private void initStorage(final Map propertiesMap) throws ConfigurationException { + storage = new JavaStorageLayer(); + storage.configure("StorageLayer", propertiesMap); + } - if (pifs.get("public") == null) { - LOGGER.debug("Failed to get public nic name"); - throw new ConfigurationException("Failed to get public nic name"); + private static String findScriptPath(final String baseDir, final String path, final String scriptName) throws ConfigurationException { + final String scriptPath = Script.findScript(baseDir + path, scriptName); + if (scriptPath == null) { + throw new ConfigurationException("Unable to find " + scriptName); + } else { + return scriptPath; } - LOGGER.debug("Found pif: " + pifs.get("private") + " on " + privBridgeName + ", pif: " + pifs.get("public") + " on " - + publicBridgeName); - - canBridgeFirewall = canBridgeFirewall(pifs.get("public")); + } - localGateway = Script.runSimpleBashScript("ip route |grep default|awk '{print $3}'"); - if (localGateway == null) { - LOGGER.debug("Failed to found the local gateway"); - } + private static String findScriptPath(final String baseDir, final String scriptName) throws ConfigurationException { + return findScriptPath(baseDir, "", scriptName); + } - mountPoint = (String) params.get("mount.path"); - if (mountPoint == null) { - mountPoint = "/mnt"; + private void checkIsHvmEnabled(final Connect conn) throws ConfigurationException { + if (HypervisorType.KVM == getHypervisorType()) { + if (!isHvmEnabled(conn)) { + throw new ConfigurationException("NO HVM support on this machine, please make sure: " + + "1. VT/SVM is supported by your CPU, or is enabled in BIOS. " + + "2. kvm modules are loaded (kvm, kvm_amd|kvm_intel)"); + } } + } - value = (String) params.get("vm.migrate.downtime"); - migrateDowntime = NumbersUtil.parseInt(value, -1); - - value = (String) params.get("vm.migrate.pauseafter"); - migratePauseAfter = NumbersUtil.parseInt(value, -1); + private Connect connectToHypervisor() throws ConfigurationException { + Connect conn = null; + try { + conn = LibvirtConnection.getConnection(); - value = (String) params.get("vm.migrate.speed"); - migrateSpeed = NumbersUtil.parseInt(value, -1); - if (migrateSpeed == -1) { - // get guest network device speed - migrateSpeed = 0; - final String speed = Script.runSimpleBashScript( - "ethtool " + pifs.get("public") + " |grep Speed | cut -d \\ -f 2"); - if (speed != null) { - final String[] tokens = speed.split("M"); - if (tokens.length == 2) { - try { - migrateSpeed = Integer.parseInt(tokens[0]); - } catch (final NumberFormatException e) { - LOGGER.trace("Ignoring migrateSpeed extraction error.", e); - } - LOGGER.debug("device " + pifs.get("public") + " has speed: " + String.valueOf(migrateSpeed)); + if (getBridgeType() == OPENVSWITCH) { + if (conn.getLibVirVersion() < 10 * 1000 + 0) { + throw new ConfigurationException("Libvirt version 0.10.0 required for openvswitch support, but version " + + conn.getLibVirVersion() + " detected"); } } - params.put("vm.migrate.speed", String.valueOf(migrateSpeed)); + } catch (final LibvirtException e) { + throw new CloudRuntimeException(e.getMessage()); } - - final Map bridges = new HashMap<>(); - bridges.put("linklocal", linkLocalBridgeName); - bridges.put("public", publicBridgeName); - bridges.put("private", privBridgeName); - bridges.put("guest", guestBridgeName); - - params.put("libvirt.host.bridges", bridges); - params.put("libvirt.host.pifs", pifs); - - params.put("libvirt.computing.resource", this); - params.put("libvirtVersion", hypervisorLibvirtVersion); - - configureVifDrivers(params); - configureDiskActivityChecks(params); - - final KvmStorageProcessor storageProcessor = new KvmStorageProcessor(storagePoolMgr, this); - storageProcessor.configure(name, params); - storageHandler = new StorageSubsystemCommandHandlerBase(storageProcessor); - - final String unameKernelVersion = Script.runSimpleBashScript("uname -r"); - final String[] kernelVersions = unameKernelVersion.split("[\\.\\-]"); - kernelVersion = Integer.parseInt(kernelVersions[0]) * 1000 * 1000 - + (long) Integer.parseInt(kernelVersions[1]) * 1000 + Integer.parseInt(kernelVersions[2]); - - /* - * Disable this, the code using this is pretty bad and non portable getOsVersion(); - */ - return true; - } - - protected String getDefaultDomrScriptsDir() { - return "scripts/network/domr"; - } - - protected String getDefaultHypervisorScriptsDir() { - return "scripts/vm/hypervisor"; - } - - protected String getDefaultKvmScriptsDir() { - return "scripts/vm/hypervisor/kvm"; - } - - protected String getDefaultNetworkScriptsDir() { - return "scripts/vm/network/vnet"; - } - - protected String getDefaultStorageScriptsDir() { - return "scripts/storage/qcow2"; + return conn; } private Map getDeveloperProperties() throws ConfigurationException { @@ -1319,7 +1096,7 @@ private Map getDeveloperProperties() throws ConfigurationExcepti throw new ConfigurationException("Unable to find developer.properties."); } - LOGGER.info("developer.properties found at " + file.getAbsolutePath()); + logger.info("developer.properties found at " + file.getAbsolutePath()); try { final Properties properties = PropertiesUtil.loadFromFile(file); @@ -1358,7 +1135,7 @@ private boolean isHvmEnabled(final Connect conn) { } } } catch (final LibvirtException e) { - LOGGER.trace("Ignoring libvirt error.", e); + logger.trace("Ignoring libvirt error.", e); } return false; } @@ -1368,7 +1145,7 @@ private String getHypervisorPath(final Connect conn) { try { parser.parseCapabilitiesXml(conn.getCapabilities()); } catch (final LibvirtException e) { - LOGGER.debug(e.getMessage()); + logger.debug(e.getMessage()); } return parser.getEmulator(); } @@ -1392,47 +1169,49 @@ private String prettyVersion(final long version) { } private void getOvsPifs() { + logger.debug("Looking for OpenVSwitch bridges"); final String cmdout = Script.runSimpleBashScript("ovs-vsctl list-br | sed '{:q;N;s/\\n/%/g;t q}'"); - LOGGER.debug("cmdout was " + cmdout); + logger.debug("cmdout was " + cmdout); final List bridges = Arrays.asList(cmdout.split("%")); for (final String bridge : bridges) { - LOGGER.debug("looking for pif for bridge " + bridge); + logger.debug("looking for pif for bridge " + bridge); // String pif = getOvsPif(bridge); // Not really interested in the pif name at this point for ovs // bridges final String pif = bridge; - if (publicBridgeName != null && bridge.equals(publicBridgeName)) { + if (getPublicBridgeName() != null && bridge.equals(getPublicBridgeName())) { pifs.put("public", pif); } - if (guestBridgeName != null && bridge.equals(guestBridgeName)) { + if (getGuestBridgeName() != null && bridge.equals(getGuestBridgeName())) { pifs.put("private", pif); } pifs.put(bridge, pif); } - LOGGER.debug("done looking for pifs, no more bridges"); + logger.debug("done looking for pifs, no more bridges"); } private void getPifs() { + logger.debug("Looking for Linux bridges"); final File dir = new File("/sys/devices/virtual/net"); final File[] netdevs = dir.listFiles(); final List bridges = new ArrayList<>(); for (final File netdev : netdevs) { final File isbridge = new File(netdev.getAbsolutePath() + "/bridge"); final String netdevName = netdev.getName(); - LOGGER.debug("looking in file " + netdev.getAbsolutePath() + "/bridge"); + logger.debug("looking in file " + netdev.getAbsolutePath() + "/bridge"); if (isbridge.exists()) { - LOGGER.debug("Found bridge " + netdevName); + logger.debug("Found bridge " + netdevName); bridges.add(netdevName); } } for (final String bridge : bridges) { - LOGGER.debug("looking for pif for bridge " + bridge); + logger.debug("looking for pif for bridge " + bridge); final String pif = getPif(bridge); - if (publicBridgeName != null && bridge.equals(publicBridgeName)) { + if (getPublicBridgeName() != null && bridge.equals(getPublicBridgeName())) { pifs.put("public", pif); } - if (guestBridgeName != null && bridge.equals(guestBridgeName)) { + if (getGuestBridgeName() != null && bridge.equals(getGuestBridgeName())) { pifs.put("private", pif); } pifs.put(bridge, pif); @@ -1441,32 +1220,32 @@ private void getPifs() { // guest(private) creates bridges on a pif, if private bridge not found try pif direct // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label if (pifs.get("private") == null) { - LOGGER.debug("guest(private) traffic label '" + guestBridgeName + logger.debug("guest(private) traffic label '" + getGuestBridgeName() + "' not found as bridge, looking for physical interface"); - final File dev = new File("/sys/class/net/" + guestBridgeName); + final File dev = new File("/sys/class/net/" + getGuestBridgeName()); if (dev.exists()) { - LOGGER.debug("guest(private) traffic label '" + guestBridgeName + "' found as a physical device"); - pifs.put("private", guestBridgeName); + logger.debug("guest(private) traffic label '" + getGuestBridgeName() + "' found as a physical device"); + pifs.put("private", getGuestBridgeName()); } } // public creates bridges on a pif, if private bridge not found try pif direct // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label if (pifs.get("public") == null) { - LOGGER.debug( - "public traffic label '" + publicBridgeName + "' not found as bridge, looking for physical interface"); - final File dev = new File("/sys/class/net/" + publicBridgeName); + logger.debug( + "public traffic label '" + getPublicBridgeName() + "' not found as bridge, looking for physical interface"); + final File dev = new File("/sys/class/net/" + getPublicBridgeName()); if (dev.exists()) { - LOGGER.debug("public traffic label '" + publicBridgeName + "' found as a physical device"); - pifs.put("public", publicBridgeName); + logger.debug("public traffic label '" + getPublicBridgeName() + "' found as a physical device"); + pifs.put("public", getPublicBridgeName()); } } - LOGGER.debug("done looking for pifs, no more bridges"); + logger.debug("done looking for pifs, no more bridges"); } private boolean canBridgeFirewall(final String prvNic) { - final Script cmd = new Script(securityGroupPath, timeout, LOGGER); + final Script cmd = new Script(securityGroupPath, getScriptsTimeout(), logger); cmd.add("can_bridge_firewall"); cmd.add(prvNic); final String result = cmd.execute(); @@ -1484,11 +1263,11 @@ protected void configureVifDrivers(final Map params) throws Conf // Load the default vif driver String defaultVifDriverName = (String) params.get(libvirtVifDriver); if (defaultVifDriverName == null) { - if (bridgeType == BridgeType.OPENVSWITCH) { - LOGGER.info("No libvirt.vif.driver specified. Defaults to OvsVifDriver."); + if (getBridgeType() == OPENVSWITCH) { + logger.info("No libvirt.vif.driver specified. Defaults to OvsVifDriver."); defaultVifDriverName = DEFAULT_OVS_VIF_DRIVER_CLASS; } else { - LOGGER.info("No libvirt.vif.driver specified. Defaults to BridgeVifDriver."); + logger.info("No libvirt.vif.driver specified. Defaults to BridgeVifDriver."); defaultVifDriverName = DEFAULT_BRIDGE_VIF_DRIVER_CLASS; } } @@ -1578,28 +1357,20 @@ public boolean stop() { final Connect conn = LibvirtConnection.getConnection(); conn.close(); } catch (final LibvirtException e) { - LOGGER.trace("Ignoring libvirt error.", e); + logger.trace("Ignoring libvirt error.", e); } return true; } - protected String getNetworkDirectSourceMode() { - return networkDirectSourceMode; - } - - protected String getNetworkDirectDevice() { - return networkDirectDevice; - } - public boolean passCmdLine(final String vmName, final String cmdLine) throws InternalErrorException { - final Script command = new Script(patchViaSocketPath, 5 * 1000, LOGGER); + final Script command = new Script(patchViaSocketPath, 5 * 1000, logger); final String result; command.add("-n", vmName); command.add("-p", cmdLine.replaceAll(" ", "%")); result = command.execute(); if (result != null) { - LOGGER.debug("passcmd failed:" + result); + logger.debug("passcmd failed:" + result); return false; } return true; @@ -1621,14 +1392,14 @@ boolean isDirectAttachedNetwork(final String type) { public synchronized boolean destroyTunnelNetwork(final String bridge) { findOrCreateTunnelNetwork(bridge); - final Script cmd = new Script(ovsTunnelPath, timeout, LOGGER); + final Script cmd = new Script(ovsTunnelPath, getScriptsTimeout(), logger); cmd.add("destroy_ovs_bridge"); cmd.add("--bridge", bridge); final String result = cmd.execute(); if (result != null) { - LOGGER.debug("OVS Bridge could not be destroyed due to error ==> " + result); + logger.debug("OVS Bridge could not be destroyed due to error ==> " + result); return false; } return true; @@ -1645,9 +1416,9 @@ public synchronized boolean findOrCreateTunnelNetwork(final String nwName) { Script.runSimpleBashScript("ovs-vsctl -- --may-exist add-br " + nwName + " -- set bridge " + nwName + " other_config:ovs-host-setup='-1'"); - LOGGER.debug("### KVM network for tunnels created:" + nwName); + logger.debug("### KVM network for tunnels created:" + nwName); } catch (final Exception e) { - LOGGER.warn("createTunnelNetwork failed", e); + logger.warn("createTunnelNetwork failed", e); return false; } return true; @@ -1658,7 +1429,7 @@ public boolean checkNetwork(final String networkName) { return true; } - if (bridgeType == BridgeType.OPENVSWITCH) { + if (getBridgeType() == OPENVSWITCH) { return checkOvsNetwork(networkName); } else { return checkBridgeNetwork(networkName); @@ -1666,12 +1437,12 @@ public boolean checkNetwork(final String networkName) { } private boolean checkOvsNetwork(final String networkName) { - LOGGER.debug("Checking if network " + networkName + " exists as openvswitch bridge"); + logger.debug("Checking if network " + networkName + " exists as openvswitch bridge"); if (networkName == null) { return true; } - final Script command = new Script("/bin/sh", timeout); + final Script command = new Script("/bin/sh", getScriptsTimeout()); command.add("-c"); command.add("ovs-vsctl br-exists " + networkName); return "0".equals(command.execute(null)); @@ -1696,7 +1467,7 @@ public synchronized boolean configureTunnelNetwork(final long networkId, try { final boolean findResult = findOrCreateTunnelNetwork(nwName); if (!findResult) { - LOGGER.warn( + logger.warn( "LibvirtComputingResource.findOrCreateTunnelNetwork() failed! Cannot proceed creating the tunnel."); return false; } @@ -1713,7 +1484,7 @@ public synchronized boolean configureTunnelNetwork(final long networkId, } } if (!configured) { - final Script cmd = new Script(ovsTunnelPath, timeout, LOGGER); + final Script cmd = new Script(ovsTunnelPath, getScriptsTimeout(), logger); cmd.add("setup_ovs_bridge"); cmd.add("--key", nwName); cmd.add("--cs_host_id", ((Long) hostId).toString()); @@ -1726,7 +1497,7 @@ public synchronized boolean configureTunnelNetwork(final long networkId, } } } catch (final Exception e) { - LOGGER.warn("createandConfigureTunnelNetwork failed", e); + logger.warn("createandConfigureTunnelNetwork failed", e); return false; } return true; @@ -1755,7 +1526,7 @@ public KvmPhysicalDisk templateToPrimaryDownload(final String templateUrl, final secondaryPool.refresh(); final List disks = secondaryPool.listPhysicalDisks(); if (disks == null || disks.isEmpty()) { - LOGGER.error("Failed to get volumes from pool: " + secondaryPool.getUuid()); + logger.error("Failed to get volumes from pool: " + secondaryPool.getUuid()); return null; } for (final KvmPhysicalDisk disk : disks) { @@ -1765,7 +1536,7 @@ public KvmPhysicalDisk templateToPrimaryDownload(final String templateUrl, final } } if (templateVol == null) { - LOGGER.error("Failed to get template from pool: " + secondaryPool.getUuid()); + logger.error("Failed to get template from pool: " + secondaryPool.getUuid()); return null; } } else { @@ -1777,7 +1548,7 @@ public KvmPhysicalDisk templateToPrimaryDownload(final String templateUrl, final final KvmPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(templateVol, volUuid, primaryPool, 0); return primaryVol; } catch (final CloudRuntimeException e) { - LOGGER.error("Failed to download template to primary storage", e); + logger.error("Failed to download template to primary storage", e); return null; } finally { if (secondaryPool != null) { @@ -1811,14 +1582,14 @@ public PowerState getVmState(final Connect conn, final String vmName) { final PowerState s = convertToPowerState(vms.getInfo().state); return s; } catch (final LibvirtException e) { - LOGGER.warn("Can't get vm state " + vmName + e.getMessage() + "retry:" + retry); + logger.warn("Can't get vm state " + vmName + e.getMessage() + "retry:" + retry); } finally { try { if (vms != null) { vms.free(); } } catch (final LibvirtException l) { - LOGGER.trace("Ignoring libvirt error.", l); + logger.trace("Ignoring libvirt error.", l); } } } @@ -1860,7 +1631,7 @@ public long[] getVpcNetworkStats(final String privateIp, final String publicIp, public String configureVpcNetworkUsage(final String privateIpAddress, final String publicIp, final String option, final String vpcCidr) { - final Script getUsage = new Script(routerProxyPath, LOGGER); + final Script getUsage = new Script(routerProxyPath, logger); getUsage.add("vpc_netusage.sh"); getUsage.add(privateIpAddress); getUsage.add("-l", publicIp); @@ -1881,13 +1652,13 @@ public String configureVpcNetworkUsage(final String privateIpAddress, final Stri final OutputInterpreter.OneLineParser usageParser = new OutputInterpreter.OneLineParser(); final String result = getUsage.execute(usageParser); if (result != null) { - LOGGER.debug("Failed to execute VPCNetworkUsage:" + result); + logger.debug("Failed to execute VPCNetworkUsage:" + result); return null; } return usageParser.getLine(); } - public void handleVmStartFailure(final Connect conn, final String vmName, final LibvirtVmDef vm) { + public void handleVmStartFailure(final Connect conn, final LibvirtVmDef vm) { if (vm != null && vm.getDevices() != null) { cleanupVmNetworks(conn, vm.getDevices().getInterfaces()); } @@ -1929,7 +1700,7 @@ public LibvirtVmDef createVmFromSpec(final VirtualMachineTO vmTo) { final GuestResourceDef grd = new GuestResourceDef(); - if (vmTo.getMinRam() != vmTo.getMaxRam() && !noMemBalloon) { + if (vmTo.getMinRam() != vmTo.getMaxRam() && !libvirtComputingResourceProperties.getVmMemballoonDisable()) { grd.setMemBalloning(true); grd.setCurrentMem(vmTo.getMinRam() / 1024); grd.setMemorySize(vmTo.getMaxRam() / 1024); @@ -1941,10 +1712,10 @@ public LibvirtVmDef createVmFromSpec(final VirtualMachineTO vmTo) { vm.addComp(grd); final CpuModeDef cmd = new CpuModeDef(); - cmd.setMode(guestCpuMode); - cmd.setModel(guestCpuModel); + cmd.setMode(getGuestCpuMode()); + cmd.setModel(getGuestCpuModel()); if (vmTo.getType() == VirtualMachine.Type.User) { - cmd.setFeatures(cpuFeatures); + cmd.setFeatures(getCpuFeatures()); } // multi cores per socket, for larger core configs if (vcpus % 6 == 0) { @@ -1990,7 +1761,7 @@ public LibvirtVmDef createVmFromSpec(final VirtualMachineTO vmTo) { clock.setTimer("rtc", "catchup", null); } else if (vmTo.getType() != VirtualMachine.Type.User || isGuestPvEnabled(vmTo.getOs())) { if (hypervisorLibvirtVersion >= 9 * 1000 + 10) { - clock.setTimer("kvmclock", null, null, noKvmClock); + clock.setTimer("kvmclock", null, null, isKvmclockDisabled()); } } @@ -2011,7 +1782,7 @@ public LibvirtVmDef createVmFromSpec(final VirtualMachineTO vmTo) { final QemuGuestAgentDef guestagent = new QemuGuestAgentDef(); devices.addDevice(guestagent); - if (rngEnable) { + if (libvirtComputingResourceProperties.getVmRngEnable()) { final RngDef rngDevice = new RngDef(rngPath, rngBackendModel); devices.addDevice(rngDevice); } @@ -2019,7 +1790,7 @@ public LibvirtVmDef createVmFromSpec(final VirtualMachineTO vmTo) { final WatchDogDef watchDog = new WatchDogDef(watchDogAction, watchDogModel); devices.addDevice(watchDog); - final VideoDef videoCard = new VideoDef(videoHw, videoRam); + final VideoDef videoCard = new VideoDef(libvirtComputingResourceProperties.getVmVideoHardware(), libvirtComputingResourceProperties.getVmVideoRam()); devices.addDevice(videoCard); final ConsoleDef console = new ConsoleDef("pty", null, null, (short) 0); @@ -2038,18 +1809,30 @@ public LibvirtVmDef createVmFromSpec(final VirtualMachineTO vmTo) { return vm; } + private boolean isKvmclockDisabled() { + return libvirtComputingResourceProperties.isKvmclockDisable(); + } + + private String getGuestCpuModel() { + return libvirtComputingResourceProperties.getGuestCpuModel(); + } + + private String getGuestCpuMode() { + return libvirtComputingResourceProperties.getGuestCpuMode(); + } + protected String getUuid(String uuid) { if (uuid == null) { - uuid = UUID.randomUUID().toString(); + uuid = randomUUID().toString(); } else { try { final UUID uuid2 = UUID.fromString(uuid); final String uuid3 = uuid2.toString(); if (!uuid3.equals(uuid)) { - uuid = UUID.randomUUID().toString(); + uuid = randomUUID().toString(); } } catch (final IllegalArgumentException e) { - uuid = UUID.randomUUID().toString(); + uuid = randomUUID().toString(); } } return uuid; @@ -2103,8 +1886,8 @@ private void createVif(final LibvirtVmDef vm, final NicTO nic, final String nicA final String vrIp = nic.getBroadcastUri().getPath().substring(1); vm.getMetaData().getMetadataNode(LibvirtVmDef.NuageExtensionDef.class).addNuageExtension(nic.getMac(), vrIp); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("NIC with MAC " + nic.getMac() + " and BroadcastDomainType " + nic.getBroadcastType() + if (logger.isDebugEnabled()) { + logger.debug("NIC with MAC " + nic.getMac() + " and BroadcastDomainType " + nic.getBroadcastType() + " in network(" + nic.getGateway() + "/" + nic.getNetmask() + ") is " + nic.getType() + " traffic type. So, vsp-vr-ip " + vrIp + " is set in the metadata"); } @@ -2178,7 +1961,7 @@ public int compare(final DiskTO arg0, final DiskTO arg1) { // check for disk activity, if detected we should exit because vm is running elsewhere if (diskActivityCheckEnabled && physicalDisk != null && physicalDisk.getFormat() == PhysicalDiskFormat.QCOW2) { - LOGGER.debug("Checking physical disk file at path " + volPath + logger.debug("Checking physical disk file at path " + volPath + " for disk activity to ensure vm is not running elsewhere"); try { HypervisorUtils.checkVolumeFileForActivity(volPath, diskActivityCheckTimeoutSeconds, @@ -2186,7 +1969,7 @@ public int compare(final DiskTO arg0, final DiskTO arg1) { } catch (final IOException ex) { throw new CloudRuntimeException("Unable to check physical disk file for activity", ex); } - LOGGER.debug("Disk activity check cleared"); + logger.debug("Disk activity check cleared"); } // if params contains a rootDiskController key, use its value (this is what other HVs are doing) @@ -2194,10 +1977,10 @@ public int compare(final DiskTO arg0, final DiskTO arg1) { final Map params = vmSpec.getDetails(); if (params != null && params.get("rootDiskController") != null && !params.get("rootDiskController").isEmpty()) { final String rootDiskController = params.get("rootDiskController"); - LOGGER.debug("Passed custom disk bus " + rootDiskController); + logger.debug("Passed custom disk bus " + rootDiskController); for (final DiskDef.DiskBus bus : DiskDef.DiskBus.values()) { if (bus.toString().equalsIgnoreCase(rootDiskController)) { - LOGGER.debug("Found matching enum for disk bus " + rootDiskController); + logger.debug("Found matching enum for disk bus " + rootDiskController); diskBusType = bus; break; } @@ -2267,6 +2050,7 @@ public int compare(final DiskTO arg0, final DiskTO arg1) { } if (vmSpec.getType() != VirtualMachine.Type.User) { + final String sysvmIsoPath = getSysvmIsoPath(); if (sysvmIsoPath != null) { final DiskDef iso = new DiskDef(); iso.defIsoDisk(sysvmIsoPath); @@ -2275,6 +2059,10 @@ public int compare(final DiskTO arg0, final DiskTO arg1) { } } + private String getSysvmIsoPath() { + return libvirtComputingResourceProperties.getSystemvmIsoPath(); + } + @Override public Type getType() { return Type.Routing; @@ -2289,7 +2077,7 @@ private DiskDef.DiskBus getGuestDiskModel(final String platformEmulator) { } private Map getVersionStrings() { - final Script command = new Script(versionstringpath, timeout, LOGGER); + final Script command = new Script(versionstringpath, getScriptsTimeout(), logger); final KeyValueInterpreter kvi = new KeyValueInterpreter(); final String result = command.execute(kvi); if (result == null) { @@ -2310,21 +2098,22 @@ public StartupCommand[] initialize() { final List info = getHostInfo(); final StartupRoutingCommand cmd = new StartupRoutingCommand((Integer) info.get(0), (Long) info.get(1), - (Long) info.get(2), (Long) info.get(4), (String) info.get(3), hypervisorType, + (Long) info.get(2), (Long) info.get(4), (String) info.get(3), getHypervisorType(), RouterPrivateIpStrategy.HostLocal); cmd.setCpuSockets((Integer) info.get(5)); fillNetworkInformation(cmd); privateIp = cmd.getPrivateIpAddress(); cmd.getHostDetails().putAll(getVersionStrings()); - cmd.setPool(pool); - cmd.setCluster(clusterId); + cmd.setPool(getPool()); + cmd.setCluster(getCluster()); cmd.setGatewayIpAddress(localGateway); cmd.setIqn(getIqn()); StartupStorageCommand sscmd = null; try { - final KvmStoragePool localStoragePool = storagePoolMgr.createStoragePool(localStorageUuid, "localhost", -1, + final String localStoragePath = getLocalStoragePath(); + final KvmStoragePool localStoragePool = storagePoolMgr.createStoragePool(getLocalStorageUuid(), "localhost", -1, localStoragePath, "", StoragePoolType.Filesystem); final com.cloud.agent.api.StoragePoolInfo pi = new com.cloud.agent.api.StoragePoolInfo(localStoragePool.getUuid(), cmd.getPrivateIpAddress(), localStoragePath, localStoragePath, @@ -2333,10 +2122,10 @@ public StartupCommand[] initialize() { sscmd = new StartupStorageCommand(); sscmd.setPoolInfo(pi); sscmd.setGuid(pi.getUuid()); - sscmd.setDataCenter(dcId); + sscmd.setDataCenter(getZone()); sscmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL); } catch (final CloudRuntimeException e) { - LOGGER.debug("Unable to initialize local storage pool: " + e); + logger.debug("Unable to initialize local storage pool: " + e); } if (sscmd != null) { @@ -2346,6 +2135,26 @@ public StartupCommand[] initialize() { } } + private String getZone() { + return libvirtComputingResourceProperties.getZone(); + } + + private String getLocalStoragePath() { + return libvirtComputingResourceProperties.getLocalStoragePath(); + } + + private String getLocalStorageUuid() { + return libvirtComputingResourceProperties.getLocalStorageUuid(); + } + + private String getCluster() { + return libvirtComputingResourceProperties.getCluster(); + } + + private String getPool() { + return libvirtComputingResourceProperties.getPool(); + } + protected KvmStoragePoolManager getPoolManager() { return storagePoolMgr; } @@ -2387,7 +2196,7 @@ private String getIqn() { try { final String textToFind = "InitiatorName="; - final Script iScsiAdmCmd = new Script(true, "grep", 0, LOGGER); + final Script iScsiAdmCmd = new Script(true, "grep", 0, logger); iScsiAdmCmd.add(textToFind); iScsiAdmCmd.add("/etc/iscsi/initiatorname.iscsi"); @@ -2416,7 +2225,7 @@ public List getDisks(final Connect conn, final String vmName) { parser.parseDomainXml(dm.getXMLDesc(0)); return parser.getDisks(); } catch (final LibvirtException e) { - LOGGER.debug("Failed to get dom xml: " + e.toString()); + logger.debug("Failed to get dom xml: " + e.toString()); return new ArrayList<>(); } finally { try { @@ -2424,7 +2233,7 @@ public List getDisks(final Connect conn, final String vmName) { dm.free(); } } catch (final LibvirtException e) { - LOGGER.trace("Ignoring libvirt error.", e); + logger.trace("Ignoring libvirt error.", e); } } } @@ -2435,17 +2244,17 @@ protected synchronized String attachOrDetachDevice(final Connect conn, final boo try { dm = conn.domainLookupByName(vmName); if (attach) { - LOGGER.debug("Attaching device: " + xml); + logger.debug("Attaching device: " + xml); dm.attachDevice(xml); } else { - LOGGER.debug("Detaching device: " + xml); + logger.debug("Detaching device: " + xml); dm.detachDevice(xml); } } catch (final LibvirtException e) { if (attach) { - LOGGER.warn("Failed to attach device to " + vmName + ": " + e.getMessage()); + logger.warn("Failed to attach device to " + vmName + ": " + e.getMessage()); } else { - LOGGER.warn("Failed to detach device from " + vmName + ": " + e.getMessage()); + logger.warn("Failed to detach device from " + vmName + ": " + e.getMessage()); } throw e; } finally { @@ -2453,7 +2262,7 @@ protected synchronized String attachOrDetachDevice(final Connect conn, final boo try { dm.free(); } catch (final LibvirtException l) { - LOGGER.trace("Ignoring libvirt error.", l); + logger.trace("Ignoring libvirt error.", l); } } } @@ -2465,12 +2274,12 @@ private HashMap getHostVmStateReport() { final HashMap vmStates = new HashMap<>(); Connect conn = null; - if (hypervisorType == HypervisorType.KVM) { + if (getHypervisorType() == HypervisorType.KVM) { try { conn = LibvirtConnection.getConnectionByType(HypervisorType.KVM.toString()); vmStates.putAll(getHostVmStateReport(conn)); } catch (final LibvirtException e) { - LOGGER.debug("Failed to get connection: " + e.getMessage()); + logger.debug("Failed to get connection: " + e.getMessage()); } } @@ -2481,7 +2290,7 @@ public boolean cleanupDisk(final DiskDef disk) { final String path = disk.getDiskPath(); if (path == null) { - LOGGER.debug("Unable to clean up disk with null path (perhaps empty cdrom drive):" + disk); + logger.debug("Unable to clean up disk with null path (perhaps empty cdrom drive):" + disk); return false; } @@ -2502,13 +2311,13 @@ private HashMap getHostVmStateReport(final Conne try { ids = conn.listDomains(); } catch (final LibvirtException e) { - LOGGER.warn("Unable to listDomains", e); + logger.warn("Unable to listDomains", e); return null; } try { vms = conn.listDefinedDomains(); } catch (final LibvirtException e) { - LOGGER.warn("Unable to listDomains", e); + logger.warn("Unable to listDomains", e); return null; } @@ -2521,7 +2330,7 @@ private HashMap getHostVmStateReport(final Conne final PowerState state = convertToPowerState(ps); - LOGGER.trace("VM " + dm.getName() + ": powerstate = " + ps + "; vm state=" + state.toString()); + logger.trace("VM " + dm.getName() + ": powerstate = " + ps + "; vm state=" + state.toString()); final String vmName = dm.getName(); // TODO : for XS/KVM (host-based resource), we require to remove @@ -2532,14 +2341,14 @@ private HashMap getHostVmStateReport(final Conne vmStates.put(vmName, new HostVmStateReportEntry(state, conn.getHostName())); } } catch (final LibvirtException e) { - LOGGER.warn("Unable to get vms", e); + logger.warn("Unable to get vms", e); } finally { try { if (dm != null) { dm.free(); } } catch (final LibvirtException e) { - LOGGER.trace("Ignoring libvirt error.", e); + logger.trace("Ignoring libvirt error.", e); } } } @@ -2552,7 +2361,7 @@ private HashMap getHostVmStateReport(final Conne final DomainState ps = dm.getInfo().state; final PowerState state = convertToPowerState(ps); final String vmName = dm.getName(); - LOGGER.trace("VM " + vmName + ": powerstate = " + ps + "; vm state=" + state.toString()); + logger.trace("VM " + vmName + ": powerstate = " + ps + "; vm state=" + state.toString()); // TODO : for XS/KVM (host-based resource), we require to remove // VM completely from host, for some reason, KVM seems to still keep @@ -2562,14 +2371,14 @@ private HashMap getHostVmStateReport(final Conne vmStates.put(vmName, new HostVmStateReportEntry(state, conn.getHostName())); } } catch (final LibvirtException e) { - LOGGER.warn("Unable to get vms", e); + logger.warn("Unable to get vms", e); } finally { try { if (dm != null) { dm.free(); } } catch (final LibvirtException e) { - LOGGER.trace("Ignoring libvirt error.", e); + logger.trace("Ignoring libvirt error.", e); } } } @@ -2679,7 +2488,7 @@ protected List getHostInfo() { } } } catch (final LibvirtException e) { - LOGGER.trace("Ignoring libvirt error.", e); + logger.trace("Ignoring libvirt error.", e); } if (isSnapshotSupported()) { @@ -2689,17 +2498,21 @@ protected List getHostInfo() { info.add((int) cpus); info.add(speed); // Report system's RAM as actual RAM minus host OS reserved RAM + final long dom0MinMem = getHostReservedMemMb(); ram = ram - dom0MinMem; info.add(ram); info.add(cap); info.add(dom0MinMem); info.add(cpuSockets); - LOGGER.debug("cpus=" + cpus + ", speed=" + speed + ", ram=" + ram + ", _dom0MinMem=" + dom0MinMem - + ", cpu sockets=" + cpuSockets); + logger.debug("cpus=" + cpus + ", speed=" + speed + ", ram=" + ram + ", _dom0MinMem=" + dom0MinMem + ", cpu sockets=" + cpuSockets); return info; } + private long getHostReservedMemMb() { + return libvirtComputingResourceProperties.getHostReservedMemMb(); + } + protected List getAllVmNames(final Connect conn) { final ArrayList la = new ArrayList<>(); try { @@ -2708,14 +2521,14 @@ protected List getAllVmNames(final Connect conn) { la.add(name); } } catch (final LibvirtException e) { - LOGGER.warn("Failed to list Defined domains", e); + logger.warn("Failed to list Defined domains", e); } int[] ids = null; try { ids = conn.listDomains(); } catch (final LibvirtException e) { - LOGGER.warn("Failed to list domains", e); + logger.warn("Failed to list domains", e); return la; } @@ -2725,14 +2538,14 @@ protected List getAllVmNames(final Connect conn) { dm = conn.domainLookupByID(id); la.add(dm.getName()); } catch (final LibvirtException e) { - LOGGER.warn("Unable to get vms", e); + logger.warn("Unable to get vms", e); } finally { try { if (dm != null) { dm.free(); } } catch (final LibvirtException e) { - LOGGER.trace("Ignoring libvirt error.", e); + logger.trace("Ignoring libvirt error.", e); } } } @@ -2745,7 +2558,7 @@ protected static long getCpuSpeed(final NodeInfo nodeInfo) { "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq")) { return Long.parseLong(IOUtils.toString(reader).trim()) / 1000; } catch (IOException | NumberFormatException e) { - LOGGER.warn("Could not read cpuinfo_max_freq"); + logger.warn("Could not read cpuinfo_max_freq"); return nodeInfo.mhz; } } @@ -2765,24 +2578,24 @@ public String rebootVm(final Connect conn, final String vmName) { if (nic.getNetType() == GuestNetType.BRIDGE && nic.getBrName().startsWith("cloudVirBr")) { try { final int vnetId = Integer.parseInt(nic.getBrName().replaceFirst("cloudVirBr", "")); - final String pifName = getPif(guestBridgeName); + final String pifName = getPif(getGuestBridgeName()); final String newBrName = "br" + pifName + "-" + vnetId; vmDef = vmDef.replaceAll("'" + nic.getBrName() + "'", "'" + newBrName + "'"); - LOGGER.debug("VM bridge name is changed from " + nic.getBrName() + " to " + newBrName); + logger.debug("VM bridge name is changed from " + nic.getBrName() + " to " + newBrName); } catch (final NumberFormatException e) { continue; } } } - LOGGER.debug(vmDef); + logger.debug(vmDef); msg = stopVm(conn, vmName); msg = startVm(conn, vmName, vmDef); return null; } catch (final LibvirtException e) { - LOGGER.warn("Failed to create vm", e); + logger.warn("Failed to create vm", e); msg = e.getMessage(); } catch (final InternalErrorException e) { - LOGGER.warn("Failed to create vm", e); + logger.warn("Failed to create vm", e); msg = e.getMessage(); } finally { try { @@ -2790,7 +2603,7 @@ public String rebootVm(final Connect conn, final String vmName) { dm.free(); } } catch (final LibvirtException e) { - LOGGER.trace("Ignoring libvirt error.", e); + logger.trace("Ignoring libvirt error.", e); } } @@ -2801,7 +2614,7 @@ public String stopVm(final Connect conn, final String vmName) { DomainState state = null; Domain dm = null; - LOGGER.debug("Try to stop the vm at first"); + logger.debug("Try to stop the vm at first"); String ret = stopVm(conn, vmName, false); if (ret == Script.ERR_TIMEOUT) { ret = stopVm(conn, vmName, true); @@ -2817,25 +2630,25 @@ public String stopVm(final Connect conn, final String vmName) { state = dm.getInfo().state; break; } catch (final LibvirtException e) { - LOGGER.debug("Failed to get vm status:" + e.getMessage()); + logger.debug("Failed to get vm status:" + e.getMessage()); } finally { try { if (dm != null) { dm.free(); } } catch (final LibvirtException l) { - LOGGER.trace("Ignoring libvirt error.", l); + logger.trace("Ignoring libvirt error.", l); } } } if (state == null) { - LOGGER.debug("Can't get vm's status, assume it's dead already"); + logger.debug("Can't get vm's status, assume it's dead already"); return null; } if (state != DomainState.VIR_DOMAIN_SHUTOFF) { - LOGGER.debug("Try to destroy the vm"); + logger.debug("Try to destroy the vm"); ret = stopVm(conn, vmName, true); if (ret != null) { return ret; @@ -2897,7 +2710,7 @@ protected String stopVm(final Connect conn, final String vmName, final boolean f return null; } dm.shutdown(); - int retry = stopTimeout / 2000; + int retry = getStopScriptTimeout() / 2000; /* * Wait for the domain gets into shutoff state. When it does the dm object will no longer work, so we need to * catch it. @@ -2910,13 +2723,13 @@ protected String stopVm(final Connect conn, final String vmName, final boolean f } catch (final LibvirtException e) { final String error = e.toString(); if (error.contains("Domain not found")) { - LOGGER.debug("successfully shut down vm " + vmName); + logger.debug("successfully shut down vm " + vmName); } else { - LOGGER.debug("Error in waiting for vm shutdown:" + error); + logger.debug("Error in waiting for vm shutdown:" + error); } } if (retry < 0) { - LOGGER.warn("Timed out waiting for domain " + vmName + " to shutdown gracefully"); + logger.warn("Timed out waiting for domain " + vmName + " to shutdown gracefully"); return Script.ERR_TIMEOUT; } else { if (persist == 1) { @@ -2926,13 +2739,13 @@ protected String stopVm(final Connect conn, final String vmName, final boolean f } } catch (final LibvirtException e) { if (e.getMessage().contains("Domain not found")) { - LOGGER.debug("VM " + vmName + " doesn't exist, no need to stop it"); + logger.debug("VM " + vmName + " doesn't exist, no need to stop it"); return null; } - LOGGER.debug("Failed to stop VM :" + vmName + " :", e); + logger.debug("Failed to stop VM :" + vmName + " :", e); return e.getMessage(); } catch (final InterruptedException ie) { - LOGGER.debug("Interrupted sleep"); + logger.debug("Interrupted sleep"); return ie.getMessage(); } finally { try { @@ -2940,13 +2753,17 @@ protected String stopVm(final Connect conn, final String vmName, final boolean f dm.free(); } } catch (final LibvirtException e) { - LOGGER.trace("Ignoring libvirt error.", e); + logger.trace("Ignoring libvirt error.", e); } } return null; } + private int getStopScriptTimeout() { + return libvirtComputingResourceProperties.getStopScriptTimeout(); + } + public Integer getVncPort(final Connect conn, final String vmName) throws LibvirtException { final LibvirtDomainXmlParser parser = new LibvirtDomainXmlParser(); Domain dm = null; @@ -2961,7 +2778,7 @@ public Integer getVncPort(final Connect conn, final String vmName) throws Libvir dm.free(); } } catch (final LibvirtException l) { - LOGGER.trace("Ignoring libvirt error.", l); + logger.trace("Ignoring libvirt error.", l); } } } @@ -3122,7 +2939,7 @@ public boolean destroyNetworkRulesForVm(final Connect conn, final String vmName) final InterfaceDef intf = intfs.get(0); vif = intf.getDevName(); } - final Script cmd = new Script(securityGroupPath, timeout, LOGGER); + final Script cmd = new Script(securityGroupPath, getScriptsTimeout(), logger); cmd.add("destroy_network_rules_for_vm"); cmd.add("--vmname", vmName); if (vif != null) { @@ -3150,7 +2967,7 @@ public boolean defaultNetworkRules(final Connect conn, final String vmName, fina final String brname = intf.getBrName(); final String vif = intf.getDevName(); - final Script cmd = new Script(securityGroupPath, timeout, LOGGER); + final Script cmd = new Script(securityGroupPath, getScriptsTimeout(), logger); cmd.add("default_network_rules"); cmd.add("--vmname", vmName); cmd.add("--vmid", vmId.toString()); @@ -3183,7 +3000,7 @@ protected boolean post_default_network_rules(final Connect conn, final String vm final String brname = intf.getBrName(); final String vif = intf.getDevName(); - final Script cmd = new Script(securityGroupPath, timeout, LOGGER); + final Script cmd = new Script(securityGroupPath, getScriptsTimeout(), logger); cmd.add("post_default_network_rules"); cmd.add("--vmname", vmName); cmd.add("--vmid", vmId.toString()); @@ -3209,10 +3026,10 @@ public boolean configureDefaultNetworkRulesForSystemVm(final Connect conn, final return false; } - final Script cmd = new Script(securityGroupPath, timeout, LOGGER); + final Script cmd = new Script(securityGroupPath, getScriptsTimeout(), logger); cmd.add("default_network_rules_systemvm"); cmd.add("--vmname", vmName); - cmd.add("--localbrname", linkLocalBridgeName); + cmd.add("--localbrname", getLinkLocalBridgeName()); final String result = cmd.execute(); if (result != null) { return false; @@ -3228,7 +3045,7 @@ public boolean addNetworkRules(final String vmName, final String vmId, final Str } final String newRules = rules.replace(" ", ";"); - final Script cmd = new Script(securityGroupPath, timeout, LOGGER); + final Script cmd = new Script(securityGroupPath, getScriptsTimeout(), logger); cmd.add("add_network_rules"); cmd.add("--vmname", vmName); cmd.add("--vmid", vmId); @@ -3256,7 +3073,7 @@ public boolean configureNetworkRulesVmSecondaryIp(final Connect conn, final Stri return false; } - final Script cmd = new Script(securityGroupPath, timeout, LOGGER); + final Script cmd = new Script(securityGroupPath, getScriptsTimeout(), logger); cmd.add("network_rules_vmSecondaryIp"); cmd.add("--vmname", vmName); cmd.add("--nicsecips", secIp); @@ -3273,7 +3090,7 @@ public boolean cleanupRules() { if (!canBridgeFirewall) { return false; } - final Script cmd = new Script(securityGroupPath, timeout, LOGGER); + final Script cmd = new Script(securityGroupPath, getScriptsTimeout(), logger); cmd.add("cleanup_rules"); final String result = cmd.execute(); if (result != null) { @@ -3283,7 +3100,7 @@ public boolean cleanupRules() { } private String executeBashScript(final String script) { - final Script command = new Script("/bin/bash", timeout, LOGGER); + final Script command = new Script("/bin/bash", getScriptsTimeout(), logger); command.add("-c"); command.add(script); return command.execute(); @@ -3298,7 +3115,7 @@ static double readDouble(final String nicName, final String fileName) { try { return Double.parseDouble(FileUtils.readFileToString(new File(path))); } catch (final IOException ioe) { - LOGGER.warn("Failed to read the " + fileName + " for " + nicName + " from " + path, ioe); + logger.warn("Failed to read the " + fileName + " for " + nicName + " from " + path, ioe); return 0.0; } } @@ -3307,8 +3124,8 @@ static double readDouble(final String nicName, final String fileName) { public void setName(final String name) { } - public HypervisorType getHypervisorType() { - return hypervisorType; + private HypervisorType getHypervisorType() { + return libvirtComputingResourceProperties.getHypervisorType(); } public String mapRbdDevice(final KvmPhysicalDisk disk) { @@ -3326,6 +3143,18 @@ public String mapRbdDevice(final KvmPhysicalDisk disk) { return device; } + public List getCpuFeatures() { + return libvirtComputingResourceProperties.getGuestCpuFeatures(); + } + + public String[] getIfNamePatterns() { + return ifNamePatterns; + } + + protected void setBridgeType(final BridgeType bridgeType) { + this.libvirtComputingResourceProperties.setNetworkBridgeType(bridgeType); + } + protected enum BridgeType { NATIVE, OPENVSWITCH } @@ -3340,14 +3169,14 @@ public String interpret(final BufferedReader reader) throws IOException { while ((line = reader.readLine()) != null) { final String[] toks = line.trim().split("="); if (toks.length < 2) { - LOGGER.warn("Failed to parse Script output: " + line); + logger.warn("Failed to parse Script output: " + line); } else { map.put(toks[0].trim(), toks[1].trim()); } numLines++; } if (numLines == 0) { - LOGGER.warn("KeyValueInterpreter: no output lines?"); + logger.warn("KeyValueInterpreter: no output lines?"); } return null; } @@ -3369,7 +3198,7 @@ private class VmStats { } public String getRuleLogsForVms() { - final Script cmd = new Script(securityGroupPath, timeout, LOGGER); + final Script cmd = new Script(securityGroupPath, getScriptsTimeout(), logger); cmd.add("get_rule_logs_for_vms"); final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); final String result = cmd.execute(parser); @@ -3383,7 +3212,7 @@ private HashMap> syncNetworkGroups(final long id) { final HashMap> states = new HashMap<>(); final String result = getRuleLogsForVms(); - LOGGER.trace("syncNetworkGroups: id=" + id + " got: " + result); + logger.trace("syncNetworkGroups: id=" + id + " got: " + result); final String[] rulelogs = result != null ? result.split(";") : new String[0]; for (final String rulesforvm : rulelogs) { final String[] log = rulesforvm.split(","); diff --git a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceProperties.java b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceProperties.java new file mode 100644 index 0000000000..44498b0e62 --- /dev/null +++ b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceProperties.java @@ -0,0 +1,570 @@ +package com.cloud.hypervisor.kvm.resource; + +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_CMDS_TIMEOUT; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_DOMR_SCRIPTS_DIR; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_HOST_RESERVED_MEM_MB; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_HYPERVISOR_SCRIPTS_DIR; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_HYPERVISOR_TYPE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_IPADDR_START; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_LOCAL_STORAGE_PATH; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_MOUNT_PATH; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_NETWORK_SCRIPTS_DIR; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_PRIVATE_BRIDGE_NAME; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_PRIVATE_MACADDR_START; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_PRIVATE_NETWORK_DEVICE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_PRIVATE_NETWORK_NAME; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_PUBLIC_NETWORK_DEVICE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_SCRIPTS_TIMEOUT; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_STOP_SCRIPT_TIMEOUT; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_STORAGE_SCRIPTS_DIR; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_SYSTEMVM_ISO_PATH; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_VM_MIGRATE_DOWNTIME; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_VM_MIGRATE_PAUSEAFTER; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_VM_MIGRATE_SPEED; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_VM_RNG_PATH; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.DEFAULT_VM_VIDEO_RAM; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.FORMAT_PRIVATE_BRIDGE_NAME; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.FORMAT_PRIVATE_NETWORK_NAME; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_CMDS_TIMEOUT; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_DOMR_SCRIPTS_DIR; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_GUEST_CPU_FEATURES; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_GUEST_CPU_MODE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_GUEST_CPU_MODEL; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_GUEST_NETWORK_DEVICE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_HOST_RESERVED_MEM_MB; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_HYPERVISOR_SCRIPTS_DIR; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_HYPERVISOR_TYPE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_HYPERVISOR_URI; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_KVMCLOCK_DISABLE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_KVM_SCRIPTS_DIR; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_LOCAL_STORAGE_PATH; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_LOCAL_STORAGE_UUID; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_MOUNT_PATH; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_NETWORK_BRIDGE_TYPE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_NETWORK_DIRECT_DEVICE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_NETWORK_DIRECT_SOURCE_MODE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_NETWORK_SCRIPTS_DIR; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_PRIVATE_BRIDGE_NAME; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_PRIVATE_IPADDR_START; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_PRIVATE_MACADDR_START; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_PRIVATE_NETWORK_DEVICE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_PRIVATE_NETWORK_NAME; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_PUBLIC_NETWORK_DEVICE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_SCRIPTS_TIMEOUT; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_STOP_SCRIPT_TIMEOUT; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_STORAGE_SCRIPTS_DIR; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_SYSTEMVM_ISO_PATH; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_VM_MEMBALLOON_DISABLE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_VM_MIGRATE_DOWNTIME; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_VM_MIGRATE_PAUSEAFTER; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_VM_MIGRATE_SPEED; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_VM_RNG_ENABLE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_VM_RNG_MODEL; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_VM_RNG_PATH; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_VM_VIDEO_HARDWARE; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_VM_VIDEO_RAM; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_VM_WATCHDOG_ACTION; +import static com.cloud.hypervisor.kvm.resource.LibvirtComputingResourceProperties.Constants.PROPERTY_KEY_VM_WATCHDOG_MODEL; +import static com.cloud.utils.CloudConstants.DEFAULT_HOST; +import static com.cloud.utils.CloudConstants.DEFAULT_POD; +import static com.cloud.utils.CloudConstants.DEFAULT_ZONE; +import static com.cloud.utils.CloudConstants.PROPERTY_KEY_CLUSTER; +import static com.cloud.utils.CloudConstants.PROPERTY_KEY_HOST; +import static com.cloud.utils.CloudConstants.PROPERTY_KEY_INSTANCE; +import static com.cloud.utils.CloudConstants.PROPERTY_KEY_POD; +import static com.cloud.utils.CloudConstants.PROPERTY_KEY_POOL; +import static com.cloud.utils.CloudConstants.PROPERTY_KEY_ZONE; +import static com.cloud.utils.PropertiesUtil.parse; +import static com.cloud.utils.PropertiesUtil.stringSplitDecomposer; + +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource.BridgeType; +import com.cloud.hypervisor.kvm.resource.LibvirtVmDef.RngDef.RngBackendModel; +import com.cloud.hypervisor.kvm.resource.LibvirtVmDef.WatchDogDef.WatchDogAction; +import com.cloud.hypervisor.kvm.resource.LibvirtVmDef.WatchDogDef.WatchDogModel; +import com.cloud.utils.PropertiesPojo; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +public class LibvirtComputingResourceProperties implements PropertiesPojo { + private String cluster; + private int cmdsTimeout = DEFAULT_CMDS_TIMEOUT; + private String domrScriptsDir = DEFAULT_DOMR_SCRIPTS_DIR; + private boolean developer = false; + private List guestCpuFeatures; + private String guestCpuModel; + private String guestCpuMode; + private String guestNetworkDevice; + private String host = DEFAULT_HOST; + private long hostReservedMemMb = DEFAULT_HOST_RESERVED_MEM_MB; + private String hypervisorScriptsDir = DEFAULT_HYPERVISOR_SCRIPTS_DIR; + private HypervisorType hypervisorType = DEFAULT_HYPERVISOR_TYPE; + private String hypervisorUri; + private String instance; + private String kvmScriptsDir; + private boolean kvmclockDisable; + private String localStoragePath = DEFAULT_LOCAL_STORAGE_PATH; + private String localStorageUuid; + private String mountPath = DEFAULT_MOUNT_PATH; + private String networkScriptsDir = DEFAULT_NETWORK_SCRIPTS_DIR; + private BridgeType networkBridgeType = BridgeType.NATIVE; + private String networkDirectSourceMode; + private String networkDirectDevice; + private String pool; + private String pod = DEFAULT_POD; + private String privateMacaddrStart = DEFAULT_PRIVATE_MACADDR_START; + private String privateIpaddrStart = DEFAULT_IPADDR_START; + private String privateBridgeName = DEFAULT_PRIVATE_BRIDGE_NAME; + private String publicNetworkDevice = DEFAULT_PUBLIC_NETWORK_DEVICE; + private String privateNetworkDevice = DEFAULT_PRIVATE_NETWORK_DEVICE; + private String privateNetworkName = DEFAULT_PRIVATE_NETWORK_NAME; + private String storageScriptsDir = DEFAULT_STORAGE_SCRIPTS_DIR; + private int scriptsTimeout = DEFAULT_SCRIPTS_TIMEOUT; + private int stopScriptTimeout = DEFAULT_STOP_SCRIPT_TIMEOUT; + private String systemvmIsoPath = DEFAULT_SYSTEMVM_ISO_PATH; + private boolean vmMemballoonDisable; + private String vmVideoHardware; + private int vmVideoRam = DEFAULT_VM_VIDEO_RAM; + private boolean vmRngEnable = false; + private RngBackendModel vmRngModel = RngBackendModel.RANDOM; + private String vmRngPath = DEFAULT_VM_RNG_PATH; + private WatchDogModel vmWatchdogModel = WatchDogModel.I6300ESB; + private WatchDogAction vmWatchdogAction = WatchDogAction.NONE; + private int vmMigrateDowntime = DEFAULT_VM_MIGRATE_DOWNTIME; + private int vmMigratePauseafter = DEFAULT_VM_MIGRATE_PAUSEAFTER; + private int vmMigrateSpeed = DEFAULT_VM_MIGRATE_SPEED; + private String zone = DEFAULT_ZONE; + + @Override + public void load(final Properties properties) { + cluster = parse(properties, PROPERTY_KEY_CLUSTER, cluster); + cmdsTimeout = parse(properties, PROPERTY_KEY_CMDS_TIMEOUT, cmdsTimeout); + domrScriptsDir = parse(properties, PROPERTY_KEY_DOMR_SCRIPTS_DIR, domrScriptsDir); + developer = parse(properties, PROPERTY_KEY_DOMR_SCRIPTS_DIR, developer); + guestCpuFeatures = parse(properties, PROPERTY_KEY_GUEST_CPU_FEATURES, guestCpuFeatures, stringSplitDecomposer(" ", String.class)); + guestCpuModel = parse(properties, PROPERTY_KEY_GUEST_CPU_MODEL, guestCpuModel); + guestCpuMode = parse(properties, PROPERTY_KEY_GUEST_CPU_MODE, guestCpuMode); + guestNetworkDevice = parse(properties, PROPERTY_KEY_GUEST_NETWORK_DEVICE, guestNetworkDevice); + host = parse(properties, PROPERTY_KEY_HOST, host); + hostReservedMemMb = parse(properties, PROPERTY_KEY_HOST_RESERVED_MEM_MB, hostReservedMemMb); + hypervisorScriptsDir = parse(properties, PROPERTY_KEY_HYPERVISOR_SCRIPTS_DIR, hypervisorScriptsDir); + hypervisorUri = parse(properties, PROPERTY_KEY_HYPERVISOR_URI, hypervisorUri); + instance = parse(properties, PROPERTY_KEY_INSTANCE, instance); + kvmScriptsDir = parse(properties, PROPERTY_KEY_KVM_SCRIPTS_DIR, kvmScriptsDir); + kvmclockDisable = parse(properties, PROPERTY_KEY_KVMCLOCK_DISABLE, kvmclockDisable); + localStoragePath = parse(properties, PROPERTY_KEY_LOCAL_STORAGE_PATH, localStoragePath); + localStorageUuid = parse(properties, PROPERTY_KEY_LOCAL_STORAGE_UUID, localStorageUuid); + mountPath = parse(properties, PROPERTY_KEY_MOUNT_PATH, mountPath); + networkScriptsDir = parse(properties, PROPERTY_KEY_NETWORK_SCRIPTS_DIR, networkScriptsDir); + networkDirectSourceMode = parse(properties, PROPERTY_KEY_NETWORK_DIRECT_SOURCE_MODE, networkDirectSourceMode); + networkDirectDevice = parse(properties, PROPERTY_KEY_NETWORK_DIRECT_DEVICE, networkDirectDevice); + pool = parse(properties, PROPERTY_KEY_POOL, pool); + pod = parse(properties, PROPERTY_KEY_POD, pod); + privateMacaddrStart = parse(properties, PROPERTY_KEY_PRIVATE_MACADDR_START, privateMacaddrStart); + privateIpaddrStart = parse(properties, PROPERTY_KEY_PRIVATE_IPADDR_START, privateIpaddrStart); + privateBridgeName = parse(properties, PROPERTY_KEY_PRIVATE_BRIDGE_NAME, privateBridgeName); + publicNetworkDevice = parse(properties, PROPERTY_KEY_PUBLIC_NETWORK_DEVICE, publicNetworkDevice); + privateNetworkDevice = parse(properties, PROPERTY_KEY_PRIVATE_NETWORK_DEVICE, privateNetworkDevice); + privateNetworkName = parse(properties, PROPERTY_KEY_PRIVATE_NETWORK_NAME, privateNetworkName); + storageScriptsDir = parse(properties, PROPERTY_KEY_STORAGE_SCRIPTS_DIR, storageScriptsDir); + scriptsTimeout = parse(properties, PROPERTY_KEY_SCRIPTS_TIMEOUT, scriptsTimeout); + stopScriptTimeout = parse(properties, PROPERTY_KEY_STOP_SCRIPT_TIMEOUT, stopScriptTimeout); + systemvmIsoPath = parse(properties, PROPERTY_KEY_SYSTEMVM_ISO_PATH, systemvmIsoPath); + vmMemballoonDisable = parse(properties, PROPERTY_KEY_VM_MEMBALLOON_DISABLE, vmMemballoonDisable); + vmVideoHardware = parse(properties, PROPERTY_KEY_VM_VIDEO_HARDWARE, vmVideoHardware); + vmVideoRam = parse(properties, PROPERTY_KEY_VM_VIDEO_RAM, vmVideoRam); + vmRngEnable = parse(properties, PROPERTY_KEY_VM_RNG_ENABLE, vmRngEnable); + vmRngPath = parse(properties, PROPERTY_KEY_VM_RNG_PATH, vmRngPath); + vmMigrateDowntime = parse(properties, PROPERTY_KEY_VM_MIGRATE_DOWNTIME, vmMigrateDowntime); + vmMigratePauseafter = parse(properties, PROPERTY_KEY_VM_MIGRATE_PAUSEAFTER, vmMigratePauseafter); + vmMigrateSpeed = parse(properties, PROPERTY_KEY_VM_MIGRATE_SPEED, vmMigrateSpeed); + zone = parse(properties, PROPERTY_KEY_ZONE, zone); + + hypervisorType = parse(properties, PROPERTY_KEY_HYPERVISOR_TYPE, hypervisorType, HypervisorType.class); + networkBridgeType = parse(properties, PROPERTY_KEY_NETWORK_BRIDGE_TYPE, networkBridgeType, BridgeType.class); + vmRngModel = parse(properties, PROPERTY_KEY_VM_RNG_MODEL, vmRngModel, RngBackendModel.class); + vmWatchdogModel = parse(properties, PROPERTY_KEY_VM_WATCHDOG_MODEL, vmWatchdogModel, WatchDogModel.class); + vmWatchdogAction = parse(properties, PROPERTY_KEY_VM_WATCHDOG_ACTION, vmWatchdogAction, WatchDogAction.class); + + validateValues(); + } + + private void validateValues() { + hypervisorType = hypervisorType == HypervisorType.None ? HypervisorType.KVM : hypervisorType; + hypervisorUri = hypervisorUri == null ? LibvirtConnection.getHypervisorUri(hypervisorType.toString()) : hypervisorUri; + privateBridgeName = developer ? String.format(FORMAT_PRIVATE_BRIDGE_NAME, instance) : privateBridgeName; + guestNetworkDevice = guestNetworkDevice == null ? privateNetworkDevice : guestNetworkDevice; + privateNetworkName = developer ? String.format(FORMAT_PRIVATE_NETWORK_NAME, instance) : privateNetworkName; + localStoragePath = new File(localStoragePath).getAbsolutePath(); + localStorageUuid = localStorageUuid == null ? UUID.randomUUID().toString() : localStorageUuid; + } + + @Override + public Map buildPropertiesMap() { + final HashMap propertiesMap = new HashMap<>(); + propertiesMap.put(PROPERTY_KEY_CLUSTER, cluster); + propertiesMap.put(PROPERTY_KEY_CMDS_TIMEOUT, cmdsTimeout); + propertiesMap.put(PROPERTY_KEY_DOMR_SCRIPTS_DIR, domrScriptsDir); + propertiesMap.put(PROPERTY_KEY_GUEST_CPU_FEATURES, guestCpuFeatures); + propertiesMap.put(PROPERTY_KEY_GUEST_CPU_MODEL, guestCpuModel); + propertiesMap.put(PROPERTY_KEY_GUEST_CPU_MODE, guestCpuMode); + propertiesMap.put(PROPERTY_KEY_GUEST_NETWORK_DEVICE, guestNetworkDevice); + propertiesMap.put(PROPERTY_KEY_HOST, host); + propertiesMap.put(PROPERTY_KEY_HOST_RESERVED_MEM_MB, hostReservedMemMb); + propertiesMap.put(PROPERTY_KEY_HYPERVISOR_SCRIPTS_DIR, hypervisorScriptsDir); + propertiesMap.put(PROPERTY_KEY_HYPERVISOR_TYPE, hypervisorType); + propertiesMap.put(PROPERTY_KEY_HYPERVISOR_URI, hypervisorUri); + propertiesMap.put(PROPERTY_KEY_INSTANCE, instance); + propertiesMap.put(PROPERTY_KEY_KVM_SCRIPTS_DIR, kvmScriptsDir); + propertiesMap.put(PROPERTY_KEY_KVMCLOCK_DISABLE, kvmclockDisable); + propertiesMap.put(PROPERTY_KEY_LOCAL_STORAGE_PATH, localStoragePath); + propertiesMap.put(PROPERTY_KEY_LOCAL_STORAGE_UUID, localStorageUuid); + propertiesMap.put(PROPERTY_KEY_MOUNT_PATH, mountPath); + propertiesMap.put(PROPERTY_KEY_NETWORK_SCRIPTS_DIR, networkScriptsDir); + propertiesMap.put(PROPERTY_KEY_NETWORK_BRIDGE_TYPE, networkBridgeType); + propertiesMap.put(PROPERTY_KEY_NETWORK_DIRECT_SOURCE_MODE, networkDirectSourceMode); + propertiesMap.put(PROPERTY_KEY_NETWORK_DIRECT_DEVICE, networkDirectDevice); + propertiesMap.put(PROPERTY_KEY_POOL, pool); + propertiesMap.put(PROPERTY_KEY_POD, pod); + propertiesMap.put(PROPERTY_KEY_PRIVATE_MACADDR_START, privateMacaddrStart); + propertiesMap.put(PROPERTY_KEY_PRIVATE_IPADDR_START, privateIpaddrStart); + propertiesMap.put(PROPERTY_KEY_PRIVATE_BRIDGE_NAME, privateBridgeName); + propertiesMap.put(PROPERTY_KEY_PUBLIC_NETWORK_DEVICE, publicNetworkDevice); + propertiesMap.put(PROPERTY_KEY_PRIVATE_NETWORK_DEVICE, privateNetworkDevice); + propertiesMap.put(PROPERTY_KEY_PRIVATE_NETWORK_NAME, privateNetworkName); + propertiesMap.put(PROPERTY_KEY_STORAGE_SCRIPTS_DIR, storageScriptsDir); + propertiesMap.put(PROPERTY_KEY_SCRIPTS_TIMEOUT, scriptsTimeout); + propertiesMap.put(PROPERTY_KEY_STOP_SCRIPT_TIMEOUT, stopScriptTimeout); + propertiesMap.put(PROPERTY_KEY_SYSTEMVM_ISO_PATH, systemvmIsoPath); + propertiesMap.put(PROPERTY_KEY_VM_MEMBALLOON_DISABLE, vmMemballoonDisable); + propertiesMap.put(PROPERTY_KEY_VM_VIDEO_HARDWARE, vmVideoHardware); + propertiesMap.put(PROPERTY_KEY_VM_VIDEO_RAM, vmVideoRam); + propertiesMap.put(PROPERTY_KEY_VM_RNG_ENABLE, vmRngEnable); + propertiesMap.put(PROPERTY_KEY_VM_RNG_MODEL, vmRngModel); + propertiesMap.put(PROPERTY_KEY_VM_RNG_PATH, vmRngPath); + propertiesMap.put(PROPERTY_KEY_VM_WATCHDOG_MODEL, vmWatchdogModel); + propertiesMap.put(PROPERTY_KEY_VM_WATCHDOG_ACTION, vmWatchdogAction); + propertiesMap.put(PROPERTY_KEY_VM_MIGRATE_DOWNTIME, vmMigrateDowntime); + propertiesMap.put(PROPERTY_KEY_VM_MIGRATE_PAUSEAFTER, vmMigratePauseafter); + propertiesMap.put(PROPERTY_KEY_VM_MIGRATE_SPEED, vmMigrateSpeed); + propertiesMap.put(PROPERTY_KEY_ZONE, zone); + return propertiesMap; + } + + public String getCluster() { + return cluster; + } + + public int getCmdsTimeout() { + return cmdsTimeout * 1000; + } + + public String getDomrScriptsDir() { + return domrScriptsDir; + } + + public String getGuestCpuModel() { + return guestCpuModel; + } + + public String getGuestCpuMode() { + return guestCpuMode; + } + + public String getGuestNetworkDevice() { + return guestNetworkDevice; + } + + public String getHost() { + return host; + } + + public long getHostReservedMemMb() { + return hostReservedMemMb * 1024 * 1024L; + } + + public String getHypervisorScriptsDir() { + return hypervisorScriptsDir; + } + + public HypervisorType getHypervisorType() { + return hypervisorType; + } + + public String getHypervisorUri() { + return hypervisorUri; + } + + public String getKvmScriptsDir() { + return kvmScriptsDir; + } + + public boolean isKvmclockDisable() { + return kvmclockDisable; + } + + public String getLocalStoragePath() { + return localStoragePath; + } + + public String getLocalStorageUuid() { + return localStorageUuid; + } + + public String getMountPath() { + return mountPath; + } + + public String getNetworkScriptsDir() { + return networkScriptsDir; + } + + public BridgeType getNetworkBridgeType() { + return networkBridgeType; + } + + public String getNetworkDirectSourceMode() { + return networkDirectSourceMode; + } + + public String getNetworkDirectDevice() { + return networkDirectDevice; + } + + public String getPod() { + return pod; + } + + public String getPrivateMacaddrStart() { + return privateMacaddrStart; + } + + public String getPrivateIpaddrStart() { + return privateIpaddrStart; + } + + public String getPrivateBridgeName() { + return privateBridgeName; + } + + public String getPublicNetworkDevice() { + return publicNetworkDevice; + } + + public String getPrivateNetworkDevice() { + return privateNetworkDevice; + } + + public String getPrivateNetworkName() { + return privateNetworkName; + } + + public String getStorageScriptsDir() { + return storageScriptsDir; + } + + public int getScriptsTimeout() { + return scriptsTimeout * 1000; + } + + public int getStopScriptTimeout() { + return stopScriptTimeout * 1000; + } + + public String getSystemvmIsoPath() { + return systemvmIsoPath; + } + + public boolean getVmMemballoonDisable() { + return vmMemballoonDisable; + } + + public String getVmVideoHardware() { + return vmVideoHardware; + } + + public int getVmVideoRam() { + return vmVideoRam; + } + + public boolean getVmRngEnable() { + return vmRngEnable; + } + + public RngBackendModel getVmRngModel() { + return vmRngModel; + } + + public String getVmRngPath() { + return vmRngPath; + } + + public WatchDogModel getVmWatchdogModel() { + return vmWatchdogModel; + } + + public WatchDogAction getVmWatchdogAction() { + return vmWatchdogAction; + } + + public int getVmMigrateDowntime() { + return vmMigrateDowntime; + } + + public int getVmMigratePauseafter() { + return vmMigratePauseafter; + } + + public int getVmMigrateSpeed() { + return vmMigrateSpeed; + } + + public List getGuestCpuFeatures() { + return guestCpuFeatures; + } + + public String getInstance() { + return instance; + } + + public String getPool() { + return pool; + } + + public boolean isVmMemballoonDisable() { + return vmMemballoonDisable; + } + + public boolean isVmRngEnable() { + return vmRngEnable; + } + + public String getZone() { + return zone; + } + + public boolean isDeveloper() { + return developer; + } + + public boolean hasGuestCpuMode() { + return guestCpuMode != null; + } + + public void unsetGuestCpuMode() { + guestCpuMode = ""; + } + + public void unsetGuestCpuModel() { + guestCpuModel = ""; + } + + public void setVmMigrateSpeed(final int vmMigrateSpeed) { + this.vmMigrateSpeed = vmMigrateSpeed; + } + + public void setNetworkBridgeType(final BridgeType bridgeType) { + this.networkBridgeType = bridgeType; + } + + public static class Constants { + public static final String BRIDGE_LINKLOCAL = "linklocal"; + public static final String BRIDGE_PUBLIC = "public"; + public static final String BRIDGE_PRIVATE = "private"; + public static final String BRIDGE_GUEST = "guest"; + + public static final String PROPERTY_KEY_DOMR_SCRIPTS_DIR = "domr.scripts.dir"; + public static final String PROPERTY_KEY_HYPERVISOR_SCRIPTS_DIR = "hypervisor.scripts.dir"; + public static final String PROPERTY_KEY_KVM_SCRIPTS_DIR = "kvm.scripts.dir"; + public static final String PROPERTY_KEY_NETWORK_SCRIPTS_DIR = "network.scripts.dir"; + public static final String PROPERTY_KEY_STORAGE_SCRIPTS_DIR = "storage.scripts.dir"; + public static final String PROPERTY_KEY_NETWORK_BRIDGE_TYPE = "network.bridge.type"; + public static final String PROPERTY_KEY_HYPERVISOR_TYPE = "hypervisor.type"; + public static final String PROPERTY_KEY_HYPERVISOR_URI = "hypervisor.uri"; + public static final String PROPERTY_KEY_NETWORK_DIRECT_SOURCE_MODE = "network.direct.source.mode"; + public static final String PROPERTY_KEY_NETWORK_DIRECT_DEVICE = "network.direct.device"; + public static final String PROPERTY_KEY_PRIVATE_MACADDR_START = "private.macaddr.start"; + public static final String PROPERTY_KEY_PRIVATE_IPADDR_START = "private.ipaddr.start"; + public static final String PROPERTY_KEY_PRIVATE_BRIDGE_NAME = "private.bridge.name"; + public static final String PROPERTY_KEY_PUBLIC_NETWORK_DEVICE = "public.network.device"; + public static final String PROPERTY_KEY_PRIVATE_NETWORK_DEVICE = "private.network.device"; + public static final String PROPERTY_KEY_GUEST_NETWORK_DEVICE = "guest.network.device"; + public static final String PROPERTY_KEY_PRIVATE_NETWORK_NAME = "private.network.name"; + public static final String PROPERTY_KEY_LOCAL_STORAGE_PATH = "local.storage.path"; + public static final String PROPERTY_KEY_LOCAL_STORAGE_UUID = "local.storage.uuid"; + public static final String PROPERTY_KEY_SCRIPTS_TIMEOUT = "scripts.timeout"; + public static final String PROPERTY_KEY_STOP_SCRIPT_TIMEOUT = "stop.script.timeout"; + public static final String PROPERTY_KEY_CMDS_TIMEOUT = "cmds.timeout"; + public static final String PROPERTY_KEY_VM_MEMBALLOON_DISABLE = "vm.memballoon.disable"; + public static final String PROPERTY_KEY_VM_VIDEO_HARDWARE = "vm.video.hardware"; + public static final String PROPERTY_KEY_VM_VIDEO_RAM = "vm.video.ram"; + public static final String PROPERTY_KEY_HOST_RESERVED_MEM_MB = "host.reserved.mem.mb"; + public static final String PROPERTY_KEY_KVMCLOCK_DISABLE = "kvmclock.disable"; + public static final String PROPERTY_KEY_VM_RNG_ENABLE = "vm.rng.enable"; + public static final String PROPERTY_KEY_VM_RNG_MODEL = "vm.rng.model"; + public static final String PROPERTY_KEY_VM_RNG_PATH = "vm.rng.path"; + public static final String PROPERTY_KEY_VM_WATCHDOG_MODEL = "vm.watchdog.model"; + public static final String PROPERTY_KEY_VM_WATCHDOG_ACTION = "vm.watchdog.action"; + public static final String PROPERTY_KEY_GUEST_CPU_FEATURES = "guest.cpu.features"; + public static final String PROPERTY_KEY_GUEST_CPU_MODEL = "guest.cpu.model"; + public static final String PROPERTY_KEY_GUEST_CPU_MODE = "guest.cpu.mode"; + public static final String PROPERTY_KEY_SYSTEMVM_ISO_PATH = "systemvm.iso.path"; + public static final String PROPERTY_KEY_MOUNT_PATH = "mount.path"; + public static final String PROPERTY_KEY_VM_MIGRATE_DOWNTIME = "vm.migrate.downtime"; + public static final String PROPERTY_KEY_VM_MIGRATE_PAUSEAFTER = "vm.migrate.pauseafter"; + public static final String PROPERTY_KEY_VM_MIGRATE_SPEED = "vm.migrate.speed"; + + public static final int DEFAULT_CMDS_TIMEOUT = 7200; + public static final String DEFAULT_DOMR_SCRIPTS_DIR = "scripts/network/domr"; + public static final long DEFAULT_HOST_RESERVED_MEM_MB = 1047L; + public static final String DEFAULT_HYPERVISOR_SCRIPTS_DIR = "scripts/vm/hypervisor/kvm"; + public static final String DEFAULT_IPADDR_START = "192.168.166.128"; + public static final HypervisorType DEFAULT_HYPERVISOR_TYPE = HypervisorType.KVM; + public static final String DEFAULT_LOCAL_STORAGE_PATH = "/var/lib/libvirt/images/"; + public static final String DEFAULT_NETWORK_SCRIPTS_DIR = "scripts/vm/network/vnet"; + public static final String DEFAULT_PRIVATE_MACADDR_START = "00:16:3e:77:e2:a0"; + public static final String DEFAULT_PRIVATE_BRIDGE_NAME = "cloud0"; + public static final String DEFAULT_PUBLIC_NETWORK_DEVICE = "cloudbr0"; + public static final String DEFAULT_PRIVATE_NETWORK_DEVICE = "cloudbr1"; + public static final String DEFAULT_PRIVATE_NETWORK_NAME = "cloud-private"; + public static final int DEFAULT_SCRIPTS_TIMEOUT = 30 * 60; + public static final int DEFAULT_STOP_SCRIPT_TIMEOUT = 120; + public static final String DEFAULT_STORAGE_SCRIPTS_DIR = "scripts/storage/qcow2"; + public static final int DEFAULT_VM_VIDEO_RAM = 0; + public static final String DEFAULT_SYSTEMVM_ISO_PATH = "/usr/share/cosmic-common/vms/systemvm.iso"; + public static final String DEFAULT_MOUNT_PATH = "/mnt"; + public static final int DEFAULT_VM_MIGRATE_DOWNTIME = -1; + public static final int DEFAULT_VM_MIGRATE_PAUSEAFTER = -1; + public static final int DEFAULT_VM_MIGRATE_SPEED = -1; + + public static final String DEFAULT_VM_RNG_PATH = "/dev/random"; + public static final String SCRIPT_MODIFY_VLAN = "modifyvlan.sh"; + public static final String SCRIPT_VERSIONS = "versions.sh"; + public static final String SCRIPT_PATCH_VIA_SOCKET = "patchviasocket.pl"; + public static final String SCRIPT_KVM_HEART_BEAT = "kvmheartbeat.sh"; + public static final String SCRIPT_CREATE_VM = "createvm.sh"; + public static final String SCRIPT_MANAGE_SNAPSHOT = "managesnapshot.sh"; + public static final String SCRIPT_RESIZE_VOLUME = "resizevolume.sh"; + public static final String SCRIPT_CREATE_TEMPLATE = "createtmplt.sh"; + public static final String SCRIPT_SECURITY_GROUP = "security_group.py"; + public static final String SCRIPT_OVS_TUNNEL = "ovstunnel.py"; + public static final String SCRIPT_ROUTER_PROXY = "router_proxy.sh"; + public static final String SCRIPT_OVS_PVLAN_DHCP_HOST = "ovs-pvlan-dhcp-host.sh"; + public static final String SCRIPT_OVS_PVLAN_VM = "ovs-pvlan-vm.sh"; + public static final String SCRIPT_PING_TEST = "pingtest.sh"; + public static final String SCRIPT_LOCAL_GATEWAY = "ip route |grep default|awk '{print $3}'"; + public static final String SCRIPT_UNAME = "uname -r"; + + public static final String FORMAT_NETWORK_SPEED = "ethtool %s |grep Speed | cut -d \\ -f 2"; + public static final String FORMAT_PRIVATE_BRIDGE_NAME = "cloud-%s-0"; + public static final String FORMAT_PRIVATE_NETWORK_NAME = "cloud-%s-private"; + + public static final String PATH_PATCH_DIR = "/patch/"; + public static final String PATH_SCRIPTS_NETWORK_DOMR = "scripts/network/domr/"; + } +} diff --git a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java index 60ea7895bd..4d95edcb1f 100644 --- a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java +++ b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java @@ -4,7 +4,6 @@ import com.cloud.exception.InternalErrorException; import com.cloud.hypervisor.kvm.resource.LibvirtVmDef.InterfaceDef; import com.cloud.network.Networks; -import com.cloud.utils.NumbersUtil; import com.cloud.utils.net.NetUtils; import com.cloud.utils.script.OutputInterpreter; import com.cloud.utils.script.Script; @@ -31,8 +30,7 @@ public void configure(final Map params) throws ConfigurationExce networkScriptsDir = "scripts/vm/network/vnet"; } - final String value = (String) params.get("scripts.timeout"); - timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000; + timeout = ((Integer) params.get("scripts.timeout")) * 1000; createControlNetwork(bridges.get("linklocal")); } diff --git a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java index 11ed276bc1..b1594fc313 100644 --- a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java +++ b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java @@ -35,7 +35,7 @@ public Answer execute(final ModifySshKeysCommand command, final LibvirtComputing String result = null; if (!sshKeysDir.exists()) { // Change permissions for the 700 - final Script script = new Script("mkdir", libvirtComputingResource.getTimeout(), s_logger); + final Script script = new Script("mkdir", libvirtComputingResource.getScriptsTimeout(), s_logger); script.add("-m", "700"); script.add(sshkeyspath); script.execute(); @@ -91,7 +91,7 @@ public Answer execute(final ModifySshKeysCommand command, final LibvirtComputing result = "Write file " + sshprvkeypath + ":" + e.toString(); s_logger.debug(result); } - final Script script = new Script("chmod", libvirtComputingResource.getTimeout(), s_logger); + final Script script = new Script("chmod", libvirtComputingResource.getScriptsTimeout(), s_logger); script.add("600", sshprvkeypath); script.execute(); } diff --git a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPvlanSetupCommandWrapper.java b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPvlanSetupCommandWrapper.java index ad026b5a40..e69eca5db1 100644 --- a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPvlanSetupCommandWrapper.java +++ b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPvlanSetupCommandWrapper.java @@ -41,7 +41,7 @@ public Answer execute(final PvlanSetupCommand command, final LibvirtComputingRes String result = null; try { final String guestBridgeName = libvirtComputingResource.getGuestBridgeName(); - final int timeout = libvirtComputingResource.getTimeout(); + final int timeout = libvirtComputingResource.getScriptsTimeout(); if (command.getType() == PvlanSetupCommand.Type.DHCP) { final String ovsPvlanDhcpHostPath = libvirtComputingResource.getOvsPvlanDhcpHostPath(); diff --git a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java index f508260a56..09e79a345e 100644 --- a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java +++ b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java @@ -106,19 +106,19 @@ public Answer execute(final StartCommand command, final LibvirtComputingResource } catch (final LibvirtException e) { s_logger.warn("LibvirtException ", e); if (conn != null) { - libvirtComputingResource.handleVmStartFailure(conn, vmName, vm); + libvirtComputingResource.handleVmStartFailure(conn, vm); } return new StartAnswer(command, e.getMessage()); } catch (final InternalErrorException e) { s_logger.warn("InternalErrorException ", e); if (conn != null) { - libvirtComputingResource.handleVmStartFailure(conn, vmName, vm); + libvirtComputingResource.handleVmStartFailure(conn, vm); } return new StartAnswer(command, e.getMessage()); } catch (final URISyntaxException e) { s_logger.warn("URISyntaxException ", e); if (conn != null) { - libvirtComputingResource.handleVmStartFailure(conn, vmName, vm); + libvirtComputingResource.handleVmStartFailure(conn, vm); } return new StartAnswer(command, e.getMessage()); } finally { diff --git a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KvmStorageProcessor.java b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KvmStorageProcessor.java index c1cfd1adc4..083fcf29ac 100644 --- a/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KvmStorageProcessor.java +++ b/cosmic-core/plugins/hypervisor/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KvmStorageProcessor.java @@ -25,7 +25,6 @@ import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.QCOW2Processor; import com.cloud.storage.template.TemplateLocation; -import com.cloud.utils.NumbersUtil; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; import com.cloud.utils.storage.S3.S3Utils; @@ -116,8 +115,7 @@ public boolean configure(final String name, final Map params) th throw new ConfigurationException("Unable to find the managesnapshot.sh"); } - final String value = (String) params.get("cmds.timeout"); - cmdsTimeout = NumbersUtil.parseInt(value, 7200) * 1000; + cmdsTimeout = ((Integer) params.get("cmds.timeout")) * 1000; return true; } diff --git a/cosmic-core/plugins/hypervisor/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java b/cosmic-core/plugins/hypervisor/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java index 4dc1a30677..2d676f724a 100644 --- a/cosmic-core/plugins/hypervisor/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java +++ b/cosmic-core/plugins/hypervisor/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java @@ -1570,7 +1570,7 @@ public void testModifySshKeysCommand() { when(libvirtUtilitiesHelper.retrieveSshPubKeyPath()).thenReturn("/path/pub/keys"); when(libvirtUtilitiesHelper.retrieveSshPrvKeyPath()).thenReturn("/path/pvt/keys"); - when(libvirtComputingResource.getTimeout()).thenReturn(0); + when(libvirtComputingResource.getScriptsTimeout()).thenReturn(0); final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); assertNotNull(wrapper); @@ -1578,7 +1578,7 @@ public void testModifySshKeysCommand() { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertFalse(answer.getResult()); - verify(libvirtComputingResource, times(1)).getTimeout(); + verify(libvirtComputingResource, times(1)).getScriptsTimeout(); } @Test @@ -3889,7 +3889,7 @@ public void testPvlanSetupCommandDhcpAdd() { when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName); final int timeout = 0; - when(libvirtComputingResource.getTimeout()).thenReturn(timeout); + when(libvirtComputingResource.getScriptsTimeout()).thenReturn(timeout); final String ovsPvlanDhcpHostPath = "/pvlan"; when(libvirtComputingResource.getOvsPvlanDhcpHostPath()).thenReturn(ovsPvlanDhcpHostPath); when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); @@ -3931,7 +3931,7 @@ public void testPvlanSetupCommandVm() { final String guestBridgeName = "br0"; when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName); final int timeout = 0; - when(libvirtComputingResource.getTimeout()).thenReturn(timeout); + when(libvirtComputingResource.getScriptsTimeout()).thenReturn(timeout); final String ovsPvlanVmPath = "/pvlan"; when(libvirtComputingResource.getOvsPvlanVmPath()).thenReturn(ovsPvlanVmPath); @@ -3960,7 +3960,7 @@ public void testPvlanSetupCommandDhcpException() { when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName); final int timeout = 0; - when(libvirtComputingResource.getTimeout()).thenReturn(timeout); + when(libvirtComputingResource.getScriptsTimeout()).thenReturn(timeout); final String ovsPvlanDhcpHostPath = "/pvlan"; when(libvirtComputingResource.getOvsPvlanDhcpHostPath()).thenReturn(ovsPvlanDhcpHostPath); when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); @@ -4002,7 +4002,7 @@ public void testPvlanSetupCommandDhcpDelete() { when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName); final int timeout = 0; - when(libvirtComputingResource.getTimeout()).thenReturn(timeout); + when(libvirtComputingResource.getScriptsTimeout()).thenReturn(timeout); final String ovsPvlanDhcpHostPath = "/pvlan"; when(libvirtComputingResource.getOvsPvlanDhcpHostPath()).thenReturn(ovsPvlanDhcpHostPath); when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); @@ -4624,12 +4624,11 @@ public void testIsInterface() { final LibvirtComputingResource lvcr = new LibvirtComputingResource(); assertFalse(lvcr.isInterface("bla")); assertTrue(lvcr.isInterface("p99p00")); - for (final String ifNamePattern : lvcr.ifNamePatterns) { + for (final String ifNamePattern : lvcr.getIfNamePatterns()) { // excluding regexps as "\\\\d+" won't replace with String.replaceAll(String,String); if (!ifNamePattern.contains("\\")) { final String ifName = ifNamePattern.replaceFirst("\\^", "") + "0"; - assertTrue("The pattern '" + ifNamePattern + "' is expected to be valid for interface " + ifName, - lvcr.isInterface(ifName)); + assertTrue("The pattern '" + ifNamePattern + "' is expected to be valid for interface " + ifName, lvcr.isInterface(ifName)); } } } diff --git a/cosmic-core/plugins/hypervisor/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVifDriverTest.java b/cosmic-core/plugins/hypervisor/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVifDriverTest.java index c9f46392a8..26ec0003f8 100644 --- a/cosmic-core/plugins/hypervisor/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVifDriverTest.java +++ b/cosmic-core/plugins/hypervisor/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVifDriverTest.java @@ -62,11 +62,11 @@ public void testDefaults() throws ConfigurationException { // map to the default vif driver for the bridge type final Map params = new HashMap<>(); - res.bridgeType = BridgeType.NATIVE; + res.setBridgeType(BridgeType.NATIVE); configure(params); checkAllSame(bridgeVifDriver); - res.bridgeType = BridgeType.OPENVSWITCH; + res.setBridgeType(BridgeType.OPENVSWITCH); configure(params); checkAllSame(ovsVifDriver); } @@ -102,13 +102,13 @@ public void testDefaultsWhenExplicitlySet() throws ConfigurationException { // Switch res' bridge type for test purposes params.put(LibVirtVifDriver, LibvirtComputingResource.DEFAULT_BRIDGE_VIF_DRIVER_CLASS); - res.bridgeType = BridgeType.NATIVE; + res.setBridgeType(BridgeType.NATIVE); configure(params); checkAllSame(bridgeVifDriver); params.clear(); params.put(LibVirtVifDriver, LibvirtComputingResource.DEFAULT_OVS_VIF_DRIVER_CLASS); - res.bridgeType = BridgeType.OPENVSWITCH; + res.setBridgeType(BridgeType.OPENVSWITCH); configure(params); checkAllSame(ovsVifDriver); } @@ -121,13 +121,13 @@ public void testWhenExplicitlySetDifferentDefault() throws ConfigurationExceptio // Switch res' bridge type for test purposes params.put(LibVirtVifDriver, LibvirtComputingResource.DEFAULT_OVS_VIF_DRIVER_CLASS); - res.bridgeType = BridgeType.NATIVE; + res.setBridgeType(BridgeType.NATIVE); configure(params); checkAllSame(ovsVifDriver); params.clear(); params.put(LibVirtVifDriver, LibvirtComputingResource.DEFAULT_BRIDGE_VIF_DRIVER_CLASS); - res.bridgeType = BridgeType.OPENVSWITCH; + res.setBridgeType(BridgeType.OPENVSWITCH); configure(params); checkAllSame(bridgeVifDriver); } @@ -138,7 +138,7 @@ public void testOverrideSomeTrafficTypes() throws ConfigurationException { final Map params = new HashMap<>(); params.put(LibVirtVifDriver + "." + "Public", FakeVifDriverClassName); params.put(LibVirtVifDriver + "." + "Guest", LibvirtComputingResource.DEFAULT_OVS_VIF_DRIVER_CLASS); - res.bridgeType = BridgeType.NATIVE; + res.setBridgeType(BridgeType.NATIVE); configure(params); // Initially, set all traffic types to use default @@ -156,7 +156,7 @@ public void testOverrideSomeTrafficTypes() throws ConfigurationException { public void testBadTrafficType() throws ConfigurationException { final Map params = new HashMap<>(); params.put(LibVirtVifDriver + "." + "NonExistentTrafficType", FakeVifDriverClassName); - res.bridgeType = BridgeType.NATIVE; + res.setBridgeType(BridgeType.NATIVE); configure(params); // Set all traffic types to use default, because bad traffic type should be ignored @@ -171,7 +171,7 @@ public void testBadTrafficType() throws ConfigurationException { public void testEmptyTrafficType() throws ConfigurationException { final Map params = new HashMap<>(); params.put(LibVirtVifDriver + ".", FakeVifDriverClassName); - res.bridgeType = BridgeType.NATIVE; + res.setBridgeType(BridgeType.NATIVE); configure(params); // Set all traffic types to use default, because bad traffic type should be ignored @@ -186,7 +186,7 @@ public void testEmptyTrafficType() throws ConfigurationException { public void testBadVifDriverClassName() throws ConfigurationException { final Map params = new HashMap<>(); params.put(LibVirtVifDriver + "." + "Public", NonExistentVifDriverClassName); - res.bridgeType = BridgeType.NATIVE; + res.setBridgeType(BridgeType.NATIVE); configure(params); } } diff --git a/cosmic-core/services/secondary-storage-server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/cosmic-core/services/secondary-storage-server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 4c327d4826..6f657b4a3c 100644 --- a/cosmic-core/services/secondary-storage-server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/cosmic-core/services/secondary-storage-server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -1982,18 +1982,11 @@ public Answer executeRequest(final Command cmd) { @Override public boolean configure(final String name, final Map params) throws ConfigurationException { - _eth1ip = (String) params.get("eth1ip"); - _eth1mask = (String) params.get("eth1mask"); - if (_eth1ip != null) { // can only happen inside service vm - params.put("private.network.device", "eth1"); - } else { - s_logger.warn("eth1ip parameter has not been configured, assuming that we are not inside a system vm"); - } - final String eth2ip = (String) params.get("eth2ip"); - if (eth2ip != null) { - params.put("public.network.device", "eth2"); - } - _publicIp = (String) params.get("eth2ip"); + s_logger.info("Configuring resource {}", name); + + configurePrivateInterface(params); + configuringPublicInterface(params); + _hostname = (String) params.get("name"); final String inSystemVM = (String) params.get("secondary.storage.vm"); @@ -2101,6 +2094,25 @@ public boolean configure(final String name, final Map params) th return true; } + private void configuringPublicInterface(final Map params) { + _publicIp = (String) params.get("eth2ip"); + s_logger.debug("Configuring public interface with IP {}", _publicIp); + if (_publicIp != null) { + params.put("public.network.device", "eth2"); + } + } + + private void configurePrivateInterface(final Map params) { + _eth1ip = (String) params.get("eth1ip"); + _eth1mask = (String) params.get("eth1mask"); + s_logger.debug("Configuring private interface with IP {} and mask {}", _eth1ip, _eth1mask); + if (_eth1ip != null) { // can only happen inside service vm + params.put("private.network.device", "eth1"); + } else { + s_logger.warn("eth1ip parameter has not been configured, assuming that we are not inside a system vm"); + } + } + protected void configureStorageLayerClass(final Map params) throws ConfigurationException { String value; if (_storage == null) { @@ -2225,6 +2237,7 @@ private void configureSSL() { if (!_inSystemVM) { return; } + s_logger.debug("Configuring SSL in SystemVM for public IP {} and hostname {}", _publicIp, _hostname); final Script command = new Script(_configSslScr); command.add("-i", _publicIp); command.add("-h", _hostname); diff --git a/cosmic-core/utils/src/main/java/com/cloud/utils/CloudConstants.java b/cosmic-core/utils/src/main/java/com/cloud/utils/CloudConstants.java new file mode 100644 index 0000000000..852f8d14ac --- /dev/null +++ b/cosmic-core/utils/src/main/java/com/cloud/utils/CloudConstants.java @@ -0,0 +1,19 @@ +package com.cloud.utils; + +public abstract class CloudConstants { + public static final String PROPERTY_KEY_HOST = "host"; + public static final String PROPERTY_KEY_PORT = "port"; + public static final String PROPERTY_KEY_ZONE = "zone"; + public static final String PROPERTY_KEY_POD = "pod"; + public static final String PROPERTY_KEY_CLUSTER = "cluster"; + public static final String PROPERTY_KEY_RESOURCE = "resource"; + public static final String PROPERTY_KEY_INSTANCE = "instance"; + public static final String PROPERTY_KEY_POOL = "pool"; + public static final String PROPERTY_KEY_GUID = "guid"; + public static final String PROPERTY_KEY_DEVELOPER = "developer"; + public static final String PROPERTY_KEY_CONSOLE_VERSION = "version"; + + public static final String DEFAULT_ZONE = "default"; + public static final String DEFAULT_POD = "default"; + public static final String DEFAULT_HOST = "localhost"; +} diff --git a/cosmic-core/utils/src/main/java/com/cloud/utils/PropertiesPojo.java b/cosmic-core/utils/src/main/java/com/cloud/utils/PropertiesPojo.java new file mode 100644 index 0000000000..d8d09edcd2 --- /dev/null +++ b/cosmic-core/utils/src/main/java/com/cloud/utils/PropertiesPojo.java @@ -0,0 +1,16 @@ +package com.cloud.utils; + +import java.util.Map; +import java.util.Properties; + +public interface PropertiesPojo { + void load(final Properties properties); + + default void load(final Map map) { + final Properties properties = new Properties(); + properties.putAll(map); + load(properties); + } + + Map buildPropertiesMap(); +} diff --git a/cosmic-core/utils/src/main/java/com/cloud/utils/PropertiesUtil.java b/cosmic-core/utils/src/main/java/com/cloud/utils/PropertiesUtil.java index 853acb40ea..fc1598729c 100644 --- a/cosmic-core/utils/src/main/java/com/cloud/utils/PropertiesUtil.java +++ b/cosmic-core/utils/src/main/java/com/cloud/utils/PropertiesUtil.java @@ -1,11 +1,15 @@ package com.cloud.utils; +import static java.util.stream.Collectors.toList; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -23,16 +27,28 @@ public class PropertiesUtil { public static final String PROPERTY_KEY_VALUE_SEPARATOR = "="; + public static List parse(final Properties properties, final String propertyKey, final List defaultValue, final Function> decomposer) { + return properties.containsKey(propertyKey) ? decomposer.apply(properties.get(propertyKey)).collect(toList()) : defaultValue; + } + public static String parse(final Properties properties, final String propertyKey, final String defaultValue) { return properties.containsKey(propertyKey) ? String.valueOf(properties.get(propertyKey)) : defaultValue; } - public static Integer parse(final Properties properties, final String propertyKey, final Integer defaultValue) { - return Integer.valueOf(parse(properties, propertyKey, defaultValue.toString())); + public static int parse(final Properties properties, final String propertyKey, final int defaultValue) { + return Integer.valueOf(parse(properties, propertyKey, Integer.toString(defaultValue))); + } + + public static long parse(final Properties properties, final String propertyKey, final long defaultValue) { + return Long.valueOf(parse(properties, propertyKey, Long.toString(defaultValue))); } - public static Boolean parse(final Properties properties, final String propertyKey, final Boolean defaultValue) { - return Boolean.valueOf(parse(properties, propertyKey, defaultValue.toString())); + public static boolean parse(final Properties properties, final String propertyKey, final boolean defaultValue) { + return Boolean.valueOf(parse(properties, propertyKey, Boolean.toString(defaultValue))); + } + + public static > T parse(final Properties properties, final String propertyKey, final T defaultValue, final Class clazz) { + return Enum.valueOf(clazz, parse(properties, propertyKey, defaultValue.toString()).toUpperCase()); } public static Properties parse(final Stream properties) { @@ -54,6 +70,12 @@ private static Predicate wellDefinedProperties() { return property -> property.contains(PROPERTY_KEY_VALUE_SEPARATOR); } + public static Function> stringSplitDecomposer(final String regex, final Class clazz) { + return (Object value) -> Arrays.stream(((String) value).split(regex)) + .filter(array -> !array.isEmpty()) + .map(clazz::cast); + } + public static BinaryOperator propertiesCombiner() { return (properties1, properties2) -> { final Properties merged = new Properties(); diff --git a/cosmic-core/utils/src/test/java/com/cloud/utils/PropertiesUtilsTest.java b/cosmic-core/utils/src/test/java/com/cloud/utils/PropertiesUtilsTest.java index ba7f799de8..b09192cbfd 100644 --- a/cosmic-core/utils/src/test/java/com/cloud/utils/PropertiesUtilsTest.java +++ b/cosmic-core/utils/src/test/java/com/cloud/utils/PropertiesUtilsTest.java @@ -1,6 +1,9 @@ package com.cloud.utils; +import static com.cloud.utils.PropertiesUtil.stringSplitDecomposer; + import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.core.AllOf.allOf; @@ -9,6 +12,8 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.stream.Stream; @@ -24,6 +29,35 @@ public class PropertiesUtilsTest { private static final String PROPERTY_KEY_POD = "pod"; private static final String PROPERTY_KEY_DEVELOPER = "developer"; + @Test + public void test_parse_whenPropertyIsPresentAndIsAList() throws Exception { + final Properties properties = new Properties(); + properties.setProperty("key", "element1,element2,element3"); + final List defaultValue = Collections.emptyList(); + + final List list = PropertiesUtil.parse(properties, "key", defaultValue, stringSplitDecomposer(",", String.class)); + + assertThat(list, containsInAnyOrder("element1", "element2", "element3")); + } + + @Test + public void test_parse_whenPropertyIsPresentAndIsAListAndIsEmpty() throws Exception { + final Properties properties = new Properties(); + properties.setProperty("key", ""); + final List defaultValue = Arrays.asList(new String[]{"element1", "element2", "element3"}); + + assertThat(PropertiesUtil.parse(properties, "key", defaultValue, stringSplitDecomposer(",", String.class)), empty()); + } + + @Test + public void test_parse_whenPropertyIsNotPresentAndIsAList() throws Exception { + final Properties properties = new Properties(); + properties.setProperty("key", "element1,element2,element3"); + final List defaultValue = Collections.emptyList(); + + assertThat(PropertiesUtil.parse(properties, "key1", defaultValue, stringSplitDecomposer(",", String.class)), empty()); + } + @Test public void test_parse_whenPropertiesExists() throws Exception { final Properties properties = new Properties(); @@ -46,14 +80,22 @@ public void test_parse_whenPropertiesDoesNotExists() throws Exception { } @Test - public void tets_parse_whenStreamIsEmpty() throws Exception { + public void test_parse_whenValueIsOfCustomType() throws Exception { + final Properties properties = new Properties(); + properties.setProperty("key", MyCustomType.VALUE1.toString()); + + assertThat(PropertiesUtil.parse(properties, "key", MyCustomType.VALUE2, MyCustomType.class), is(MyCustomType.VALUE1)); + } + + @Test + public void test_parse_whenStreamIsEmpty() throws Exception { final Properties properties = PropertiesUtil.parse(Stream.empty()); assertThat(properties.entrySet(), empty()); } @Test - public void tets_parse_whenStreamIsNotEmpty() throws Exception { + public void test_parse_whenStreamIsNotEmpty() throws Exception { final Stream stream = Arrays.stream(new String[]{"key1=value1", "key2=value2", "key1=value3"}); final Properties properties = PropertiesUtil.parse(stream); @@ -153,4 +195,10 @@ public void processConfigFile() throws IOException { Assert.assertEquals("d", config.get("c")); tempFile.delete(); } + + private enum MyCustomType { + VALUE1, VALUE2 + } } + +