Revert "CLOUDSTACK-658 - Adding Scalevm command and XS related changes"

This reverts commit e0019eccd997d9b2b3ff9395bcd99f821f5121db.
This commit is contained in:
Nitin Mehta 2013-03-04 23:32:52 +05:30
parent 43c7126c07
commit b12aebefee
18 changed files with 161 additions and 676 deletions

View File

@ -59,7 +59,6 @@ public class EventTypes {
public static final String EVENT_VM_REBOOT = "VM.REBOOT";
public static final String EVENT_VM_UPDATE = "VM.UPDATE";
public static final String EVENT_VM_UPGRADE = "VM.UPGRADE";
public static final String EVENT_VM_SCALE = "VM.SCALE";
public static final String EVENT_VM_RESETPASSWORD = "VM.RESETPASSWORD";
public static final String EVENT_VM_RESETSSHKEY = "VM.RESETSSHKEY";
public static final String EVENT_VM_MIGRATE = "VM.MIGRATE";

View File

@ -23,7 +23,18 @@ import javax.naming.InsufficientResourcesException;
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
import org.apache.cloudstack.api.command.user.vm.*;
import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
@ -390,7 +401,4 @@ public interface UserVmService {
VirtualMachine vmStorageMigration(Long vmId, StoragePool destPool);
UserVm restoreVM(RestoreVMCmd cmd);
UserVm upgradeVirtualMachine(ScaleVMCmd scaleVMCmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException;
}

View File

@ -41,7 +41,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
Destroyed(false, "VM is marked for destroy."),
Expunging(true, "VM is being expunged."),
Migrating(true, "VM is being migrated. host id holds to from host"),
Reconfiguring(true, "VM is being reconfigured to a new service offering"),
Error(false, "VM is in error"),
Unknown(false, "VM state is unknown."),
Shutdowned(false, "VM is shutdowned from inside");
@ -96,9 +95,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
s_fsm.addTransition(State.Running, VirtualMachine.Event.StopRequested, State.Stopping);
s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportMigrated, State.Running);
s_fsm.addTransition(State.Running, VirtualMachine.Event.ReconfiguringRequested, State.Reconfiguring);
s_fsm.addTransition(State.Reconfiguring, VirtualMachine.Event.OperationSucceeded, State.Running);
s_fsm.addTransition(State.Reconfiguring, VirtualMachine.Event.OperationFailed, State.Running);
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.MigrationRequested, State.Migrating);
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.OperationSucceeded, State.Running);
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.OperationFailed, State.Running);
@ -180,8 +176,7 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
AgentReportShutdowned,
AgentReportMigrated,
RevertRequested,
SnapshotRequested,
ReconfiguringRequested
SnapshotRequested
};
public enum Type {
@ -299,8 +294,4 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
public Map<String, String> getDetails();
public Boolean getSameHost();
public Long getNewSvcOfferingId();
}

View File

@ -1,109 +0,0 @@
package org.apache.cloudstack.api.command.user.vm;
import com.cloud.exception.*;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.log4j.Logger;
// 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.
@APICommand(name = "scaleVirtualMachine", description="Scales the virtual machine to a new service offering.", responseObject=UserVmResponse.class)
public class ScaleVMCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(ScaleVMCmd.class.getName());
private static final String s_name = "scalevirtualmachineresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@ACL
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
required=true, description="The ID of the virtual machine")
private Long id;
@ACL
@Parameter(name=ApiConstants.SERVICE_OFFERING_ID, type=CommandType.UUID, entityType=ServiceOfferingResponse.class,
required=true, description="the ID of the service offering for the virtual machine")
private Long serviceOfferingId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
public Long getServiceOfferingId() {
return serviceOfferingId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
public static String getResultObjectName() {
return "virtualmachine";
}
@Override
public long getEntityOwnerId() {
UserVm userVm = _entityMgr.findById(UserVm.class, getId());
if (userVm != null) {
return userVm.getAccountId();
}
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
}
@Override
public void execute(){
UserContext.current().setEventDetails("Vm Id: "+getId());
UserVm result = null;
try {
result = _userVmService.upgradeVirtualMachine(this);
} catch (ResourceUnavailableException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
} catch (ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (ManagementServerException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (VirtualMachineMigrationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
}
if (result != null){
UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upgrade vm");
}
}
}

View File

@ -66,7 +66,6 @@ listVirtualMachines=15
getVMPassword=15
restoreVirtualMachine=15
changeServiceForVirtualMachine=15
scaleVirtualMachine=15
assignVirtualMachine=1
migrateVirtualMachine=1
recoverVirtualMachine=7

View File

@ -151,12 +151,6 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
@Transient
Map<String, String> details;
@Transient
Long newSvcOfferingId;
@Transient
Boolean sameHost;
@Column(name="uuid")
protected String uuid = UUID.randomUUID().toString();
;
@ -486,22 +480,4 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
return diskOfferingId;
}
@Override
public Long getNewSvcOfferingId() {
return newSvcOfferingId;
}
public void setNewSvcOfferingId(Long oldSvcOfferingId) {
this.newSvcOfferingId = oldSvcOfferingId;
}
@Override
public Boolean getSameHost() {
return sameHost;
}
public void setSameHost(Boolean sameHost) {
this.sameHost = sameHost;
}
}
}

View File

@ -53,7 +53,6 @@ import javax.ejb.Local;
import javax.naming.ConfigurationException;
import javax.xml.parsers.DocumentBuilderFactory;
import com.cloud.agent.api.*;
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
import com.cloud.agent.api.to.*;
import com.cloud.network.rules.FirewallRule;
@ -65,6 +64,96 @@ import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import com.cloud.agent.IAgentControl;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
import com.cloud.agent.api.AttachVolumeAnswer;
import com.cloud.agent.api.AttachVolumeCommand;
import com.cloud.agent.api.BackupSnapshotAnswer;
import com.cloud.agent.api.BackupSnapshotCommand;
import com.cloud.agent.api.BumpUpPriorityCommand;
import com.cloud.agent.api.CheckHealthAnswer;
import com.cloud.agent.api.CheckHealthCommand;
import com.cloud.agent.api.CheckNetworkAnswer;
import com.cloud.agent.api.CheckNetworkCommand;
import com.cloud.agent.api.CheckOnHostAnswer;
import com.cloud.agent.api.CheckOnHostCommand;
import com.cloud.agent.api.CheckRouterAnswer;
import com.cloud.agent.api.CheckRouterCommand;
import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer;
import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.CleanupNetworkRulesCmd;
import com.cloud.agent.api.ClusterSyncAnswer;
import com.cloud.agent.api.ClusterSyncCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateStoragePoolCommand;
import com.cloud.agent.api.CreateVMSnapshotAnswer;
import com.cloud.agent.api.CreateVMSnapshotCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.DeleteVMSnapshotAnswer;
import com.cloud.agent.api.DeleteVMSnapshotCommand;
import com.cloud.agent.api.GetDomRVersionAnswer;
import com.cloud.agent.api.GetDomRVersionCmd;
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.GetVmStatsAnswer;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.GetVncPortAnswer;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.HostStatsEntry;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.ManageSnapshotAnswer;
import com.cloud.agent.api.ManageSnapshotCommand;
import com.cloud.agent.api.MigrateAnswer;
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.NetworkRulesSystemVmCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.PingRoutingCommand;
import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
import com.cloud.agent.api.PingRoutingWithOvsCommand;
import com.cloud.agent.api.PingTestCommand;
import com.cloud.agent.api.PlugNicAnswer;
import com.cloud.agent.api.PlugNicCommand;
import com.cloud.agent.api.PoolEjectCommand;
import com.cloud.agent.api.PrepareForMigrationAnswer;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.ReadyAnswer;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.RebootAnswer;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.RebootRouterCommand;
import com.cloud.agent.api.RevertToVMSnapshotAnswer;
import com.cloud.agent.api.RevertToVMSnapshotCommand;
import com.cloud.agent.api.SecurityGroupRuleAnswer;
import com.cloud.agent.api.SecurityGroupRulesCmd;
import com.cloud.agent.api.SetupAnswer;
import com.cloud.agent.api.SetupCommand;
import com.cloud.agent.api.SetupGuestNetworkAnswer;
import com.cloud.agent.api.SetupGuestNetworkCommand;
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.StartupStorageCommand;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.StoragePoolInfo;
import com.cloud.agent.api.UnPlugNicAnswer;
import com.cloud.agent.api.UnPlugNicCommand;
import com.cloud.agent.api.UpdateHostPasswordCommand;
import com.cloud.agent.api.UpgradeSnapshotCommand;
import com.cloud.agent.api.VmStatsEntry;
import com.cloud.agent.api.check.CheckSshAnswer;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
@ -508,93 +597,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return execute((DeleteVMSnapshotCommand)cmd);
} else if (clazz == RevertToVMSnapshotCommand.class) {
return execute((RevertToVMSnapshotCommand)cmd);
} else if (clazz == ScaleVmCommand.class) {
return execute((ScaleVmCommand) cmd);
} else {
return Answer.createUnsupportedCommandAnswer(cmd);
}
}
protected void scaleVM(Connection conn, VM vm, VirtualMachineTO vmSpec, Host host) throws XenAPIException, XmlRpcException {
vm.setMemoryDynamicRange(conn, vmSpec.getMinRam() * 1024 * 1024, vmSpec.getMaxRam() * 1024 * 1024);
vm.setVCPUsNumberLive(conn, (long)vmSpec.getCpus());
Integer speed = vmSpec.getSpeed();
if (speed != null) {
int cpuWeight = _maxWeight; //cpu_weight
// weight based allocation
cpuWeight = (int)((speed*0.99) / _host.speed * _maxWeight);
if (cpuWeight > _maxWeight) {
cpuWeight = _maxWeight;
}
if (vmSpec.getLimitCpuUse()) {
long utilization = 0; // max CPU cap, default is unlimited
utilization = ((long)speed * 100 * vmSpec.getCpus()) / _host.speed ;
vm.addToVCPUsParamsLive(conn, "cap", Long.toString(utilization));
}
//vm.addToVCPUsParamsLive(conn, "weight", Integer.toString(cpuWeight));
callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", Integer.toString(cpuWeight), "vmname", vmSpec.getName() );
}
}
public ScaleVmAnswer execute(ScaleVmCommand cmd) {
VirtualMachineTO vmSpec = cmd.getVirtualMachine();
String vmName = vmSpec.getName();
try {
Connection conn = getConnection();
Set<VM> vms = VM.getByNameLabel(conn, vmName);
Host host = Host.getByUuid(conn, _host.uuid);
// stop vm which is running on this host or is in halted state
Iterator<VM> iter = vms.iterator();
while ( iter.hasNext() ) {
VM vm = iter.next();
VM.Record vmr = vm.getRecord(conn);
if ((vmr.powerState == VmPowerState.HALTED) || (vmr.powerState == VmPowerState.RUNNING && !isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(_host.uuid))) {
iter.remove();
}
}
if (vms.size() == 0) {
s_logger.info("No running VM " + vmName +" exists on XenServer" + _host.uuid);
return new ScaleVmAnswer(cmd, false, "VM does not exist");
}
for (VM vm : vms) {
VM.Record vmr = vm.getRecord(conn);
try {
scaleVM(conn, vm, vmSpec, host);
} catch (Exception e) {
String msg = "Catch exception " + e.getClass().getName() + " when scaling VM:" + vmName + " due to " + e.toString();
s_logger.debug(msg);
return new ScaleVmAnswer(cmd, false, msg);
}
}
String msg = "scaling VM " + vmName + " is successful on host " + host;
s_logger.debug(msg);
return new ScaleVmAnswer(cmd, true, msg);
} catch (XenAPIException e) {
String msg = "Upgrade Vm " + vmName + " fail due to " + e.toString();
s_logger.warn(msg, e);
return new ScaleVmAnswer(cmd, false, msg);
} catch (XmlRpcException e) {
String msg = "Upgrade Vm " + vmName + " fail due to " + e.getMessage();
s_logger.warn(msg, e);
return new ScaleVmAnswer(cmd, false, msg);
} catch (Exception e) {
String msg = "Unable to upgrade " + vmName + " due to " + e.getMessage();
s_logger.warn(msg, e);
return new ScaleVmAnswer(cmd, false, msg);
}
}
private Answer execute(RevertToVMSnapshotCommand cmd) {
String vmName = cmd.getVmName();

View File

@ -138,14 +138,9 @@ public class XenServer56FP1Resource extends XenServer56Resource {
record.actionsAfterShutdown = Types.OnNormalExit.DESTROY;
record.memoryDynamicMax = vmSpec.getMaxRam();
record.memoryDynamicMin = vmSpec.getMinRam();
record.memoryStaticMax = 8589934592L; //128GB
record.memoryStaticMin = 134217728L; //128MB
if (guestOsTypeName.toLowerCase().contains("windows")) {
record.VCPUsMax = (long) vmSpec.getCpus();
} else {
record.VCPUsMax = 32L;
}
record.memoryStaticMax = vmSpec.getMaxRam();
record.memoryStaticMin = vmSpec.getMinRam();
record.VCPUsMax = (long) vmSpec.getCpus();
record.VCPUsAtStartup = (long) vmSpec.getCpus();
record.consoles.clear();

View File

@ -1,33 +0,0 @@
#!/bin/sh
# 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.
set -x
vmname=$1
key=$2
value=$3
uuid=`xe vm-list name-label=$vmname | grep uuid | awk '{print $NF}'`
if [[ $key == "weight" ]]
then
xe vm-param-set VCPUs-params:weight=$value uuid=$uuid
fi
if [[ $key == "cap" ]]
then
xe vm-param-set VCPUs-params:cap=$value uuid=$uuid
fi

View File

@ -42,18 +42,6 @@ def echo(fn):
return res
return wrapped
@echo
def add_to_VCPUs_params_live(session, args):
key = args['key']
value = args['value']
vmname = args['vmname']
try:
cmd = ["bash", "/opt/xensource/bin/Add-To-VCPUs-Params-Live.sh", vmname, key, value]
txt = util.pread2(cmd)
except:
return 'false'
return 'true'
@echo
def gethostvmstats(session, args):
collect_host_stats = args['collectHostStats']
@ -1482,7 +1470,6 @@ if __name__ == "__main__":
"destroy_network_rules_for_vm":destroy_network_rules_for_vm,
"default_network_rules_systemvm":default_network_rules_systemvm,
"get_rule_logs_for_vms":get_rule_logs_for_vms,
"add_to_VCPUs_params_live":add_to_VCPUs_params_live,
"setLinkLocalIP":setLinkLocalIP,
"cleanup_rules":cleanup_rules,
"bumpUpPriority":bumpUpPriority,

View File

@ -173,8 +173,7 @@ public enum Config {
RouterTemplateId("Advanced", NetworkManager.class, Long.class, "router.template.id", "1", "Default ID for template.", null),
RouterExtraPublicNics("Advanced", NetworkManager.class, Integer.class, "router.extra.public.nics", "2", "specify extra public nics used for virtual router(up to 5)", "0-5"),
StartRetry("Advanced", AgentManager.class, Integer.class, "start.retry", "10", "Number of times to retry create and start commands", null),
ScaleRetry("Advanced", AgentManager.class, Integer.class, "scale.retry", "2", "Number of times to retry scaling up the vm", null),
StopRetryInterval("Advanced", HighAvailabilityManager.class, Integer.class, "stop.retry.interval", "600", "Time in seconds between retries to stop or destroy a vm" , null),
StopRetryInterval("Advanced", HighAvailabilityManager.class, Integer.class, "stop.retry.interval", "600", "Time in seconds between retries to stop or destroy a vm" , null),
StorageCleanupInterval("Advanced", StorageManager.class, Integer.class, "storage.cleanup.interval", "86400", "The interval (in seconds) to wait before running the storage cleanup thread.", null),
StorageCleanupEnabled("Advanced", StorageManager.class, Boolean.class, "storage.cleanup.enabled", "true", "Enables/disables the storage cleanup thread.", null),
UpdateWait("Advanced", AgentManager.class, Integer.class, "update.wait", "600", "Time to wait (in seconds) before alerting on a updating agent", null),

View File

@ -2110,7 +2110,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
cmdList.add(DestroyVMCmd.class);
cmdList.add(GetVMPasswordCmd.class);
cmdList.add(ListVMsCmd.class);
cmdList.add(ScaleVMCmd.class);
cmdList.add(RebootVMCmd.class);
cmdList.add(RemoveNicFromVMCmd.class);
cmdList.add(ResetVMPasswordCmd.class);

View File

@ -41,8 +41,7 @@ public class ItWorkVO {
Started,
Release,
Done,
Migrating,
Reconfiguring
Migrating
}
@Id

View File

@ -32,12 +32,22 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.api.ApiDBUtils;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
import org.apache.cloudstack.api.command.user.vm.*;
import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
@ -387,7 +397,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
protected String _instance;
protected String _zone;
protected boolean _instanceNameFlag;
protected int _scaleRetry;
@Inject ConfigurationDao _configDao;
private int _createprivatetemplatefromvolumewait;
@ -1008,74 +1017,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
throw new CloudRuntimeException("something strange happened, new default network(" + newdefault.getId() + ") is not null, and is not equal to the network(" + nic.getNetworkId() + ") of the chosen nic");
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_SCALE, eventDescription = "scaling Vm")
public UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws InvalidParameterValueException {
Long vmId = cmd.getId();
Long newSvcOffId = cmd.getServiceOfferingId();
Account caller = UserContext.current().getCaller();
// Verify input parameters
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
if(vmInstance.getHypervisorType() != HypervisorType.XenServer){
throw new InvalidParameterValueException("This operation not permitted for this hypervisor of the vm");
}
_accountMgr.checkAccess(caller, null, true, vmInstance);
// Check that the specified service offering ID is valid
_itMgr.checkIfCanUpgrade(vmInstance, newSvcOffId);
//Check if its a scale up
ServiceOffering newServiceOffering = _configMgr.getServiceOffering(newSvcOffId);
ServiceOffering oldServiceOffering = _configMgr.getServiceOffering(vmInstance.getServiceOfferingId());
if(newServiceOffering.getSpeed() <= oldServiceOffering.getSpeed()
&& newServiceOffering.getRamSize() <= oldServiceOffering.getRamSize()){
throw new InvalidParameterValueException("Only scaling up the vm is supported");
}
// Dynamically upgrade the running vms
if(vmInstance.getState().equals(State.Running)){
boolean success = false;
int retry = _scaleRetry;
while (retry-- != 0) { // It's != so that it can match -1.
try{
// #1 Check existing host has capacity
boolean existingHostHasCapacity = _capacityMgr.checkIfHostHasCapacity(vmInstance.getHostId(), newServiceOffering.getSpeed() - oldServiceOffering.getSpeed(),
(newServiceOffering.getRamSize() - oldServiceOffering.getRamSize()) * 1024L * 1024L, false, ApiDBUtils.getCpuOverprovisioningFactor(), 1f, false);
// #2 migrate the vm
if (!existingHostHasCapacity){
vmInstance = _itMgr.scale(vmInstance.getType(), vmInstance, newSvcOffId);
}else{
vmInstance.setSameHost(existingHostHasCapacity);
}
// #3 scale the vm now
vmInstance = _itMgr.reConfigureVm(vmInstance, newServiceOffering, existingHostHasCapacity);
success = true;
}catch(InsufficientCapacityException e ){
} catch (ResourceUnavailableException e) {
e.printStackTrace();
} catch (ConcurrentOperationException e) {
e.printStackTrace();
} catch (VirtualMachineMigrationException e) {
e.printStackTrace();
} catch (ManagementServerException e) {
e.printStackTrace();
}
}
if (!success)
return null;
}
//Update the DB.
_itMgr.upgradeVmDb(vmId, newSvcOffId);
return _vmDao.findById(vmInstance.getId());
}
@Override
public HashMap<Long, VmStatsEntry> getVirtualMachineStatistics(long hostId,
String hostName, List<Long> vmIds) throws CloudRuntimeException {
@ -1269,7 +1210,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
new UserVmStateListener(_usageEventDao, _networkDao, _nicDao));
value = _configDao.getValue(Config.SetVmInternalNameUsingDisplayName.key());
if(value == null) {
_instanceNameFlag = false;
}
@ -1278,8 +1218,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
_instanceNameFlag = Boolean.parseBoolean(value);
}
_scaleRetry = NumbersUtil.parseInt(configs.get(Config.ScaleRetry.key()), 2);
s_logger.info("User VM Manager is configured.");
return true;

View File

@ -186,16 +186,4 @@ public interface VirtualMachineManager extends Manager {
*/
VirtualMachineTO toVmTO(VirtualMachineProfile<? extends VMInstanceVO> profile);
VMInstanceVO reConfigureVm(VMInstanceVO vm, ServiceOffering newServiceOffering, boolean sameHost)
throws ResourceUnavailableException, ConcurrentOperationException;
VMInstanceVO scale(VirtualMachine.Type vmType, VMInstanceVO vm, Long newSvcOfferingId) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException,
VirtualMachineMigrationException, ManagementServerException;
<T extends VMInstanceVO> T migrateForScale(T vm, long srcHostId, DeployDestination dest, Long newSvcOfferingId)
throws ResourceUnavailableException, ConcurrentOperationException,
ManagementServerException, VirtualMachineMigrationException;
}

View File

@ -38,13 +38,33 @@ import javax.naming.ConfigurationException;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import com.cloud.dc.*;
import com.cloud.agent.api.*;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.AgentManager.OnError;
import com.cloud.agent.Listener;
import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.AgentControlCommand;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.ClusterSyncAnswer;
import com.cloud.agent.api.ClusterSyncCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.MigrateAnswer;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.PingRoutingCommand;
import com.cloud.agent.api.PrepareForMigrationAnswer;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.RebootAnswer;
import com.cloud.agent.api.RebootCommand;
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.StartupRoutingCommand.VmState;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.manager.Commands;
@ -2401,12 +2421,13 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
if (newServiceOffering == null) {
throw new InvalidParameterValueException("Unable to find a service offering with id " + newServiceOfferingId);
}
// Check that the VM is stopped / running
if (!(vmInstance.getState().equals(State.Stopped) || vmInstance.getState().equals(State.Running) )) {
// Check that the VM is stopped
if (!vmInstance.getState().equals(State.Stopped)) {
s_logger.warn("Unable to upgrade virtual machine " + vmInstance.toString() + " in state " + vmInstance.getState());
throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + " " + " in state " + vmInstance.getState()
+ "; make sure the virtual machine is stopped/running");
throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + " " +
"in state " + vmInstance.getState()
+ "; make sure the virtual machine is stopped and not in an error state before upgrading.");
}
// Check if the service offering being upgraded to is what the VM is already running with
@ -2657,276 +2678,4 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
return true;
}
@Override
public VMInstanceVO scale(VirtualMachine.Type vmType, VMInstanceVO vm, Long newSvcOfferingId)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, VirtualMachineMigrationException, ManagementServerException {
VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(vm);
Long srcHostId = vm.getHostId();
Long oldSvcOfferingId = vm.getServiceOfferingId();
if (srcHostId == null) {
s_logger.debug("Unable to scale the vm because it doesn't have a host id: " + vm);
return vm;
}
Host host = _hostDao.findById(srcHostId);
DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), null, null, null);
ExcludeList excludes = new ExcludeList();
excludes.addHost(vm.getHostId());
vm.setServiceOfferingId(newSvcOfferingId); // Need to find the destination host based on new svc offering
DeployDestination dest = null;
for (DeploymentPlanner planner : _planners) {
if (planner.canHandle(profile, plan, excludes)) {
dest = planner.plan(profile, plan, excludes);
} else {
continue;
}
if (dest != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Planner " + planner + " found " + dest + " for scaling the vm to.");
}
break;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Planner " + planner + " was unable to find anything.");
}
}
if (dest == null) {
throw new InsufficientServerCapacityException("Unable to find a server to scale the vm to.", host.getClusterId());
}
excludes.addHost(dest.getHost().getId());
VMInstanceVO vmInstance = null;
try {
vmInstance = migrateForScale(vm, srcHostId, dest, oldSvcOfferingId);
} catch (ResourceUnavailableException e) {
s_logger.debug("Unable to migrate to unavailable " + dest);
throw e;
} catch (ConcurrentOperationException e) {
s_logger.debug("Unable to migrate VM due to: " + e.getMessage());
throw e;
} catch (ManagementServerException e) {
s_logger.debug("Unable to migrate VM: " + e.getMessage());
throw e;
} catch (VirtualMachineMigrationException e) {
s_logger.debug("Got VirtualMachineMigrationException, Unable to migrate: " + e.getMessage());
if (vm.getState() == State.Starting) {
s_logger.debug("VM seems to be still Starting, we should retry migration later");
throw e;
} else {
s_logger.debug("Unable to migrate VM, VM is not in Running or even Starting state, current state: " + vm.getState().toString());
}
}
if (vmInstance != null) {
return vmInstance;
}else{
return null;
}
}
@Override
public VMInstanceVO reConfigureVm(VMInstanceVO vm , ServiceOffering newServiceOffering, boolean sameHost) throws ResourceUnavailableException, ConcurrentOperationException {
ScaleVmCommand reconfigureCmd = new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(),
newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), newServiceOffering.getRamSize());
Long dstHostId = vm.getHostId();
ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Reconfiguring, vm.getType(), vm.getId());
work.setStep(Step.Prepare);
work.setResourceType(ItWorkVO.ResourceType.Host);
work.setResourceId(vm.getHostId());
work = _workDao.persist(work);
boolean success = false;
try {
vm.setNewSvcOfferingId(newServiceOffering.getId()); // Capacity update should be delta (new - old) offering
changeState(vm, Event.ReconfiguringRequested, dstHostId, work, Step.Reconfiguring);
Answer reconfigureAnswer = _agentMgr.send(vm.getHostId(), reconfigureCmd);
if (!reconfigureAnswer.getResult()) {
s_logger.error("Unable to reconfigure due to " + reconfigureAnswer.getDetails());
return null;
}
changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Done);
success = true;
} catch (OperationTimedoutException e) {
throw new AgentUnavailableException("Operation timed out on reconfiguring " + vm, dstHostId);
} catch (AgentUnavailableException e) {
throw e;
} catch (NoTransitionException e) {
s_logger.info("Unable to change the state : " + e.getMessage());
throw new ConcurrentOperationException("Unable to change the state : " + e.getMessage());
}finally{
work.setStep(Step.Done);
_workDao.update(work.getId(), work);
if(!success){
try {
stateTransitTo(vm, Event.OperationFailed, vm.getHostId());
} catch (NoTransitionException e) {
s_logger.warn(e.getMessage());
}
}
}
return vm;
}
@Override
public <T extends VMInstanceVO> T migrateForScale(T vm, long srcHostId, DeployDestination dest, Long oldSvcOfferingId) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
VirtualMachineMigrationException {
s_logger.info("Migrating " + vm + " to " + dest);
Long newSvcOfferingId = vm.getServiceOfferingId();
long dstHostId = dest.getHost().getId();
Host fromHost = _hostDao.findById(srcHostId);
if (fromHost == null) {
s_logger.info("Unable to find the host to migrate from: " + srcHostId);
throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId);
}
if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) {
s_logger.info("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId());
throw new CloudRuntimeException("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId());
}
VirtualMachineGuru<T> vmGuru = getVmGuru(vm);
long vmId = vm.getId();
vm = vmGuru.findById(vmId);
if (vm == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find the vm " + vm);
}
throw new ManagementServerException("Unable to find a virtual machine with id " + vmId);
}
if (vm.getState() != State.Running) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
}
throw new VirtualMachineMigrationException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString());
}
short alertType = AlertManager.ALERT_TYPE_USERVM_MIGRATE;
if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE;
} else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY_MIGRATE;
}
VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(vm);
_networkMgr.prepareNicForMigration(profile, dest);
this.volumeMgr.prepareForMigration(profile, dest);
VirtualMachineTO to = toVmTO(profile);
PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId());
work.setStep(Step.Prepare);
work.setResourceType(ItWorkVO.ResourceType.Host);
work.setResourceId(dstHostId);
work = _workDao.persist(work);
PrepareForMigrationAnswer pfma = null;
try {
pfma = (PrepareForMigrationAnswer) _agentMgr.send(dstHostId, pfmc);
if (!pfma.getResult()) {
String msg = "Unable to prepare for migration due to " + pfma.getDetails();
pfma = null;
throw new AgentUnavailableException(msg, dstHostId);
}
} catch (OperationTimedoutException e1) {
throw new AgentUnavailableException("Operation timed out", dstHostId);
} finally {
if (pfma == null) {
work.setStep(Step.Done);
_workDao.update(work.getId(), work);
}
}
vm.setLastHostId(srcHostId);
try {
if (vm == null || vm.getHostId() == null || vm.getHostId() != srcHostId || !changeState(vm, Event.MigrationRequested, dstHostId, work, Step.Migrating)) {
s_logger.info("Migration cancelled because state has changed: " + vm);
throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm);
}
} catch (NoTransitionException e1) {
s_logger.info("Migration cancelled because " + e1.getMessage());
throw new ConcurrentOperationException("Migration cancelled because " + e1.getMessage());
}
boolean migrated = false;
try {
boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows);
mc.setHostGuid(dest.getHost().getGuid());
try {
MigrateAnswer ma = (MigrateAnswer) _agentMgr.send(vm.getLastHostId(), mc);
if (!ma.getResult()) {
s_logger.error("Unable to migrate due to " + ma.getDetails());
return null;
}
} catch (OperationTimedoutException e) {
if (e.isActive()) {
s_logger.warn("Active migration command so scheduling a restart for " + vm);
_haMgr.scheduleRestart(vm, true);
}
throw new AgentUnavailableException("Operation timed out on migrating " + vm, dstHostId);
}
try {
vm.setServiceOfferingId(oldSvcOfferingId); // release capacity for the old service offering only
if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) {
throw new ConcurrentOperationException("Unable to change the state for " + vm);
}
} catch (NoTransitionException e1) {
throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage());
}
try {
if (!checkVmOnHost(vm, dstHostId)) {
s_logger.error("Unable to complete migration for " + vm);
try {
_agentMgr.send(srcHostId, new Commands(cleanup(vm.getInstanceName())), null);
} catch (AgentUnavailableException e) {
s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
}
cleanup(vmGuru, new VirtualMachineProfileImpl<T>(vm), work, Event.AgentReportStopped, true, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount());
return null;
}
} catch (OperationTimedoutException e) {
}
migrated = true;
return vm;
} finally {
if (!migrated) {
s_logger.info("Migration was unsuccessful. Cleaning up: " + vm);
_alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone "
+ dest.getDataCenter().getName() + " and pod " + dest.getPod().getName(), "Migrate Command failed. Please check logs.");
try {
_agentMgr.send(dstHostId, new Commands(cleanup(vm.getInstanceName())), null);
} catch (AgentUnavailableException ae) {
s_logger.info("Looks like the destination Host is unavailable for cleanup");
}
try {
stateTransitTo(vm, Event.OperationFailed, srcHostId);
} catch (NoTransitionException e) {
s_logger.warn(e.getMessage());
}
}
work.setStep(Step.Done);
_workDao.update(work.getId(), work);
}
}
}
}

View File

@ -25,7 +25,18 @@ import javax.naming.ConfigurationException;
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
import org.apache.cloudstack.api.command.user.vm.*;
import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
import org.springframework.stereotype.Component;
@ -380,10 +391,6 @@ public class MockUserVmManagerImpl extends ManagerBase implements UserVmManager,
return null;
}
@Override
public UserVm upgradeVirtualMachine(ScaleVMCmd scaleVMCmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override

View File

@ -265,21 +265,6 @@ public class MockVirtualMachineManagerImpl extends ManagerBase implements Virtua
return null;
}
@Override
public VMInstanceVO reConfigureVm(VMInstanceVO vm, ServiceOffering newServiceOffering, boolean sameHost) throws ResourceUnavailableException, ConcurrentOperationException {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public VMInstanceVO scale(Type vmType, VMInstanceVO vm, Long newSvcOfferingId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, VirtualMachineMigrationException, ManagementServerException {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public <T extends VMInstanceVO> T migrateForScale(T vm, long srcHostId, DeployDestination dest, Long newSvcOfferingId) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
/* (non-Javadoc)
* @see com.cloud.vm.VirtualMachineManager#addVmToNetwork(com.cloud.vm.VirtualMachine, com.cloud.network.Network, com.cloud.vm.NicProfile)
*/