diff --git a/core/src/com/cloud/agent/api/SetupCommand.java b/core/src/com/cloud/agent/api/SetupCommand.java index 65700e9453c..ee43c5933da 100644 --- a/core/src/com/cloud/agent/api/SetupCommand.java +++ b/core/src/com/cloud/agent/api/SetupCommand.java @@ -23,8 +23,6 @@ public class SetupCommand extends Command { HostEnvironment env; boolean multipath; boolean needSetup; - String secondaryStorage; - String systemVmIso; public boolean needSetup() { return needSetup; @@ -38,8 +36,6 @@ public class SetupCommand extends Command { this.env = env; this.multipath = false; this.needSetup = false; - secondaryStorage = null; - systemVmIso = null; } public HostEnvironment getEnvironment() { @@ -57,22 +53,6 @@ public class SetupCommand extends Command { return multipath; } - public void setSecondaryStorage(String secondaryStorage) { - this.secondaryStorage = secondaryStorage; - } - - public String getSecondaryStorage() { - return this.secondaryStorage; - } - - public void setSystemVmIso(String systemVmIso) { - this.systemVmIso = systemVmIso; - } - - public String getSystemVmIso() { - return this.systemVmIso; - } - @Override public boolean executeInSequence() { return true; diff --git a/core/src/com/cloud/agent/api/StartCommand.java b/core/src/com/cloud/agent/api/StartCommand.java index 308730ab5b7..88810c6ba5d 100644 --- a/core/src/com/cloud/agent/api/StartCommand.java +++ b/core/src/com/cloud/agent/api/StartCommand.java @@ -25,6 +25,7 @@ public class StartCommand extends Command { VirtualMachineTO vm; String hostIp; boolean executeInSequence = false; + String secondaryStorage; public VirtualMachineTO getVirtualMachine() { return vm; @@ -42,9 +43,18 @@ public class StartCommand extends Command { this.vm = vm; this.hostIp = host.getPrivateIpAddress(); this.executeInSequence = executeInSequence; + this.secondaryStorage = null; } public String getHostIp() { return this.hostIp; } + + public String getSecondaryStorage() { + return this.secondaryStorage; + } + + public void setSecondaryStorage(String secondary) { + this.secondaryStorage = secondary; + } } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index f5008123930..7f9e68a84bd 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -141,7 +141,7 @@ namespace HypervResource public static HypervResourceControllerConfig config = new HypervResourceControllerConfig(); private static ILog logger = LogManager.GetLogger(typeof(HypervResourceController)); - private static string systemVmIso; + private string systemVmIso = ""; Dictionary contextMap = new Dictionary(); public static void Initialize() @@ -179,19 +179,6 @@ namespace HypervResource try { - NFSTO share = new NFSTO(); - String uriStr = (String)cmd.secondaryStorage; - share.uri = new Uri(uriStr); - - string systemVmIso = (string)cmd.systemVmIso; - string defaultDataPath = wmiCallsV2.GetDefaultDataRoot(); - string isoPath = Path.Combine(defaultDataPath, Path.GetFileName(systemVmIso)); - if (!File.Exists(isoPath)) - { - logger.Info("File " + isoPath + " not found. Copying it from the secondary share."); - Utils.DownloadCifsFileToLocalFile(systemVmIso, share, isoPath); - } - HypervResourceController.systemVmIso = isoPath; result = true; } catch (Exception sysEx) @@ -957,7 +944,40 @@ namespace HypervResource try { - wmiCallsV2.DeployVirtualMachine(cmd, systemVmIso); + string systemVmIsoPath = systemVmIso; + lock (systemVmIso) + { + systemVmIsoPath = systemVmIso; + String uriStr = (String)cmd.secondaryStorage; + if (!String.IsNullOrEmpty(uriStr)) + { + if (String.IsNullOrEmpty(systemVmIsoPath) || !File.Exists(systemVmIsoPath)) + { + NFSTO share = new NFSTO(); + share.uri = new Uri(uriStr); + string defaultDataPath = wmiCallsV2.GetDefaultDataRoot(); + + string secondaryPath = Path.Combine(share.UncPath, "systemvm").Replace(@"/", @"\"); + string[] choices = choices = Directory.GetFiles(secondaryPath, "systemvm*.iso"); + if (choices.Length != 1) + { + String errMsg = "Couldn't locate the systemvm iso on " + secondaryPath; + logger.Debug(errMsg); + } + else + { + systemVmIsoPath = Path.Combine(defaultDataPath, Path.GetFileName(choices[0])); + if (!File.Exists(systemVmIsoPath)) + { + Utils.DownloadCifsFileToLocalFile(choices[0], share, systemVmIsoPath); + } + systemVmIso = systemVmIsoPath; + } + } + } + } + + wmiCallsV2.DeployVirtualMachine(cmd, systemVmIsoPath); result = true; } catch (Exception wmiEx) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs index c6c039a9bed..b2feab35ddd 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs @@ -453,7 +453,10 @@ namespace HypervResource // call patch systemvm iso only for systemvms if (vmName.StartsWith("r-") || vmName.StartsWith("s-") || vmName.StartsWith("v-")) { - patchSystemVmIso(vmName, systemVmIso); + if (systemVmIso != null && systemVmIso.Length != 0) + { + patchSystemVmIso(vmName, systemVmIso); + } } logger.DebugFormat("Starting VM {0}", vmName); diff --git a/plugins/hypervisors/hyperv/resources/META-INF/cloudstack/core/spring-hyperv-core-context.xml b/plugins/hypervisors/hyperv/resources/META-INF/cloudstack/core/spring-hyperv-core-context.xml new file mode 100644 index 00000000000..84d50ca97e0 --- /dev/null +++ b/plugins/hypervisors/hyperv/resources/META-INF/cloudstack/core/spring-hyperv-core-context.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java index 2a630c7e6db..2b81fa605d7 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java @@ -114,8 +114,6 @@ public class HypervServerDiscoverer extends DiscovererBase implements Discoverer private HostPodDao _podDao; @Inject private DataCenterDao _dcDao; - @Inject - DataStoreManager _dataStoreMgr; // TODO: AgentManager and AlertManager not being used to transmit info, // may want to reconsider. @@ -172,17 +170,8 @@ public class HypervServerDiscoverer extends DiscovererBase implements Discoverer s_logger.debug("Setting up host " + agentId); } - String secondaryStorageUri = getSecondaryStorageStoreUrl(cluster.getDataCenterId()); - if (secondaryStorageUri == null) { - s_logger.debug("Secondary storage uri for dc " + cluster.getDataCenterId() + " couldn't be obtained"); - } else { - prepareSecondaryStorageStore(secondaryStorageUri); - } - HostEnvironment env = new HostEnvironment(); SetupCommand setup = new SetupCommand(env); - setup.setSecondaryStorage(secondaryStorageUri); - setup.setSystemVmIso("systemvm/" + getSystemVMIsoFileNameOnDatastore()); if (!host.isSetup()) { setup.setNeedSetup(true); } @@ -309,7 +298,6 @@ public class HypervServerDiscoverer extends DiscovererBase implements Discoverer params.put("cluster", Long.toString(clusterId)); params.put("guid", guidWithTail); params.put("ipaddress", agentIp); - params.put("sec.storage.url", getSecondaryStorageStoreUrl(dcId)); // Hyper-V specific settings Map details = new HashMap(); @@ -352,175 +340,6 @@ public class HypervServerDiscoverer extends DiscovererBase implements Discoverer return null; } - private void prepareSecondaryStorageStore(String storageUrl) { - String mountPoint = getMountPoint(storageUrl); - - GlobalLock lock = GlobalLock.getInternLock("prepare.systemvm"); - try { - if (lock.lock(3600)) { - try { - File patchFolder = new File(mountPoint + "/systemvm"); - if (!patchFolder.exists()) { - if (!patchFolder.mkdirs()) { - String msg = "Unable to create systemvm folder on secondary storage. location: " + patchFolder.toString(); - s_logger.error(msg); - throw new CloudRuntimeException(msg); - } - } - - File srcIso = getSystemVMPatchIsoFile(); - File destIso = new File(mountPoint + "/systemvm/" + getSystemVMIsoFileNameOnDatastore()); - if (!destIso.exists()) { - s_logger.info("Copy System VM patch ISO file to secondary storage. source ISO: " + srcIso.getAbsolutePath() + ", destination: " + - destIso.getAbsolutePath()); - try { - FileUtil.copyfile(srcIso, destIso); - } catch (IOException e) { - s_logger.error("Unexpected exception ", e); - - String msg = "Unable to copy systemvm ISO on secondary storage. src location: " + srcIso.toString() + ", dest location: " + destIso; - s_logger.error(msg); - throw new CloudRuntimeException(msg); - } - } else { - if (s_logger.isTraceEnabled()) { - s_logger.trace("SystemVM ISO file " + destIso.getPath() + " already exists"); - } - } - } finally { - lock.unlock(); - } - } - } finally { - lock.releaseRef(); - } - } - - private String getMountPoint(String storageUrl) { - String mountPoint = null; - synchronized (_storageMounts) { - mountPoint = _storageMounts.get(storageUrl); - if (mountPoint != null) { - return mountPoint; - } - - URI uri; - try { - uri = new URI(storageUrl); - } catch (URISyntaxException e) { - s_logger.error("Invalid storage URL format ", e); - throw new CloudRuntimeException("Unable to create mount point due to invalid storage URL format " + storageUrl); - } - - mountPoint = mount(File.separator + File.separator + uri.getHost() + uri.getPath(), _mountParent, uri.getScheme(), uri.getQuery()); - if (mountPoint == null) { - s_logger.error("Unable to create mount point for " + storageUrl); - return "/mnt/sec"; - } - - _storageMounts.put(storageUrl, mountPoint); - return mountPoint; - } - } - - protected String mount(String path, String parent, String scheme, String query) { - String mountPoint = setupMountPoint(parent); - if (mountPoint == null) { - s_logger.warn("Unable to create a mount point"); - return null; - } - - Script script = null; - String result = null; - if (scheme.equals("cifs")) { - Script command = new Script(true, "mount", _timeout, s_logger); - command.add("-t", "cifs"); - command.add(path); - command.add(mountPoint); - - if (query != null) { - query = query.replace('&', ','); - command.add("-o", query); - } - result = command.execute(); - } - - if (result != null) { - s_logger.warn("Unable to mount " + path + " due to " + result); - File file = new File(mountPoint); - if (file.exists()) { - file.delete(); - } - return null; - } - - // Change permissions for the mountpoint - script = new Script(true, "chmod", _timeout, s_logger); - script.add("-R", "777", mountPoint); - result = script.execute(); - if (result != null) { - s_logger.warn("Unable to set permissions for " + mountPoint + " due to " + result); - } - return mountPoint; - } - - private String setupMountPoint(String parent) { - String mountPoint = null; - long mshostId = ManagementServerNode.getManagementServerId(); - for (int i = 0; i < 10; i++) { - String mntPt = parent + File.separator + String.valueOf(mshostId) + "." + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE)); - File file = new File(mntPt); - if (!file.exists()) { - if (_storage.mkdir(mntPt)) { - mountPoint = mntPt; - break; - } - } - s_logger.error("Unable to create mount: " + mntPt); - } - - return mountPoint; - } - - private String getSystemVMIsoFileNameOnDatastore() { - String version = this.getClass().getPackage().getImplementationVersion(); - String fileName = "systemvm-" + version + ".iso"; - return fileName.replace(':', '-'); - } - - private File getSystemVMPatchIsoFile() { - // locate systemvm.iso - URL url = this.getClass().getClassLoader().getResource("vms/systemvm.iso"); - File isoFile = null; - if (url != null) { - isoFile = new File(url.getPath()); - } - - if (isoFile == null || !isoFile.exists()) { - isoFile = new File("/usr/share/cloudstack-common/vms/systemvm.iso"); - } - - assert (isoFile != null); - if (!isoFile.exists()) { - s_logger.error("Unable to locate systemvm.iso in your setup at " + isoFile.toString()); - } - return isoFile; - } - - private String getSecondaryStorageStoreUrl(long zoneId) { - String secUrl = null; - DataStore secStore = _dataStoreMgr.getImageStore(zoneId); - if (secStore != null) { - secUrl = secStore.getUri(); - } - - if (secUrl == null) { - s_logger.warn("Secondary storage uri couldn't be retrieved"); - } - - return secUrl; - } - /** * Encapsulate GUID calculation in public method to allow access to test * programs. Works by converting a string to a GUID using @@ -545,25 +364,6 @@ public class HypervServerDiscoverer extends DiscovererBase implements Discoverer @Override public final boolean configure(final String name, final Map params) throws ConfigurationException { super.configure(name, params); - - _mountParent = (String)params.get(Config.MountParent.key()); - if (_mountParent == null) { - _mountParent = File.separator + "mnt"; - } - - if (_instance != null) { - _mountParent = _mountParent + File.separator + _instance; - } - - String value = (String)params.get("scripts.timeout"); - _timeout = NumbersUtil.parseInt(value, 30) * 1000; - - _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey); - if (_storage == null) { - _storage = new JavaStorageLayer(); - _storage.configure("StorageLayer", params); - } - // TODO: allow timeout on we HTTPRequests to be configured _agentMgr.registerForHostEvents(this, true, false, true); _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this); diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java new file mode 100644 index 00000000000..9030e29e7a4 --- /dev/null +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java @@ -0,0 +1,24 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +package com.cloud.hypervisor.hyperv.manager; + +import com.cloud.utils.component.Manager; + +public interface HypervManager extends Manager { + public String prepareSecondaryStorageStore(long zoneId); +} diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java new file mode 100644 index 00000000000..f21683d00be --- /dev/null +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java @@ -0,0 +1,367 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +package com.cloud.hypervisor.hyperv.manager; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.utils.identity.ManagementServerNode; +import org.apache.log4j.Logger; + +import com.cloud.configuration.Config; +import com.cloud.storage.JavaStorageLayer; +import com.cloud.storage.StorageLayer; +import com.cloud.utils.FileUtil; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.db.GlobalLock; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; + +@Local(value = { HypervManager.class }) +public class HypervManagerImpl implements HypervManager { + public static final Logger s_logger = Logger.getLogger(HypervManagerImpl.class); + + private String name; + private int runLevel; + private Map params; + + private int _timeout; + Random _rand = new Random(System.currentTimeMillis()); + + Map _storageMounts = new HashMap(); + StorageLayer _storage; + + @Inject ConfigurationDao _configDao; + @Inject DataStoreManager _dataStoreMgr; + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + if (params != null) { + String value = (String)params.get("scripts.timeout"); + _timeout = NumbersUtil.parseInt(value, 30) * 1000; + _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey); + } + + if (_storage == null) { + _storage = new JavaStorageLayer(); + _storage.configure("StorageLayer", params); + } + + return true; + } + + @Override + public boolean start() { + startupCleanup(getMountParent()); + return true; + } + + @Override + public boolean stop() { + shutdownCleanup(); + return true; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setConfigParams(Map params) { + this.params = params; + } + + @Override + public Map getConfigParams() { + return params; + } + + @Override + public int getRunLevel() { + return runLevel; + } + + @Override + public void setRunLevel(int level) { + runLevel = level; + } + + public String prepareSecondaryStorageStore(long zoneId) { + String secondaryStorageUri = getSecondaryStorageStoreUrl(zoneId); + if (secondaryStorageUri == null) { + s_logger.debug("Secondary storage uri for dc " + zoneId + " couldn't be obtained"); + } else { + prepareSecondaryStorageStore(secondaryStorageUri); + } + + return secondaryStorageUri; + } + + private String getSecondaryStorageStoreUrl(long zoneId) { + String secUrl = null; + DataStore secStore = _dataStoreMgr.getImageStore(zoneId); + if (secStore != null) { + secUrl = secStore.getUri(); + } + + if (secUrl == null) { + s_logger.warn("Secondary storage uri couldn't be retrieved"); + } + + return secUrl; + } + + private void prepareSecondaryStorageStore(String storageUrl) { + String mountPoint = getMountPoint(storageUrl); + + GlobalLock lock = GlobalLock.getInternLock("prepare.systemvm"); + try { + if(lock.lock(3600)) { + try { + File patchFolder = new File(mountPoint + "/systemvm"); + if(!patchFolder.exists()) { + if(!patchFolder.mkdirs()) { + String msg = "Unable to create systemvm folder on secondary storage. location: " + patchFolder.toString(); + s_logger.error(msg); + throw new CloudRuntimeException(msg); + } + } + + File srcIso = getSystemVMPatchIsoFile(); + File destIso = new File(mountPoint + "/systemvm/" + getSystemVMIsoFileNameOnDatastore()); + if(!destIso.exists()) { + s_logger.info("Copy System VM patch ISO file to secondary storage. source ISO: " + + srcIso.getAbsolutePath() + ", destination: " + destIso.getAbsolutePath()); + try { + FileUtil.copyfile(srcIso, destIso); + } catch(IOException e) { + s_logger.error("Unexpected exception ", e); + + String msg = "Unable to copy systemvm ISO on secondary storage. src location: " + srcIso.toString() + ", dest location: " + destIso; + s_logger.error(msg); + throw new CloudRuntimeException(msg); + } + } else { + if(s_logger.isTraceEnabled()) { + s_logger.trace("SystemVM ISO file " + destIso.getPath() + " already exists"); + } + } + } finally { + lock.unlock(); + } + } + } finally { + lock.releaseRef(); + } + } + + private String getMountPoint(String storageUrl) { + String mountPoint = null; + synchronized(_storageMounts) { + mountPoint = _storageMounts.get(storageUrl); + if(mountPoint != null) { + return mountPoint; + } + + URI uri; + try { + uri = new URI(storageUrl); + } catch (URISyntaxException e) { + s_logger.error("Invalid storage URL format ", e); + throw new CloudRuntimeException("Unable to create mount point due to invalid storage URL format " + storageUrl); + } + + mountPoint = mount(File.separator + File.separator + uri.getHost() + uri.getPath(), getMountParent(), + uri.getScheme(), uri.getQuery()); + if(mountPoint == null) { + s_logger.error("Unable to create mount point for " + storageUrl); + return "/mnt/sec"; + } + + _storageMounts.put(storageUrl, mountPoint); + return mountPoint; + } + } + + protected String mount(String path, String parent, String scheme, String query) { + String mountPoint = setupMountPoint(parent); + if (mountPoint == null) { + s_logger.warn("Unable to create a mount point"); + return null; + } + + Script script = null; + String result = null; + if (scheme.equals("cifs")) { + Script command = new Script(true, "mount", _timeout, s_logger); + command.add("-t", "cifs"); + command.add(path); + command.add(mountPoint); + + if (query != null) { + query = query.replace('&', ','); + command.add("-o", query); + } + result = command.execute(); + } + + if (result != null) { + s_logger.warn("Unable to mount " + path + " due to " + result); + File file = new File(mountPoint); + if (file.exists()) { + file.delete(); + } + return null; + } + + // Change permissions for the mountpoint + script = new Script(true, "chmod", _timeout, s_logger); + script.add("-R", "777", mountPoint); + result = script.execute(); + if (result != null) { + s_logger.warn("Unable to set permissions for " + mountPoint + " due to " + result); + } + return mountPoint; + } + + private String setupMountPoint(String parent) { + String mountPoint = null; + long mshostId = ManagementServerNode.getManagementServerId(); + for (int i = 0; i < 10; i++) { + String mntPt = parent + File.separator + String.valueOf(mshostId) + "." + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE)); + File file = new File(mntPt); + if (!file.exists()) { + if (_storage.mkdir(mntPt)) { + mountPoint = mntPt; + break; + } + } + s_logger.error("Unable to create mount: " + mntPt); + } + + return mountPoint; + } + + private String getSystemVMIsoFileNameOnDatastore() { + String version = this.getClass().getPackage().getImplementationVersion(); + String fileName = "systemvm-" + version + ".iso"; + return fileName.replace(':', '-'); + } + + private File getSystemVMPatchIsoFile() { + // locate systemvm.iso + URL url = this.getClass().getClassLoader().getResource("vms/systemvm.iso"); + File isoFile = null; + if (url != null) { + isoFile = new File(url.getPath()); + } + + if(isoFile == null || !isoFile.exists()) { + isoFile = new File("/usr/share/cloudstack-common/vms/systemvm.iso"); + } + + assert(isoFile != null); + if(!isoFile.exists()) { + s_logger.error("Unable to locate systemvm.iso in your setup at " + isoFile.toString()); + } + return isoFile; + } + + private String getMountParent() { + String mountParent = _configDao.getValue(Config.MountParent.key()); + if (mountParent == null) { + mountParent = File.separator + "mnt"; + } + + String instance = _configDao.getValue(Config.InstanceName.key()); + if (instance == null) { + instance = "DEFAULT"; + } + + if (instance != null) { + mountParent = mountParent + File.separator + instance; + } + + return mountParent; + } + + private void startupCleanup(String parent) { + s_logger.info("Cleanup mounted mount points used in previous session"); + + long mshostId = ManagementServerNode.getManagementServerId(); + + // cleanup left-over NFS mounts from previous session + String[] mounts = _storage.listFiles(parent + File.separator + String.valueOf(mshostId) + ".*"); + if(mounts != null && mounts.length > 0) { + for(String mountPoint : mounts) { + s_logger.info("umount NFS mount from previous session: " + mountPoint); + + String result = null; + Script command = new Script(true, "umount", _timeout, s_logger); + command.add(mountPoint); + result = command.execute(); + if (result != null) { + s_logger.warn("Unable to umount " + mountPoint + " due to " + result); + } + File file = new File(mountPoint); + if (file.exists()) { + file.delete(); + } + } + } + } + + private void shutdownCleanup() { + s_logger.info("Cleanup mounted mount points used in current session"); + + for(String mountPoint : _storageMounts.values()) { + s_logger.info("umount NFS mount: " + mountPoint); + + String result = null; + Script command = new Script(true, "umount", _timeout, s_logger); + command.add(mountPoint); + result = command.execute(); + if (result != null) { + s_logger.warn("Unable to umount " + mountPoint + " due to " + result); + } + File file = new File(mountPoint); + if (file.exists()) { + file.delete(); + } + } + } +} diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java index f61e5ff4401..6c4babd009e 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java @@ -28,7 +28,9 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import javax.annotation.PostConstruct; import javax.ejb.Local; +import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.http.HttpResponse; @@ -57,6 +59,7 @@ import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingTestCommand; +import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupRoutingCommand.VmState; @@ -91,9 +94,11 @@ import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor; +import com.cloud.hypervisor.hyperv.manager.HypervManager; import com.cloud.network.HAProxyConfigurator; import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.Networks.RouterPrivateIpStrategy; @@ -105,7 +110,9 @@ import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; import com.cloud.utils.net.NetUtils; import com.cloud.utils.ssh.SshHelper; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineName; +import com.google.gson.Gson; /** * Implementation of dummy resource to be returned from discoverer. @@ -137,6 +144,15 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S private String _username; private String _password; + private static HypervManager s_hypervMgr; + @Inject HypervManager _hypervMgr; + + @PostConstruct + void init() { + s_hypervMgr = _hypervMgr; + } + + @Override public final Type getType() { return Type.Routing; @@ -367,9 +383,23 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S } else if (clazz == CheckS2SVpnConnectionsCommand.class) { answer = execute((CheckS2SVpnConnectionsCommand)cmd); } else if (clazz == SetStaticRouteCommand.class) { - answer = execute((SetStaticRouteCommand)cmd); + answer = execute((SetStaticRouteCommand) cmd); } else { - // Else send the cmd to hyperv agent. + if (clazz == StartCommand.class) { + VirtualMachineTO vmSpec = ((StartCommand)cmd).getVirtualMachine(); + if (vmSpec.getType() != VirtualMachine.Type.User) { + if (s_hypervMgr != null) { + String secondary = s_hypervMgr.prepareSecondaryStorageStore(Long.parseLong(_zoneId)); + if (secondary != null) { + ((StartCommand)cmd).setSecondaryStorage(secondary); + } + } else { + s_logger.error("Hyperv manager isn't available. Couldn't check and copy the systemvm iso."); + } + } + } + + // Send the cmd to hyperv agent. String ansStr = postHttpRequest(s_gson.toJson(cmd), agentUri); if (ansStr == null) { return Answer.createUnsupportedCommandAnswer(cmd); @@ -1576,19 +1606,22 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S @Override public final boolean configure(final String name, final Map params) throws ConfigurationException { /* todo: update, make consistent with the xen server equivalent. */ - _guid = (String)params.get("guid"); - _zoneId = (String)params.get("zone"); - _podId = (String)params.get("pod"); - _clusterId = (String)params.get("cluster"); - _agentIp = (String)params.get("ipaddress"); // was agentIp - _name = name; - _clusterGuid = (String)params.get("cluster.guid"); - _username = (String)params.get("url"); - _password = (String)params.get("password"); - _username = (String)params.get("username"); + if (params != null) { + _guid = (String) params.get("guid"); + _zoneId = (String) params.get("zone"); + _podId = (String) params.get("pod"); + _clusterId = (String) params.get("cluster"); + _agentIp = (String) params.get("ipaddress"); // was agentIp + _name = name; + + _clusterGuid = (String) params.get("cluster.guid"); + _username = (String) params.get("url"); + _password = (String) params.get("password"); + _username = (String) params.get("username"); + _configureCalled = true; + } - _configureCalled = true; return true; }