mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Removed Dead Code from Management Server Hyper-V 2012 Support
Update ImageFormat enum to include VHDX format introduced with Hyper-V Server 2012. Remove existing Hyper-V plugin, because it does not work and is dead code. Remove references to existing Hyper-V plugin from config files. Remove Hypervisor.HypervisorType.Hyperv special cases from manager code that are unused or unsupported. Specifically, there is no CIFS secondary storage class "CifsSecondaryStorageResource". Also, the Hyper-V plugin's ServerResource is contacted by the management server and not the other way around. Add Hyperv-V support to ListHypervisorsCmd API call Signed-off-by: Edison Su <sudison@gmail.com>
This commit is contained in:
parent
77fd76acb4
commit
4361418e41
@ -1,504 +0,0 @@
|
||||
// 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.agent;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.Agent.ExitStatus;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.StartupVMMAgentCommand;
|
||||
import com.cloud.agent.dao.StorageComponent;
|
||||
import com.cloud.agent.dao.impl.PropertiesStorage;
|
||||
import com.cloud.agent.transport.Request;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.PropertiesUtil;
|
||||
import com.cloud.utils.backoff.BackoffAlgorithm;
|
||||
import com.cloud.utils.backoff.impl.ConstantTimeBackoff;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.net.MacAddress;
|
||||
import com.cloud.utils.nio.HandlerFactory;
|
||||
import com.cloud.utils.nio.Link;
|
||||
import com.cloud.utils.nio.NioServer;
|
||||
import com.cloud.utils.nio.Task;
|
||||
|
||||
/**
|
||||
* Implementation of agent shell to run the agents on System Center Virtual Machine manager
|
||||
**/
|
||||
|
||||
public class VmmAgentShell implements IAgentShell, HandlerFactory {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(VmmAgentShell.class.getName());
|
||||
private final Properties _properties = new Properties();
|
||||
private final Map<String, Object> _cmdLineProperties = new HashMap<String, Object>();
|
||||
private StorageComponent _storage;
|
||||
private BackoffAlgorithm _backoff;
|
||||
private String _version;
|
||||
private String _zone;
|
||||
private String _pod;
|
||||
private String _cluster;
|
||||
private String _host;
|
||||
private String _privateIp;
|
||||
private int _port;
|
||||
private int _proxyPort;
|
||||
private int _workers;
|
||||
private String _guid;
|
||||
static private NioServer _connection;
|
||||
static private int _listenerPort=9000;
|
||||
private int _nextAgentId = 1;
|
||||
private volatile boolean _exit = false;
|
||||
private int _pingRetries;
|
||||
private final Thread _consoleProxyMain = null;
|
||||
private final List<Agent> _agents = new ArrayList<Agent>();
|
||||
|
||||
public VmmAgentShell() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getProperties() {
|
||||
return _properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackoffAlgorithm getBackoffAlgorithm() {
|
||||
return _backoff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPingRetries() {
|
||||
return _pingRetries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getZone() {
|
||||
return _zone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPod() {
|
||||
return _pod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return _host;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrivateIp() {
|
||||
return _privateIp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return _port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProxyPort() {
|
||||
return _proxyPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWorkers() {
|
||||
return _workers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGuid() {
|
||||
return _guid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upgradeAgent(String url) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return _version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getCmdLineProperties() {
|
||||
// TODO Auto-generated method stub
|
||||
return _cmdLineProperties;
|
||||
}
|
||||
|
||||
public String getProperty(String prefix, String name) {
|
||||
if(prefix != null)
|
||||
return _properties.getProperty(prefix + "." + name);
|
||||
|
||||
return _properties.getProperty(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPersistentProperty(String prefix, String name) {
|
||||
if(prefix != null)
|
||||
return _storage.get(prefix + "." + name);
|
||||
return _storage.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPersistentProperty(String prefix, String name, String value) {
|
||||
if(prefix != null)
|
||||
_storage.persist(prefix + "." + name, value);
|
||||
else
|
||||
_storage.persist(name, value);
|
||||
}
|
||||
|
||||
private void loadProperties() throws ConfigurationException {
|
||||
final File file = PropertiesUtil.findConfigFile("agent.properties");
|
||||
if (file == null) {
|
||||
throw new ConfigurationException("Unable to find agent.properties.");
|
||||
}
|
||||
|
||||
s_logger.info("agent.properties found at " + file.getAbsolutePath());
|
||||
|
||||
try {
|
||||
_properties.load(new FileInputStream(file));
|
||||
} catch (final FileNotFoundException ex) {
|
||||
throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
|
||||
} catch (final IOException ex) {
|
||||
throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean parseCommand(final String[] args) throws ConfigurationException {
|
||||
String host = null;
|
||||
String workers = null;
|
||||
String port = null;
|
||||
String zone = null;
|
||||
String pod = null;
|
||||
String guid = null;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
final String[] tokens = args[i].split("=");
|
||||
if (tokens.length != 2) {
|
||||
System.out.println("Invalid Parameter: " + args[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// save command line properties
|
||||
_cmdLineProperties.put(tokens[0], tokens[1]);
|
||||
|
||||
if (tokens[0].equalsIgnoreCase("port")) {
|
||||
port = tokens[1];
|
||||
} else if (tokens[0].equalsIgnoreCase("threads")) {
|
||||
workers = tokens[1];
|
||||
} else if (tokens[0].equalsIgnoreCase("host")) {
|
||||
host = tokens[1];
|
||||
} else if(tokens[0].equalsIgnoreCase("zone")) {
|
||||
zone = tokens[1];
|
||||
} else if(tokens[0].equalsIgnoreCase("pod")) {
|
||||
pod = tokens[1];
|
||||
} else if(tokens[0].equalsIgnoreCase("guid")) {
|
||||
guid = tokens[1];
|
||||
} else if(tokens[0].equalsIgnoreCase("eth1ip")) {
|
||||
_privateIp = tokens[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (port == null) {
|
||||
port = getProperty(null, "port");
|
||||
}
|
||||
|
||||
_port = NumbersUtil.parseInt(port, 8250);
|
||||
|
||||
_proxyPort = NumbersUtil.parseInt(getProperty(null, "consoleproxy.httpListenPort"), 443);
|
||||
|
||||
if (workers == null) {
|
||||
workers = getProperty(null, "workers");
|
||||
}
|
||||
|
||||
_workers = NumbersUtil.parseInt(workers, 5);
|
||||
|
||||
if (host == null) {
|
||||
host = getProperty(null, "host");
|
||||
}
|
||||
|
||||
if (host == null) {
|
||||
host = "localhost";
|
||||
}
|
||||
_host = host;
|
||||
|
||||
if(zone != null)
|
||||
_zone = zone;
|
||||
else
|
||||
_zone = getProperty(null, "zone");
|
||||
if (_zone == null || (_zone.startsWith("@") && _zone.endsWith("@"))) {
|
||||
_zone = "default";
|
||||
}
|
||||
|
||||
if(pod != null)
|
||||
_pod = pod;
|
||||
else
|
||||
_pod = getProperty(null, "pod");
|
||||
if (_pod == null || (_pod.startsWith("@") && _pod.endsWith("@"))) {
|
||||
_pod = "default";
|
||||
}
|
||||
|
||||
if (_host == null || (_host.startsWith("@") && _host.endsWith("@"))) {
|
||||
throw new ConfigurationException("Host is not configured correctly: " + _host);
|
||||
}
|
||||
|
||||
final String retries = getProperty(null, "ping.retries");
|
||||
_pingRetries = NumbersUtil.parseInt(retries, 5);
|
||||
|
||||
String value = getProperty(null, "developer");
|
||||
boolean developer = Boolean.parseBoolean(value);
|
||||
|
||||
if(guid != null)
|
||||
_guid = guid;
|
||||
else
|
||||
_guid = getProperty(null, "guid");
|
||||
if (_guid == null) {
|
||||
if (!developer) {
|
||||
throw new ConfigurationException("Unable to find the guid");
|
||||
}
|
||||
_guid = MacAddress.getMacAddress().toString(":");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void launchAgentFromTypeInfo() throws ConfigurationException {
|
||||
String typeInfo = getProperty(null, "type");
|
||||
if (typeInfo == null) {
|
||||
s_logger.error("Unable to retrieve the type");
|
||||
throw new ConfigurationException("Unable to retrieve the type of this agent.");
|
||||
}
|
||||
s_logger.trace("Launching agent based on type=" + typeInfo);
|
||||
}
|
||||
|
||||
private void launchAgent() throws ConfigurationException {
|
||||
String resourceClassNames = getProperty(null, "resource");
|
||||
s_logger.trace("resource=" + resourceClassNames);
|
||||
if(resourceClassNames != null) {
|
||||
launchAgentFromClassInfo(resourceClassNames);
|
||||
return;
|
||||
}
|
||||
|
||||
launchAgentFromTypeInfo();
|
||||
}
|
||||
|
||||
private void init(String[] args) throws ConfigurationException{
|
||||
|
||||
final Class<?> c = this.getClass();
|
||||
_version = c.getPackage().getImplementationVersion();
|
||||
if (_version == null) {
|
||||
throw new CloudRuntimeException("Unable to find the implementation version of this agent");
|
||||
}
|
||||
s_logger.info("Implementation Version is " + _version);
|
||||
|
||||
parseCommand(args);
|
||||
|
||||
s_logger.info("Defaulting to using properties file for storage");
|
||||
_storage = new PropertiesStorage();
|
||||
_storage.configure("Storage", new HashMap<String, Object>());
|
||||
|
||||
// merge with properties from command line to let resource access command line parameters
|
||||
for(Map.Entry<String, Object> cmdLineProp : getCmdLineProperties().entrySet()) {
|
||||
_properties.put(cmdLineProp.getKey(), cmdLineProp.getValue());
|
||||
}
|
||||
|
||||
s_logger.info("Defaulting to the constant time backoff algorithm");
|
||||
_backoff = new ConstantTimeBackoff();
|
||||
_backoff.configure("ConstantTimeBackoff", new HashMap<String, Object>());
|
||||
}
|
||||
|
||||
private void launchAgentFromClassInfo(String resourceClassNames) throws ConfigurationException {
|
||||
String[] names = resourceClassNames.split("\\|");
|
||||
for(String name: names) {
|
||||
Class<?> impl;
|
||||
try {
|
||||
impl = Class.forName(name);
|
||||
final Constructor<?> constructor = impl.getDeclaredConstructor();
|
||||
constructor.setAccessible(true);
|
||||
ServerResource resource = (ServerResource)constructor.newInstance();
|
||||
launchAgent(getNextAgentId(), resource);
|
||||
} catch (final ClassNotFoundException e) {
|
||||
throw new ConfigurationException("Resource class not found: " + name);
|
||||
} catch (final SecurityException e) {
|
||||
throw new ConfigurationException("Security excetion when loading resource: " + name);
|
||||
} catch (final NoSuchMethodException e) {
|
||||
throw new ConfigurationException("Method not found excetion when loading resource: " + name);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
throw new ConfigurationException("Illegal argument excetion when loading resource: " + name);
|
||||
} catch (final InstantiationException e) {
|
||||
throw new ConfigurationException("Instantiation excetion when loading resource: " + name);
|
||||
} catch (final IllegalAccessException e) {
|
||||
throw new ConfigurationException("Illegal access exception when loading resource: " + name);
|
||||
} catch (final InvocationTargetException e) {
|
||||
throw new ConfigurationException("Invocation target exception when loading resource: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void launchAgent(int localAgentId, ServerResource resource) throws ConfigurationException {
|
||||
// we don't track agent after it is launched for now
|
||||
Agent agent = new Agent(this, localAgentId, resource);
|
||||
_agents.add(agent);
|
||||
agent.start();
|
||||
}
|
||||
|
||||
public synchronized int getNextAgentId() {
|
||||
return _nextAgentId++;
|
||||
}
|
||||
|
||||
private void run(String[] args) {
|
||||
|
||||
try {
|
||||
System.setProperty("java.net.preferIPv4Stack","true");
|
||||
loadProperties();
|
||||
init(args);
|
||||
|
||||
String instance = getProperty(null, "instance");
|
||||
if (instance == null) {
|
||||
instance = "";
|
||||
} else {
|
||||
instance += ".";
|
||||
}
|
||||
|
||||
// TODO need to do this check. For Agentshell running on windows needs different approach
|
||||
//final String run = "agent." + instance + "pid";
|
||||
//s_logger.debug("Checking to see if " + run + "exists.");
|
||||
//ProcessUtil.pidCheck(run);
|
||||
|
||||
|
||||
// TODO: For Hyper-V agent.properties need to be revamped to support multiple agents
|
||||
// corresponding to multiple clusters but running on a SCVMM host
|
||||
|
||||
// read the persistent storage and launch the agents
|
||||
//launchAgent();
|
||||
|
||||
// FIXME get rid of this approach of agent listening for boot strap commands from the management server
|
||||
|
||||
// now listen for bootstrap request from the management server and launch agents
|
||||
_connection = new NioServer("VmmAgentShell", _listenerPort, 1, this);
|
||||
_connection.start();
|
||||
s_logger.info("SCVMM agent is listening on port " +_listenerPort + " for bootstrap command from management server");
|
||||
while(_connection.isRunning());
|
||||
} catch(final ConfigurationException e) {
|
||||
s_logger.error("Unable to start agent: " + e.getMessage());
|
||||
System.out.println("Unable to start agent: " + e.getMessage());
|
||||
System.exit(ExitStatus.Configuration.value());
|
||||
} catch (final Exception e) {
|
||||
s_logger.error("Unable to start agent: ", e);
|
||||
System.out.println("Unable to start agent: " + e.getMessage());
|
||||
System.exit(ExitStatus.Error.value());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task create(com.cloud.utils.nio.Task.Type type, Link link,
|
||||
byte[] data) {
|
||||
return new AgentBootStrapHandler(type, link, data);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
_exit = true;
|
||||
if(_consoleProxyMain != null) {
|
||||
_consoleProxyMain.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
VmmAgentShell shell = new VmmAgentShell();
|
||||
Runtime.getRuntime().addShutdownHook(new ShutdownThread(shell));
|
||||
shell.run(args);
|
||||
}
|
||||
|
||||
// class to handle the bootstrap command from the management server
|
||||
private class AgentBootStrapHandler extends Task {
|
||||
|
||||
public AgentBootStrapHandler(Task.Type type, Link link, byte[] data) {
|
||||
super(type, link, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doTask(Task task) throws Exception {
|
||||
final Type type = task.getType();
|
||||
s_logger.info("recieved task of type "+ type.toString() +" to handle in BootStrapTakHandler");
|
||||
if (type == Task.Type.DATA)
|
||||
{
|
||||
final byte[] data = task.getData();
|
||||
final Request request = Request.parse(data);
|
||||
final Command cmd = request.getCommand();
|
||||
|
||||
if (cmd instanceof StartupVMMAgentCommand) {
|
||||
|
||||
StartupVMMAgentCommand vmmCmd = (StartupVMMAgentCommand) cmd;
|
||||
|
||||
_zone = Long.toString(vmmCmd.getDataCenter());
|
||||
_cmdLineProperties.put("zone", _zone);
|
||||
|
||||
_pod = Long.toString(vmmCmd.getPod());
|
||||
_cmdLineProperties.put("pod", _pod);
|
||||
|
||||
_cluster = vmmCmd.getClusterName();
|
||||
_cmdLineProperties.put("cluster", _cluster);
|
||||
|
||||
_guid = vmmCmd.getGuid();
|
||||
_cmdLineProperties.put("guid", _guid);
|
||||
|
||||
_host = vmmCmd.getManagementServerIP();
|
||||
_port = NumbersUtil.parseInt(vmmCmd.getport(), 8250);
|
||||
|
||||
s_logger.info("Recieved boot strap command from management server with parameters " +
|
||||
" Zone:"+ _zone + " "+
|
||||
" Cluster:"+ _cluster + " "+
|
||||
" pod:"+_pod + " "+
|
||||
" host:"+ _host +" "+
|
||||
" port:"+_port);
|
||||
|
||||
launchAgentFromClassInfo("com.cloud.hypervisor.hyperv.resource.HypervResource");
|
||||
|
||||
// TODO: persist the info in agent.properties for agent restarts
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ShutdownThread extends Thread {
|
||||
VmmAgentShell _shell;
|
||||
public ShutdownThread(VmmAgentShell shell) {
|
||||
this._shell = shell;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
_shell.stop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -26,6 +26,7 @@ public class Storage {
|
||||
VHD(true, true, true, "vhd"),
|
||||
ISO(false, false, false, "iso"),
|
||||
OVA(true, true, true, "ova"),
|
||||
VHDX(true, true, true, "vhdx"),
|
||||
BAREMETAL(false, false, false, "BAREMETAL"),
|
||||
TAR(false, false, false, "tar");
|
||||
|
||||
|
||||
@ -537,10 +537,6 @@
|
||||
<property name="name" value="Lxc Discover"/>
|
||||
</bean>
|
||||
|
||||
<bean id="HypervServerDiscoverer" class="com.cloud.hypervisor.hyperv.HypervServerDiscoverer">
|
||||
<property name="name" value="SCVMMServer"/>
|
||||
</bean>
|
||||
|
||||
<bean id="OvmDiscoverer" class="com.cloud.ovm.hypervisor.OvmDiscoverer">
|
||||
<property name="name" value="Ovm Discover"/>
|
||||
</bean>
|
||||
|
||||
@ -1,978 +0,0 @@
|
||||
// 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.resource;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.IAgentControl;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.AttachIsoCommand;
|
||||
import com.cloud.agent.api.AttachVolumeCommand;
|
||||
import com.cloud.agent.api.BackupSnapshotCommand;
|
||||
import com.cloud.agent.api.CheckHealthCommand;
|
||||
import com.cloud.agent.api.CheckNetworkCommand;
|
||||
import com.cloud.agent.api.CheckOnHostCommand;
|
||||
import com.cloud.agent.api.CheckVirtualMachineCommand;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
|
||||
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
|
||||
import com.cloud.agent.api.DeleteStoragePoolCommand;
|
||||
import com.cloud.agent.api.GetHostStatsAnswer;
|
||||
import com.cloud.agent.api.GetHostStatsCommand;
|
||||
import com.cloud.agent.api.GetStorageStatsAnswer;
|
||||
import com.cloud.agent.api.GetStorageStatsCommand;
|
||||
import com.cloud.agent.api.GetVmStatsCommand;
|
||||
import com.cloud.agent.api.GetVncPortCommand;
|
||||
import com.cloud.agent.api.HostStatsEntry;
|
||||
import com.cloud.agent.api.MaintainCommand;
|
||||
import com.cloud.agent.api.ManageSnapshotCommand;
|
||||
import com.cloud.agent.api.MigrateCommand;
|
||||
import com.cloud.agent.api.ModifySshKeysCommand;
|
||||
import com.cloud.agent.api.ModifyStoragePoolAnswer;
|
||||
import com.cloud.agent.api.ModifyStoragePoolCommand;
|
||||
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.PoolEjectCommand;
|
||||
import com.cloud.agent.api.PrepareForMigrationCommand;
|
||||
import com.cloud.agent.api.ReadyAnswer;
|
||||
import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.RebootCommand;
|
||||
import com.cloud.agent.api.RebootRouterCommand;
|
||||
import com.cloud.agent.api.SetupCommand;
|
||||
import com.cloud.agent.api.StartAnswer;
|
||||
import com.cloud.agent.api.StartCommand;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupRoutingCommand;
|
||||
import com.cloud.agent.api.StopCommand;
|
||||
import com.cloud.agent.api.ValidateSnapshotCommand;
|
||||
import com.cloud.agent.api.check.CheckSshAnswer;
|
||||
import com.cloud.agent.api.check.CheckSshCommand;
|
||||
import com.cloud.agent.api.routing.DhcpEntryCommand;
|
||||
import com.cloud.agent.api.routing.IpAssocCommand;
|
||||
import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
|
||||
import com.cloud.agent.api.routing.NetworkElementCommand;
|
||||
import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
|
||||
import com.cloud.agent.api.routing.SavePasswordCommand;
|
||||
import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
|
||||
import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
|
||||
import com.cloud.agent.api.routing.VmDataCommand;
|
||||
import com.cloud.agent.api.routing.VpnUsersCfgCommand;
|
||||
import com.cloud.agent.api.storage.CopyVolumeCommand;
|
||||
import com.cloud.agent.api.storage.CreateAnswer;
|
||||
import com.cloud.agent.api.storage.CreateCommand;
|
||||
import com.cloud.agent.api.storage.DestroyCommand;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
import com.cloud.agent.api.to.StorageFilerTO;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
import com.cloud.host.Host.Type;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.ssh.SshHelper;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.resource.ServerResourceBase;
|
||||
import com.cloud.serializer.GsonHelper;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
* Implementation of resource base class for Hyper-V hypervisor
|
||||
**/
|
||||
|
||||
@Local(value={ServerResource.class})
|
||||
public class HypervResource extends ServerResourceBase implements ServerResource{
|
||||
private String _dcId;
|
||||
private String _podId;
|
||||
private String _clusterId;
|
||||
private String _guid;
|
||||
private String _name;
|
||||
private static final Logger s_logger = Logger.getLogger(HypervResource.class);
|
||||
private IAgentControl agentControl;
|
||||
private volatile Boolean _wakeUp = false;
|
||||
protected Gson _gson;
|
||||
protected HashMap<String, State> _vms = new HashMap<String, State>(512);
|
||||
protected final int DEFAULT_DOMR_SSHPORT = 3922;
|
||||
|
||||
public HypervResource()
|
||||
{
|
||||
_gson = GsonHelper.getGsonLogger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Answer executeRequest(Command cmd) {
|
||||
|
||||
if (cmd instanceof CreateCommand) {
|
||||
return execute((CreateCommand) cmd);
|
||||
} else if (cmd instanceof SetPortForwardingRulesCommand) {
|
||||
s_logger.info("SCVMM agent recived command SetPortForwardingRulesCommand");
|
||||
//return execute((SetPortForwardingRulesCommand) cmd);
|
||||
} else if (cmd instanceof SetStaticNatRulesCommand) {
|
||||
s_logger.info("SCVMM agent recived command SetStaticNatRulesCommand");
|
||||
//return execute((SetStaticNatRulesCommand) cmd);
|
||||
}else if (cmd instanceof LoadBalancerConfigCommand) {
|
||||
s_logger.info("SCVMM agent recived command SetStaticNatRulesCommand");
|
||||
//return execute((LoadBalancerConfigCommand) cmd);
|
||||
} else if (cmd instanceof IpAssocCommand) {
|
||||
s_logger.info("SCVMM agent recived command IPAssocCommand");
|
||||
//return execute((IPAssocCommand) cmd);
|
||||
} else if (cmd instanceof SavePasswordCommand) {
|
||||
s_logger.info("SCVMM agent recived command SavePasswordCommand");
|
||||
//return execute((SavePasswordCommand) cmd);
|
||||
} else if (cmd instanceof DhcpEntryCommand) {
|
||||
return execute((DhcpEntryCommand) cmd);
|
||||
} else if (cmd instanceof VmDataCommand) {
|
||||
//return execute((VmDataCommand) cmd);
|
||||
} else if (cmd instanceof ReadyCommand) {
|
||||
s_logger.info("SCVMM agent recived ReadyCommand: " + _gson.toJson(cmd));
|
||||
return new ReadyAnswer((ReadyCommand) cmd);
|
||||
} else if (cmd instanceof GetHostStatsCommand) {
|
||||
return execute((GetHostStatsCommand) cmd);
|
||||
} else if (cmd instanceof GetVmStatsCommand) {
|
||||
s_logger.info("SCVMM agent recived command GetVmStatsCommand");
|
||||
//return execute((GetVmStatsCommand) cmd);
|
||||
} else if (cmd instanceof CheckHealthCommand) {
|
||||
//return execute((CheckHealthCommand) cmd);
|
||||
} else if (cmd instanceof StopCommand) {
|
||||
//return execute((StopCommand) cmd);
|
||||
} else if (cmd instanceof RebootRouterCommand) {
|
||||
//return execute((RebootRouterCommand) cmd);
|
||||
} else if (cmd instanceof RebootCommand) {
|
||||
//return execute((RebootCommand) cmd);
|
||||
} else if (cmd instanceof CheckVirtualMachineCommand) {
|
||||
s_logger.info("SCVMM agent recived command CheckVirtualMachineCommand");
|
||||
//return execute((CheckVirtualMachineCommand) cmd);
|
||||
} else if (cmd instanceof PrepareForMigrationCommand) {
|
||||
//return execute((PrepareForMigrationCommand) cmd);
|
||||
} else if (cmd instanceof MigrateCommand) {
|
||||
//return execute((MigrateCommand) cmd);
|
||||
} else if (cmd instanceof DestroyCommand) {
|
||||
//return execute((DestroyCommand) cmd);
|
||||
} else if (cmd instanceof ModifyStoragePoolCommand) {
|
||||
return execute((ModifyStoragePoolCommand) cmd);
|
||||
} else if (cmd instanceof DeleteStoragePoolCommand) {
|
||||
s_logger.info("SCVMM agent recived command DeleteStoragePoolCommand");
|
||||
Answer answer = new Answer(cmd, true, "success");
|
||||
return answer;
|
||||
//return execute((DeleteStoragePoolCommand) cmd);
|
||||
} else if (cmd instanceof CopyVolumeCommand) {
|
||||
s_logger.info("SCVMM agent recived command CopyVolumeCommand");
|
||||
//return execute((CopyVolumeCommand) cmd);
|
||||
} else if (cmd instanceof AttachVolumeCommand) {
|
||||
s_logger.info("SCVMM agent recived command AttachVolumeCommand");
|
||||
//return execute((AttachVolumeCommand) cmd);
|
||||
} else if (cmd instanceof AttachIsoCommand) {
|
||||
//return execute((AttachIsoCommand) cmd);
|
||||
} else if (cmd instanceof ValidateSnapshotCommand) {
|
||||
//return execute((ValidateSnapshotCommand) cmd);
|
||||
} else if (cmd instanceof ManageSnapshotCommand) {
|
||||
//return execute((ManageSnapshotCommand) cmd);
|
||||
} else if (cmd instanceof BackupSnapshotCommand) {
|
||||
//return execute((BackupSnapshotCommand) cmd);
|
||||
} else if (cmd instanceof CreateVolumeFromSnapshotCommand) {
|
||||
//return execute((CreateVolumeFromSnapshotCommand) cmd);
|
||||
} else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) {
|
||||
//return execute((CreatePrivateTemplateFromVolumeCommand) cmd);
|
||||
} else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) {
|
||||
//return execute((CreatePrivateTemplateFromSnapshotCommand) cmd);
|
||||
} else if (cmd instanceof GetStorageStatsCommand) {
|
||||
return execute((GetStorageStatsCommand) cmd);
|
||||
} else if (cmd instanceof PrimaryStorageDownloadCommand) {
|
||||
s_logger.info("SCVMM agent recived command PrimaryStorageDownloadCommand");
|
||||
return execute((PrimaryStorageDownloadCommand) cmd);
|
||||
} else if (cmd instanceof GetVncPortCommand) {
|
||||
//return execute((GetVncPortCommand) cmd);
|
||||
} else if (cmd instanceof SetupCommand) {
|
||||
//return execute((SetupCommand) cmd);
|
||||
} else if (cmd instanceof MaintainCommand) {
|
||||
//return execute((MaintainCommand) cmd);
|
||||
} else if (cmd instanceof PingTestCommand) {
|
||||
s_logger.info("SCVMM agent recived command PingTestCommand");
|
||||
//return execute((PingTestCommand) cmd);
|
||||
} else if (cmd instanceof CheckOnHostCommand) {
|
||||
s_logger.info("SCVMM agent recived command CheckOnHostCommand");
|
||||
//return execute((CheckOnHostCommand) cmd);
|
||||
} else if (cmd instanceof ModifySshKeysCommand) {
|
||||
//return execute((ModifySshKeysCommand) cmd);
|
||||
} else if (cmd instanceof PoolEjectCommand) {
|
||||
//return execute((PoolEjectCommand) cmd);
|
||||
} else if (cmd instanceof NetworkUsageCommand) {
|
||||
//return execute((NetworkUsageCommand) cmd);
|
||||
} else if (cmd instanceof StartCommand) {
|
||||
return execute((StartCommand) cmd);
|
||||
} else if (cmd instanceof RemoteAccessVpnCfgCommand) {
|
||||
//return execute((RemoteAccessVpnCfgCommand) cmd);
|
||||
} else if (cmd instanceof VpnUsersCfgCommand) {
|
||||
//return execute((VpnUsersCfgCommand) cmd);
|
||||
} else if (cmd instanceof CheckSshCommand) {
|
||||
return execute((CheckSshCommand)cmd);
|
||||
} else if (cmd instanceof CheckNetworkCommand) {
|
||||
//return execute((CheckNetworkCommand) cmd);
|
||||
} else {
|
||||
s_logger.info("SCVMM agent recived unimplemented command: " + _gson.toJson(cmd));
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
|
||||
public PrimaryStorageDownloadAnswer execute(PrimaryStorageDownloadCommand cmd) {
|
||||
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource PrimaryStorageDownloadCommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
try {
|
||||
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
|
||||
String primaryStroageUrl = cmd.getPrimaryStorageUrl();
|
||||
String templateUuidName =null;
|
||||
assert ((primaryStroageUrl != null) && (secondaryStorageUrl != null));
|
||||
// FIXME: paths and system vm name are hard coded
|
||||
String templateUrl = cmd.getUrl();
|
||||
String templatePath = templateUrl.replace('/', '\\');
|
||||
templatePath = templatePath.substring(4);
|
||||
if (!templatePath.endsWith(".vhd")) {
|
||||
String templateName = cmd.getName();
|
||||
templateUuidName = UUID.nameUUIDFromBytes((templateName + "@" + cmd.getPoolUuid()).getBytes()).toString();
|
||||
if (!templatePath.endsWith("\\")) {
|
||||
templatePath = templatePath + "\\";
|
||||
}
|
||||
//templatePath = templatePath + templateUuidName + ".vhd";
|
||||
templatePath = templatePath + "systemvm.vhd";
|
||||
}
|
||||
|
||||
s_logger.info("template URL: "+ templateUrl + "template name: "+ cmd.getName() + " sec storage " + secondaryStorageUrl+ " pri storage" + primaryStroageUrl);
|
||||
|
||||
StringBuilder cmdStr = new StringBuilder("cmd /c powershell.exe ");
|
||||
cmdStr.append("copy-item '");
|
||||
cmdStr.append(templatePath.toCharArray());
|
||||
cmdStr.append("' 'C:\\programdata\\Virtual Machine Manager Library Files\\VHDs\\';");
|
||||
|
||||
s_logger.info("Running command: " + cmdStr);
|
||||
Process p = Runtime.getRuntime().exec(cmdStr.toString());
|
||||
p.getOutputStream().close();
|
||||
|
||||
InputStreamReader temperrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream()));
|
||||
BufferedReader errreader = new BufferedReader(temperrReader);
|
||||
if (errreader.ready()) {
|
||||
String errorOutput = new String("");
|
||||
s_logger.info("errors found while running cmdlet: " + cmdStr.toString());
|
||||
while (true){
|
||||
String errline = errreader.readLine();
|
||||
if (errline == null) {
|
||||
break;
|
||||
}
|
||||
errorOutput = errorOutput + errline;
|
||||
}
|
||||
s_logger.info(errorOutput);
|
||||
}
|
||||
|
||||
p.getErrorStream().close();
|
||||
InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream()));
|
||||
BufferedReader reader = new BufferedReader(tempReader);
|
||||
|
||||
String output = new String("");
|
||||
|
||||
while (true){
|
||||
String line = reader.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
output = output + line;
|
||||
}
|
||||
p.getInputStream().close();
|
||||
|
||||
s_logger.info("Command output: "+ output);
|
||||
|
||||
if (output.contains("FullyQualifiedErrorId") || output.contains("Error") || output.contains("Exception")) {
|
||||
return new PrimaryStorageDownloadAnswer("Failed to copy template to SCVMM library share from secondary storage.");
|
||||
}
|
||||
|
||||
return new PrimaryStorageDownloadAnswer(templateUuidName, 0);
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
s_logger.info("Exception caught: "+e.getMessage());
|
||||
return new PrimaryStorageDownloadAnswer("Failed to copy template to SCVMM library share from secondary storage.");
|
||||
}
|
||||
}
|
||||
|
||||
protected Answer execute(CreateCommand cmd) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource CreateCommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
try {
|
||||
long volId = cmd.getVolumeId();
|
||||
String templateUrl = cmd.getTemplateUrl();;
|
||||
StorageFilerTO pool = cmd.getPool();
|
||||
DiskProfile diskchar = cmd.getDiskCharacteristics();
|
||||
|
||||
if (diskchar.getType() == Volume.Type.ROOT) {
|
||||
if (cmd.getTemplateUrl() == null) {
|
||||
//create root volume
|
||||
VolumeTO vol = new VolumeTO(cmd.getVolumeId(),
|
||||
diskchar.getType(),
|
||||
pool.getType(), pool.getUuid(), cmd.getDiskCharacteristics().getName(),
|
||||
pool.getPath(), cmd.getDiskCharacteristics().getName(), cmd.getDiskCharacteristics().getSize(),
|
||||
null);
|
||||
return new CreateAnswer(cmd, vol);
|
||||
} else {
|
||||
VolumeTO vol = new VolumeTO(cmd.getVolumeId(),
|
||||
diskchar.getType(),
|
||||
pool.getType(), pool.getUuid(), cmd.getDiskCharacteristics().getName(),
|
||||
pool.getPath(), cmd.getDiskCharacteristics().getName(), cmd.getDiskCharacteristics().getSize(), null);
|
||||
return new CreateAnswer(cmd, vol);
|
||||
}
|
||||
|
||||
} else {
|
||||
//create data volume
|
||||
String volumeUuid = "cloud.worker." + UUID.randomUUID().toString();
|
||||
VolumeTO vol = new VolumeTO(cmd.getVolumeId(),
|
||||
diskchar.getType(),
|
||||
pool.getType(), pool.getUuid(), cmd.getDiskCharacteristics().getName(),
|
||||
pool.getPath(), volumeUuid, cmd.getDiskCharacteristics().getSize(), null);
|
||||
return new CreateAnswer(cmd, vol);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected StartAnswer execute(StartCommand cmd) {
|
||||
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource StartCommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
VirtualMachineTO vmSpec = cmd.getVirtualMachine();
|
||||
String vmName = vmSpec.getName();
|
||||
State state = State.Stopped;
|
||||
String scriptFileName = vmName+ ".ps1";
|
||||
String newLine = System.getProperty("line.separator");
|
||||
String bootArgsDiskName = vmName+"-bootparams.vhd";
|
||||
String bootArgsDiskPath = "C:\\ProgramData\\Virtual Machine Manager Library Files\\VHDs\\"+bootArgsDiskName;
|
||||
|
||||
try {
|
||||
// mark VM as starting state so that sync() can know not to report stopped too early
|
||||
synchronized (_vms) {
|
||||
_vms.put(vmName, State.Starting);
|
||||
{
|
||||
// create and attach boot parameter disk
|
||||
String diskpartScriptName = vmName+"-Diskpart.txt";
|
||||
|
||||
StringBuilder cmdDiskpart = new StringBuilder("create vdisk file=\"");cmdDiskpart.append(bootArgsDiskPath.toCharArray());cmdDiskpart.append("\" maximum=10 type=expandable" + newLine);
|
||||
cmdDiskpart.append("select vdisk file=\"");cmdDiskpart.append(bootArgsDiskPath.toCharArray());cmdDiskpart.append("\"" + newLine);
|
||||
cmdDiskpart.append("attach vdisk" + newLine);
|
||||
cmdDiskpart.append("create partition primary" + newLine);
|
||||
cmdDiskpart.append("format fs=ntfs label=\"test vhd\" quick" + newLine);
|
||||
cmdDiskpart.append("assign letter="+vmName.toCharArray()[0]+ newLine);
|
||||
cmdDiskpart.append("attach vdisk" + newLine);
|
||||
|
||||
File f=new File(diskpartScriptName);
|
||||
FileOutputStream fop=new FileOutputStream(f);
|
||||
fop.write(cmdDiskpart.toString().getBytes());
|
||||
fop.flush();
|
||||
fop.close();
|
||||
|
||||
s_logger.info("Running diskpart attach command");
|
||||
Process p = Runtime.getRuntime().exec("cmd.exe /c diskpart.exe /s "+diskpartScriptName);
|
||||
p.getOutputStream().close();
|
||||
|
||||
InputStreamReader temperrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream()));
|
||||
BufferedReader errreader = new BufferedReader(temperrReader);
|
||||
|
||||
if (errreader.ready()) {
|
||||
String errorOutput = new String("");
|
||||
while (true){
|
||||
String errline = errreader.readLine();
|
||||
if (errline == null) {
|
||||
break;
|
||||
}
|
||||
errorOutput = errorOutput + errline;
|
||||
}
|
||||
s_logger.info("errors found while running diskpart command: " + errorOutput);
|
||||
}
|
||||
|
||||
p.getErrorStream().close();
|
||||
InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream()));
|
||||
BufferedReader reader = new BufferedReader(tempReader);
|
||||
|
||||
String output = new String("");
|
||||
|
||||
while (true){
|
||||
String line = reader.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
output = output + line;
|
||||
}
|
||||
p.getInputStream().close();
|
||||
s_logger.info("diskpart detahc command output: "+ output);
|
||||
}
|
||||
// wait for a while so that disk formatting is done
|
||||
Thread.sleep(60000);
|
||||
|
||||
//create boot args on the disk
|
||||
String bootArgs = vmSpec.getBootArgs();
|
||||
String Drive = vmName.substring(0,1);
|
||||
File fBootargs =new File(Drive+":\\cmdline");
|
||||
FileOutputStream fopBoot=new FileOutputStream(fBootargs);
|
||||
fopBoot.write(bootArgs.toString().getBytes());
|
||||
fopBoot.flush();
|
||||
fopBoot.close();
|
||||
|
||||
//detach the boot parameter disk
|
||||
{
|
||||
String diskpartDetachScriptName = vmName+"-Detach-Diskpart.txt";
|
||||
|
||||
StringBuilder cmdDetachDiskpart = new StringBuilder("select vdisk file=\"");
|
||||
cmdDetachDiskpart.append(bootArgsDiskPath.toCharArray());cmdDetachDiskpart.append("\"" + newLine);
|
||||
cmdDetachDiskpart.append("detach vdisk" + newLine);
|
||||
|
||||
File fd=new File(diskpartDetachScriptName);
|
||||
FileOutputStream fdop=new FileOutputStream(fd);
|
||||
fdop.write(cmdDetachDiskpart.toString().getBytes());
|
||||
fdop.flush();
|
||||
fdop.close();
|
||||
|
||||
s_logger.info("Running diskpart detach command");
|
||||
Process pd = Runtime.getRuntime().exec("cmd.exe /c diskpart.exe /s "+diskpartDetachScriptName);
|
||||
pd.getOutputStream().close();
|
||||
InputStreamReader temperrReader1 = new InputStreamReader(new BufferedInputStream(pd.getErrorStream()));
|
||||
BufferedReader errreader1 = new BufferedReader(temperrReader1);
|
||||
|
||||
if (errreader1.ready()) {
|
||||
String errorOutput = new String("");
|
||||
while (true){
|
||||
String errline = errreader1.readLine();
|
||||
if (errline == null) {
|
||||
break;
|
||||
}
|
||||
errorOutput = errorOutput + errline;
|
||||
}
|
||||
s_logger.info("errors found while running diskpart detach command: " + errorOutput);
|
||||
}
|
||||
|
||||
pd.getErrorStream().close();
|
||||
InputStreamReader tempReader1 = new InputStreamReader(new BufferedInputStream(pd.getInputStream()));
|
||||
BufferedReader reader1 = new BufferedReader(tempReader1);
|
||||
|
||||
String output1 = new String("");
|
||||
|
||||
while (true){
|
||||
String line = reader1.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
output1 = output1 + line;
|
||||
}
|
||||
|
||||
pd.getInputStream().close();
|
||||
s_logger.info("diskpart detach command output: "+ output1);
|
||||
}
|
||||
}
|
||||
|
||||
UUID id = UUID.randomUUID();
|
||||
String hwProfileId = id.toString();
|
||||
|
||||
StringBuilder cmdStr = new StringBuilder("Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager;" + newLine);
|
||||
cmdStr.append("Get-VMMServer -ComputerName localhost;" + newLine);
|
||||
cmdStr.append("$JobGroupId = [Guid]::NewGuid().ToString();" + newLine);
|
||||
cmdStr.append("$hwProfileId = [Guid]::NewGuid().ToString(); " + newLine);
|
||||
cmdStr.append("$CPUType = Get-CPUType -VMMServer localhost | where {$_.Name -eq " + "'1.20 GHz Athlon MP'}; " + newLine);
|
||||
cmdStr.append("$ISO = Get-ISO -VMMServer localhost | where { $_.Name -match \"systemvm\" }; " + newLine);
|
||||
cmdStr.append("$VMHost = Get-VMHost -VMMServer localhost | where {$_.Name -eq \"HYPERVHOST.hypervdc.intranet.lab.vmops.com\"}; " + newLine);
|
||||
cmdStr.append("$VNetwork = Get-VirtualNetwork -VMHost $VMHost -Name \"public\"; " + newLine);
|
||||
cmdStr.append("New-VirtualNetworkAdapter -VMMServer localhost -JobGroup $JobGroupID -PhysicalAddressType Dynamic -VirtualNetwork $vnetwork; " + newLine);
|
||||
cmdStr.append("New-VirtualNetworkAdapter -VMMServer localhost -JobGroup $JobGroupID -PhysicalAddressType Dynamic -VirtualNetwork $vnetwork; " + newLine);
|
||||
cmdStr.append("New-VirtualNetworkAdapter -VMMServer localhost -JobGroup $JobGroupID -PhysicalAddressType Dynamic -VirtualNetwork $vnetwork; " + newLine);
|
||||
cmdStr.append("New-VirtualDVDDrive -VMMServer localhost -JobGroup $JobGroupID -Bus 1 -LUN 0 -ISO $ISO ; " + newLine);
|
||||
cmdStr.append("New-HardwareProfile -VMMServer localhost -JobGroup $JobGroupID -Owner \"HYPERVDC\\Administrator\" -CPUType $CPUType -Name $hwProfileId");
|
||||
cmdStr.append(" -Description \"Profile used to create a VM/Template\"" +
|
||||
" -CPUCount 1 -MemoryMB 512 -RelativeWeight 100 -HighlyAvailable $true -NumLock $false -BootOrder \"CD\", " +
|
||||
"\"IdeHardDrive\", \"PxeBoot\", \"Floppy\" -LimitCPUFunctionality $false -LimitCPUForMigration $false; " + newLine);
|
||||
|
||||
cmdStr.append("$JobGroupId = [Guid]::NewGuid().ToString(); " + newLine);
|
||||
|
||||
//refresh library share
|
||||
cmdStr.append("$share = Get-LibraryShare;"+newLine);
|
||||
cmdStr.append("Refresh-LibraryShare -LibraryShare $share;"+newLine);
|
||||
|
||||
// create root disk
|
||||
cmdStr.append("$VirtualHardDisk1 = Get-VirtualHardDisk -VMMServer localhost | where {$_.Location -eq \"\\\\scvmm.hypervdc.intranet.lab.vmops.com\\MSSCVMMLibrary\\VHDs\\systemvm.vhd\"} | where {$_.HostName -eq \"scvmm.hypervdc.intranet.lab.vmops.com\"}" + newLine);
|
||||
cmdStr.append("New-VirtualDiskDrive -VMMServer localhost -JobGroup $JobGroupID -IDE -Bus 0 -LUN 0 -VirtualHardDisk $VirtualHardDisk1 -Filename \"");
|
||||
cmdStr.append(vmName.toCharArray());
|
||||
cmdStr.append("-systemvm.vhd\"; " + newLine);
|
||||
|
||||
// create boot param data disk
|
||||
cmdStr.append("$VirtualHardDisk2 = Get-VirtualHardDisk -VMMServer localhost " +
|
||||
" | where {$_.Location -eq \"\\\\scvmm.hypervdc.intranet.lab.vmops.com\\MSSCVMMLibrary\\VHDs\\");
|
||||
cmdStr.append(bootArgsDiskName.toCharArray());
|
||||
cmdStr.append("\" } | where {$_.HostName -eq \"scvmm.hypervdc.intranet.lab.vmops.com\"}" + newLine);
|
||||
cmdStr.append("New-VirtualDiskDrive -VMMServer localhost -JobGroup $JobGroupID -IDE -Bus 0 -LUN 1 -VirtualHardDisk $VirtualHardDisk2 -Filename \"");
|
||||
cmdStr.append(bootArgsDiskName.toCharArray());
|
||||
cmdStr.append("\";"+newLine);
|
||||
|
||||
cmdStr.append("$HardwareProfile = Get-HardwareProfile -VMMServer localhost | where {$_.Name -eq $hwProfileId};" + newLine);
|
||||
cmdStr.append("$OperatingSystem = Get-OperatingSystem -VMMServer localhost | where {$_.Name -eq 'Other Linux (32 bit)'};" + newLine);
|
||||
|
||||
cmdStr.append("New-VM -VMMServer localhost -Name \"");
|
||||
cmdStr.append(vmName.toCharArray());
|
||||
|
||||
cmdStr.append("\" -Description \"\" -Owner \"HYPERVDC\\Administrator\" -VMHost $VMHost -Path \"C:\\ClusterStorage\\Volume1\" -HardwareProfile $HardwareProfile " +
|
||||
" -JobGroup $JobGroupID" +
|
||||
" -OperatingSystem $OperatingSystem -RunAsSystem -StartVM -StartAction NeverAutoTurnOnVM -StopAction SaveVM;" + newLine);
|
||||
|
||||
File f=new File(scriptFileName);
|
||||
FileOutputStream fop=new FileOutputStream(f);
|
||||
fop.write(cmdStr.toString().getBytes());
|
||||
fop.flush();
|
||||
fop.close();
|
||||
s_logger.info("Running command: " + cmdStr);
|
||||
Process p = Runtime.getRuntime().exec("cmd.exe /c Powershell -Command \" & '.\\" + scriptFileName +"'\"");
|
||||
p.getOutputStream().close();
|
||||
|
||||
InputStreamReader temperrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream()));
|
||||
BufferedReader errreader = new BufferedReader(temperrReader);
|
||||
|
||||
if (errreader.ready()) {
|
||||
String errorOutput = new String("");
|
||||
while (true){
|
||||
String errline = errreader.readLine();
|
||||
if (errline == null) {
|
||||
break;
|
||||
}
|
||||
errorOutput = errorOutput + errline;
|
||||
}
|
||||
s_logger.info("errors found while running cmdlet to create VM: " + errorOutput);
|
||||
}
|
||||
|
||||
p.getErrorStream().close();
|
||||
InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream()));
|
||||
BufferedReader reader = new BufferedReader(tempReader);
|
||||
|
||||
String output = new String("");
|
||||
|
||||
while (true){
|
||||
String line = reader.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
output = output + line;
|
||||
}
|
||||
p.getInputStream().close();
|
||||
|
||||
s_logger.info("vm create cmmdlet output: "+ output);
|
||||
|
||||
if (output.contains("FullyQualifiedErrorId") || output.contains("Error") || output.contains("Exception")) {
|
||||
s_logger.info("No errors found in running cmdlet "+ cmdStr.toString());
|
||||
return new StartAnswer(cmd, "Failed to start VM");
|
||||
}
|
||||
|
||||
state = State.Running;
|
||||
return new StartAnswer(cmd);
|
||||
} catch (Exception e){
|
||||
return new StartAnswer(cmd, "Failed to start VM");
|
||||
} finally {
|
||||
//delete the PS script file
|
||||
//File f=new File(".\\"+scriptFileName);
|
||||
//f.delete();
|
||||
synchronized (_vms) {
|
||||
if (state != State.Stopped) {
|
||||
_vms.put(vmName, state);
|
||||
} else {
|
||||
_vms.remove(vmName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Answer execute(DhcpEntryCommand cmd) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource DhcpEntryCommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
String args = " " + cmd.getVmMac();
|
||||
args += " " + cmd.getVmIpAddress();
|
||||
args += " " + cmd.getVmName();
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/edithosts.sh " + args);
|
||||
}
|
||||
|
||||
try {
|
||||
Pair<Boolean, String> result = SshHelper.sshExecute(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), DEFAULT_DOMR_SSHPORT, "root",
|
||||
new File("id_rsa.cloud"), null, "/root/edithosts.sh " + args);
|
||||
|
||||
if (!result.first()) {
|
||||
s_logger.error("dhcp_entry command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)
|
||||
+ " failed, message: " + result.second());
|
||||
|
||||
return new Answer(cmd, false, "DhcpEntry failed due to " + result.second());
|
||||
}
|
||||
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("dhcp_entry command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed");
|
||||
}
|
||||
|
||||
} catch (Throwable e) {
|
||||
s_logger.error("Unexpected exception ", e);
|
||||
return new Answer(cmd, false, "DhcpEntry failed due to exception");
|
||||
}
|
||||
|
||||
return new Answer(cmd);
|
||||
}
|
||||
|
||||
protected CheckSshAnswer execute(CheckSshCommand cmd) {
|
||||
String vmName = cmd.getName();
|
||||
String privateIp = cmd.getIp();
|
||||
int cmdPort = cmd.getPort();
|
||||
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Ping VM:" + cmd.getName() + " IP:" + privateIp + " port:" + cmdPort);
|
||||
}
|
||||
return new CheckSshAnswer(cmd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAgentControl(IAgentControl agentControl) {
|
||||
this.agentControl = agentControl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StartupCommand[] initialize() {
|
||||
|
||||
s_logger.info("recieved initialize request for cluster:" + _clusterId);
|
||||
List<String> vmHostList = getHostsInCluster(_clusterId);
|
||||
|
||||
if (vmHostList.size() == 0) {
|
||||
s_logger.info("cluster is not recognized or zero instances in the cluster");
|
||||
}
|
||||
|
||||
StartupCommand[] answerCmds = new StartupCommand[vmHostList.size()];
|
||||
|
||||
int index =0;
|
||||
for (String hostName: vmHostList) {
|
||||
s_logger.info("Node :" + hostName);
|
||||
StartupRoutingCommand cmd = new StartupRoutingCommand();
|
||||
answerCmds[index] = cmd;
|
||||
fillHostInfo(cmd,hostName);
|
||||
index++;
|
||||
}
|
||||
|
||||
s_logger.info("response sent to initialize request for cluster:" + _clusterId);
|
||||
return answerCmds;
|
||||
}
|
||||
|
||||
protected void fillHostInfo(StartupRoutingCommand cmd, String hostName) {
|
||||
|
||||
Map<String, String> details = cmd.getHostDetails();
|
||||
if (details == null) {
|
||||
details = new HashMap<String, String>();
|
||||
}
|
||||
|
||||
try {
|
||||
fillHostHardwareInfo(cmd);
|
||||
fillHostNetworkInfo(cmd);
|
||||
fillHostDetailsInfo(details);
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Exception while retrieving host info ", e);
|
||||
throw new CloudRuntimeException("Exception while retrieving host info");
|
||||
}
|
||||
|
||||
cmd.setName(hostName);
|
||||
cmd.setHostDetails(details);
|
||||
cmd.setGuid(_guid);
|
||||
cmd.setDataCenter(_dcId);
|
||||
cmd.setPod(_podId);
|
||||
cmd.setCluster(_clusterId);
|
||||
cmd.setHypervisorType(HypervisorType.Hyperv);
|
||||
}
|
||||
|
||||
private void fillHostDetailsInfo(Map<String, String> details) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
private Answer execute(GetHostStatsCommand cmd) {
|
||||
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource GetHostStatsCommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
try {
|
||||
// FIXME: get the actual host stats by running powershell cmdlet. This is just for prototype.
|
||||
HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), 0, 10000, 10000,
|
||||
"host", 2*1024*1024, 1*1024*1024, 1*1024*1024, 0);
|
||||
s_logger.info("returning stats :" + 2*1024*1024 + " " + 1*1024*1024 + " " + 1*1024*1024);
|
||||
return new GetHostStatsAnswer(cmd, hostStats);
|
||||
} catch (Exception e) {
|
||||
HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), 0, 0, 0,
|
||||
"host", 0, 0, 0, 0);
|
||||
String msg = "Unable to execute GetHostStatsCommand due to exception " + e.getMessage();
|
||||
s_logger.error(msg, e);
|
||||
return new GetHostStatsAnswer(cmd, hostStats);
|
||||
}
|
||||
}
|
||||
|
||||
protected Answer execute(ModifyStoragePoolCommand cmd) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource ModifyStoragePoolCommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
try {
|
||||
StorageFilerTO pool = cmd.getPool();
|
||||
s_logger.info("Primary storage pool details: " + pool.getHost() + " " + pool.getPath());
|
||||
Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
|
||||
// FIXME: get the actual storage capacity and storage stats of CSV volume
|
||||
// by running powershell cmdlet. This hardcoding just for prototype.
|
||||
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd,
|
||||
1024*1024*1024*1024L, 512*1024*1024*1024L, tInfo);
|
||||
|
||||
return answer;
|
||||
} catch (Throwable e) {
|
||||
return new Answer(cmd, false, "Unable to execute ModifyStoragePoolCommand due to exception " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected Answer execute(GetStorageStatsCommand cmd) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing GetStorageStatsCommand command: " + _gson.toJson(cmd));
|
||||
}
|
||||
// FIXME: get the actual storage capacity and storage stats of CSV volume
|
||||
return new GetStorageStatsAnswer(cmd, 1024*1024*1024*1024L, 512*1024*1024*1024L);
|
||||
}
|
||||
|
||||
private void fillHostHardwareInfo(StartupRoutingCommand cmd) throws RemoteException {
|
||||
try {
|
||||
// FIXME: get the actual host capacity by running cmdlet.This hardcoding just for prototype
|
||||
cmd.setCaps("hvm");
|
||||
cmd.setDom0MinMemory(0);
|
||||
cmd.setSpeed(100000);
|
||||
cmd.setCpus(6);
|
||||
long ram = new Long("211642163904");
|
||||
cmd.setMemory(ram);
|
||||
} catch (Throwable e) {
|
||||
s_logger.error("Unable to query host network info due to exception ", e);
|
||||
throw new CloudRuntimeException("Unable to query host network info due to exception");
|
||||
}
|
||||
}
|
||||
|
||||
private void fillHostNetworkInfo(StartupRoutingCommand cmd) throws RemoteException {
|
||||
try {
|
||||
// FIXME: get the actual host and storage IP by running cmdlet.This hardcoding just for prototype
|
||||
cmd.setPrivateIpAddress("192.168.154.236");
|
||||
cmd.setPrivateNetmask("255.255.255.0");
|
||||
cmd.setPrivateMacAddress("00:16:3e:77:e2:a0");
|
||||
|
||||
cmd.setStorageIpAddress("192.168.154.36");
|
||||
cmd.setStorageNetmask("255.255.255.0");
|
||||
cmd.setStorageMacAddress("00:16:3e:77:e2:a0");
|
||||
} catch (Throwable e) {
|
||||
s_logger.error("Unable to query host network info due to exception ", e);
|
||||
throw new CloudRuntimeException("Unable to query host network info due to exception");
|
||||
}
|
||||
}
|
||||
|
||||
private List <String> getHostsInCluster(String clusterName)
|
||||
{
|
||||
List<String> hypervHosts = new ArrayList<String>();
|
||||
|
||||
try {
|
||||
//StringBuilder cmd = new StringBuilder("cmd /c powershell.exe -OutputFormat XML ");
|
||||
StringBuilder cmd = new StringBuilder("cmd /c powershell.exe ");
|
||||
cmd.append("-Command Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager; ");
|
||||
cmd.append("Get-VMMServer -ComputerName localhost; ");
|
||||
cmd.append("Get-VMHostCluster ");
|
||||
cmd.append(clusterName.toCharArray());
|
||||
|
||||
Process p = Runtime.getRuntime().exec(cmd.toString());
|
||||
p.getOutputStream().close();
|
||||
|
||||
InputStreamReader temperrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream()));
|
||||
BufferedReader errreader = new BufferedReader(temperrReader);
|
||||
if (errreader.ready()) {
|
||||
String errorOutput = new String("");
|
||||
s_logger.info("errors found while running cmdlet Get-VMHostCluster");
|
||||
while (true){
|
||||
String errline = errreader.readLine();
|
||||
if (errline == null) {
|
||||
break;
|
||||
}
|
||||
errorOutput = errorOutput + errline;
|
||||
}
|
||||
s_logger.info(errorOutput);
|
||||
} else {
|
||||
s_logger.info("No errors found in running cmdlet:" + cmd);
|
||||
}
|
||||
|
||||
p.getErrorStream().close();
|
||||
/*
|
||||
InputStream in = (InputStream) p.getInputStream();
|
||||
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||
XMLStreamReader parser = factory.createXMLStreamReader(in);
|
||||
|
||||
while(parser.hasNext()) {
|
||||
|
||||
int eventType = parser.next();
|
||||
switch (eventType) {
|
||||
|
||||
case START_ELEMENT:
|
||||
// Do something
|
||||
break;
|
||||
case END_ELEMENT:
|
||||
// Do something
|
||||
break;
|
||||
// And so on ...
|
||||
}
|
||||
}
|
||||
parser.close();
|
||||
*/
|
||||
|
||||
InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream()));
|
||||
BufferedReader reader = new BufferedReader(tempReader);
|
||||
|
||||
String output = new String("");
|
||||
|
||||
while (true){
|
||||
String line = reader.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
output = output + line;
|
||||
}
|
||||
|
||||
String nodesListStr = output.substring(output.indexOf("Nodes"));
|
||||
nodesListStr = nodesListStr.substring(nodesListStr.indexOf('{', 0)+1, nodesListStr.indexOf('}', 0));
|
||||
String[] nodesList = nodesListStr.split(",");
|
||||
|
||||
for (String node : nodesList) {
|
||||
hypervHosts.add(node);
|
||||
}
|
||||
|
||||
p.getInputStream().close();
|
||||
} catch (Exception e)
|
||||
{
|
||||
s_logger.info("Exception caught: "+e.getMessage());
|
||||
}
|
||||
return hypervHosts;
|
||||
}
|
||||
|
||||
protected HashMap<String, State> sync() {
|
||||
HashMap<String, State> changes = new HashMap<String, State>();
|
||||
|
||||
try {
|
||||
synchronized (_vms) {
|
||||
}
|
||||
|
||||
} catch (Throwable e) {
|
||||
s_logger.error("Unable to perform sync information collection process at this point due to exception ", e);
|
||||
return null;
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PingCommand getCurrentStatus(long id) {
|
||||
HashMap<String, State> newStates = sync();
|
||||
if (newStates == null) {
|
||||
newStates = new HashMap<String, State>();
|
||||
}
|
||||
PingRoutingCommand cmd = new PingRoutingCommand(com.cloud.host.Host.Type.Routing, id, newStates);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params)
|
||||
throws ConfigurationException {
|
||||
|
||||
_dcId = params.get("zone").toString();
|
||||
_podId= params.get("pod").toString();
|
||||
_clusterId = params.get("cluster").toString();
|
||||
_guid = params.get("guid").toString();
|
||||
|
||||
boolean success = super.configure(name, params);
|
||||
if (! success) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultScriptsDir() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfigParams(Map<String, Object> params) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getConfigParams() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRunLevel() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRunLevel(int level) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
@ -125,11 +125,6 @@
|
||||
<property name="name" value="Bare Metal Agent"/>
|
||||
</bean>
|
||||
|
||||
<bean id="HypervServerDiscoverer" class="com.cloud.hypervisor.hyperv.HypervServerDiscoverer">
|
||||
<property name="name" value="SCVMMServer"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="FirstFitPlanner" class="com.cloud.deploy.FirstFitPlanner">
|
||||
<property name="name" value="First Fit"/>
|
||||
</bean>
|
||||
@ -188,10 +183,6 @@
|
||||
<property name="name" value="BareMetalGuru"/>
|
||||
</bean>
|
||||
|
||||
<bean id="HypervGuru" class="com.cloud.hypervisor.guru.HypervGuru">
|
||||
<property name="name" value="HypervGuru"/>
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
DAO with customized configuration
|
||||
-->
|
||||
|
||||
@ -113,7 +113,6 @@ under the License.
|
||||
<adapter name="SecondaryStorage" class="com.cloud.storage.secondary.SecondaryStorageDiscoverer"/>
|
||||
<adapter name="KVM Agent" class="com.cloud.hypervisor.kvm.discoverer.KvmServerDiscoverer"/>
|
||||
<adapter name="Bare Metal Agent" class="com.cloud.baremetal.BareMetalDiscoverer"/>
|
||||
<adapter name="SCVMMServer" class="com.cloud.hypervisor.hyperv.HypervServerDiscoverer"/>
|
||||
<adapter name="Ovm Discover" class="com.cloud.ovm.hypervisor.OvmDiscoverer" />
|
||||
</adapters>
|
||||
<adapters key="com.cloud.deploy.DeploymentPlanner">
|
||||
@ -147,7 +146,6 @@ under the License.
|
||||
<adapter name="XenServerGuru" class="com.cloud.hypervisor.XenServerGuru"/>
|
||||
<adapter name="KVMGuru" class="com.cloud.hypervisor.KVMGuru"/>
|
||||
<adapter name="BareMetalGuru" class="com.cloud.baremetal.BareMetalGuru"/>
|
||||
<adapter name="HypervGuru" class="com.cloud.hypervisor.guru.HypervGuru"/>
|
||||
<adapter name="OvmGuru" class="com.cloud.ovm.hypervisor.OvmGuru" />
|
||||
</adapters>
|
||||
<adapters key="com.cloud.agent.StartupCommandProcessor">
|
||||
|
||||
@ -202,7 +202,7 @@ public enum Config {
|
||||
CPUOverprovisioningFactor("Advanced", ManagementServer.class, String.class, "cpu.overprovisioning.factor", "1", "Used for CPU overprovisioning calculation; available CPU will be (actualCpuCapacity * cpu.overprovisioning.factor)", null, ConfigurationParameterScope.cluster.toString()),
|
||||
MemOverprovisioningFactor("Advanced", ManagementServer.class, String.class, "mem.overprovisioning.factor", "1", "Used for memory overprovisioning calculation", null, ConfigurationParameterScope.cluster.toString()),
|
||||
LinkLocalIpNums("Advanced", ManagementServer.class, Integer.class, "linkLocalIp.nums", "10", "The number of link local ip that needed by domR(in power of 2)", null),
|
||||
HypervisorList("Advanced", ManagementServer.class, String.class, "hypervisor.list", HypervisorType.KVM + "," + HypervisorType.XenServer + "," + HypervisorType.VMware + "," + HypervisorType.BareMetal + "," + HypervisorType.Ovm + "," + HypervisorType.LXC, "The list of hypervisors that this deployment will use.", "hypervisorList"),
|
||||
HypervisorList("Advanced", ManagementServer.class, String.class, "hypervisor.list", HypervisorType.Hyperv + "," + HypervisorType.KVM + "," + HypervisorType.XenServer + "," + HypervisorType.VMware + "," + HypervisorType.BareMetal + "," + HypervisorType.Ovm + "," + HypervisorType.LXC, "The list of hypervisors that this deployment will use.", "hypervisorList"),
|
||||
ManagementHostIPAdr("Advanced", ManagementServer.class, String.class, "host", "localhost", "The ip address of management server", null),
|
||||
ManagementNetwork("Advanced", ManagementServer.class, String.class, "management.network.cidr", null, "The cidr of management server network", null),
|
||||
EventPurgeDelay("Advanced", ManagementServer.class, Integer.class, "event.purge.delay", "15", "Events older than specified number days will be purged. Set this value to 0 to never delete events", null),
|
||||
|
||||
@ -1,73 +0,0 @@
|
||||
// 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.guru;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.HypervisorGuru;
|
||||
import com.cloud.hypervisor.HypervisorGuruBase;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.storage.GuestOSVO;
|
||||
import com.cloud.storage.dao.GuestOSDao;
|
||||
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
/**
|
||||
* Implementation of Hypervisor guru for Hyper-Vr
|
||||
**/
|
||||
|
||||
@Local(value=HypervisorGuru.class)
|
||||
public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru {
|
||||
|
||||
@Inject GuestOSDao _guestOsDao;
|
||||
@Inject HostDao _hostDao;
|
||||
|
||||
protected HypervGuru() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HypervisorType getHypervisorType() {
|
||||
return HypervisorType.Hyperv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends VirtualMachine> VirtualMachineTO implement(VirtualMachineProfile<T> vm) {
|
||||
VirtualMachineTO to = toVirtualMachineTO(vm);
|
||||
to.setBootloader(BootloaderType.HVM);
|
||||
|
||||
// Determine the VM's OS description
|
||||
GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId());
|
||||
to.setOs(guestOS.getDisplayName());
|
||||
return to;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCommandHostDelegation(long hostId, Command cmd) {
|
||||
return hostId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trackVmHostChange() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1,243 +0,0 @@
|
||||
// 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;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.StartupVMMAgentCommand;
|
||||
import com.cloud.agent.transport.Request;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.dc.ClusterDetailsDao;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.exception.DiscoveryException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.hypervisor.hyperv.resource.HypervDummyResourceBase;
|
||||
import com.cloud.resource.Discoverer;
|
||||
import com.cloud.resource.DiscovererBase;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.utils.nio.HandlerFactory;
|
||||
import com.cloud.utils.nio.Link;
|
||||
import com.cloud.utils.nio.NioClient;
|
||||
import com.cloud.utils.nio.Task;
|
||||
import com.cloud.utils.nio.Task.Type;
|
||||
|
||||
@Local(value=Discoverer.class)
|
||||
public class HypervServerDiscoverer extends DiscovererBase implements Discoverer, HandlerFactory{
|
||||
private static final Logger s_logger = Logger.getLogger(HypervServerDiscoverer.class);
|
||||
private int _waitTime = 1;
|
||||
|
||||
@Inject ClusterDao _clusterDao;
|
||||
@Inject AlertManager _alertMgr;
|
||||
@Inject ClusterDetailsDao _clusterDetailsDao;
|
||||
@Inject HostDao _hostDao = null;
|
||||
@Inject ResourceManager _resourceMgr;
|
||||
Link _link;
|
||||
|
||||
@SuppressWarnings("static-access")
|
||||
@Override
|
||||
public Map<? extends ServerResource, Map<String, String>> find(long dcId, Long podId, Long clusterId, URI url,
|
||||
String username, String password, List<String> hostTags) throws DiscoveryException {
|
||||
|
||||
if(s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Discover host. dc: " + dcId + ", pod: " + podId + ", cluster: " + clusterId + ", uri host: " + url.getHost());
|
||||
}
|
||||
|
||||
if(podId == null) {
|
||||
if(s_logger.isInfoEnabled()) {
|
||||
s_logger.info("No pod is assigned, skipping the discovery in Hyperv discoverer");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!url.getScheme().equals("http")) {
|
||||
String msg = "urlString is not http so HypervServerDiscoverer taking care of the discovery for this: " + url;
|
||||
s_logger.debug(msg);
|
||||
return null;
|
||||
}
|
||||
|
||||
ClusterVO cluster = _clusterDao.findById(clusterId);
|
||||
if(cluster == null || cluster.getHypervisorType() != HypervisorType.Hyperv) {
|
||||
if(s_logger.isInfoEnabled()) {
|
||||
s_logger.info("invalid cluster id or cluster is not for Hyperv hypervisors");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
String clusterName = cluster.getName();
|
||||
|
||||
try {
|
||||
|
||||
String hostname = url.getHost();
|
||||
InetAddress ia = InetAddress.getByName(hostname);
|
||||
String agentIp = ia.getHostAddress();
|
||||
String guid = UUID.nameUUIDFromBytes(agentIp.getBytes()).toString();
|
||||
String guidWithTail = guid + "-HypervResource";/*tail added by agent.java*/
|
||||
if (_resourceMgr.findHostByGuid(guidWithTail) != null) {
|
||||
s_logger.debug("Skipping " + agentIp + " because " + guidWithTail + " is already in the database.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// bootstrap SCVMM agent to connect back to management server
|
||||
NioClient _connection = new NioClient("HypervAgentClient", url.getHost(), 9000, 1, this);
|
||||
_connection.start();
|
||||
|
||||
StartupVMMAgentCommand cmd = new StartupVMMAgentCommand(
|
||||
dcId,
|
||||
podId,
|
||||
clusterName,
|
||||
guid,
|
||||
InetAddress.getLocalHost().getHostAddress(),
|
||||
"8250",
|
||||
HypervServerDiscoverer.class.getPackage().getImplementationVersion());
|
||||
|
||||
// send bootstrap command to agent running on SCVMM host
|
||||
s_logger.info("sending bootstrap request to SCVMM agent on host "+ url.getHost());
|
||||
Request request = new Request(0, 0, cmd, false);
|
||||
|
||||
// :FIXME without sleep link.send failing why??????
|
||||
Thread.currentThread().sleep(5000);
|
||||
_link.send(request.toBytes());
|
||||
|
||||
//wait for SCVMM agent to connect back
|
||||
HostVO connectedHost = waitForHostConnect(dcId, podId, clusterId, guidWithTail);
|
||||
if (connectedHost == null)
|
||||
{
|
||||
s_logger.info("SCVMM agent did not connect back after sending bootstrap request");
|
||||
return null;
|
||||
}
|
||||
|
||||
//disconnect
|
||||
s_logger.info("SCVMM agent connected back after sending bootstrap request");
|
||||
_connection.stop();
|
||||
|
||||
Map<HypervDummyResourceBase, Map<String, String>> resources = new HashMap<HypervDummyResourceBase, Map<String, String>>();
|
||||
Map<String, String> details = new HashMap<String, String>();
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
HypervDummyResourceBase resource = new HypervDummyResourceBase();
|
||||
|
||||
details.put("url", url.getHost());
|
||||
details.put("username", username);
|
||||
details.put("password", password);
|
||||
resources.put(resource, details);
|
||||
|
||||
params.put("zone", Long.toString(dcId));
|
||||
params.put("pod", Long.toString(podId));
|
||||
params.put("cluster", Long.toString(clusterId));
|
||||
|
||||
resource.configure("Hyperv", params);
|
||||
return resources;
|
||||
} catch (ConfigurationException e) {
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + url.getHost(), "Error is " + e.getMessage());
|
||||
s_logger.warn("Unable to instantiate " + url.getHost(), e);
|
||||
} catch (UnknownHostException e) {
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + url.getHost(), "Error is " + e.getMessage());
|
||||
s_logger.warn("Unable to instantiate " + url.getHost(), e);
|
||||
} catch (Exception e) {
|
||||
s_logger.info("exception " + e.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postDiscovery(List<HostVO> hosts, long msId) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchHypervisor(String hypervisor) {
|
||||
if(hypervisor == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Hypervisor.HypervisorType.VMware.toString().equalsIgnoreCase(hypervisor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hypervisor.HypervisorType getHypervisorType() {
|
||||
return Hypervisor.HypervisorType.Hyperv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task create(Type type, Link link, byte[] data) {
|
||||
_link = link;
|
||||
return new BootStrapTakHandler(type, link, data);
|
||||
}
|
||||
|
||||
private HostVO waitForHostConnect(long dcId, long podId, long clusterId, String guid) {
|
||||
for (int i = 0; i < _waitTime *2; i++) {
|
||||
List<HostVO> hosts = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.Routing, clusterId, podId, dcId);
|
||||
for (HostVO host : hosts) {
|
||||
if (host.getGuid().equalsIgnoreCase(guid)) {
|
||||
return host;
|
||||
}
|
||||
}
|
||||
try {
|
||||
Thread.sleep(30000);
|
||||
} catch (InterruptedException e) {
|
||||
s_logger.debug("Failed to sleep: " + e.toString());
|
||||
}
|
||||
}
|
||||
s_logger.debug("Timeout, to wait for the host connecting to mgt svr, assuming it is failed");
|
||||
return null;
|
||||
}
|
||||
|
||||
// class to handle the bootstrap command from the management server
|
||||
public class BootStrapTakHandler extends Task {
|
||||
|
||||
public BootStrapTakHandler(Task.Type type, Link link, byte[] data) {
|
||||
super(type, link, data);
|
||||
s_logger.info("created new BootStrapTakHandler");
|
||||
}
|
||||
|
||||
protected void processRequest(final Link link, final Request request) {
|
||||
final Command[] cmds = request.getCommands();
|
||||
Command cmd = cmds[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doTask(Task task) throws Exception {
|
||||
final Type type = task.getType();
|
||||
s_logger.info("recieved task of type "+type.toString() +" in BootStrapTakHandler");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -541,12 +541,6 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
for (Map.Entry<? extends ServerResource, Map<String, String>> entry : resources.entrySet()) {
|
||||
ServerResource resource = entry.getKey();
|
||||
|
||||
// For Hyper-V, we are here means agent have already started
|
||||
// and connected to management server
|
||||
if (hypervisorType == Hypervisor.HypervisorType.Hyperv) {
|
||||
break;
|
||||
}
|
||||
|
||||
HostVO host = (HostVO) createHostAndAgent(resource, entry.getValue(), true, null, false);
|
||||
if (host != null) {
|
||||
hosts.add(host);
|
||||
|
||||
@ -1046,10 +1046,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
||||
buf.append(" guid=").append(profile.getVirtualMachine().getHostName());
|
||||
|
||||
if (_configDao.isPremium()) {
|
||||
if (profile.getHypervisorType() == HypervisorType.Hyperv) {
|
||||
s_logger.debug("Hyperv hypervisor configured, telling the ssvm to load the CifsSecondaryStorageResource");
|
||||
buf.append(" resource=com.cloud.storage.resource.CifsSecondaryStorageResource");
|
||||
} else if (profile.getHypervisorType() == HypervisorType.VMware) {
|
||||
if (profile.getHypervisorType() == HypervisorType.VMware) {
|
||||
s_logger.debug("VmWare hypervisor configured, telling the ssvm to load the PremiumSecondaryStorageResource");
|
||||
buf.append(" resource=com.cloud.storage.resource.PremiumSecondaryStorageResource");
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user