mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge remote-tracking branch 'origin/4.19'
This commit is contained in:
commit
25009bfb76
@ -400,6 +400,7 @@ public class EventTypes {
|
||||
public static final String EVENT_IMAGE_STORE_DATA_MIGRATE = "IMAGE.STORE.MIGRATE.DATA";
|
||||
public static final String EVENT_IMAGE_STORE_RESOURCES_MIGRATE = "IMAGE.STORE.MIGRATE.RESOURCES";
|
||||
public static final String EVENT_IMAGE_STORE_OBJECT_DOWNLOAD = "IMAGE.STORE.OBJECT.DOWNLOAD";
|
||||
public static final String EVENT_UPDATE_IMAGE_STORE_ACCESS_STATE = "IMAGE.STORE.ACCESS.UPDATED";
|
||||
|
||||
// Configuration Table
|
||||
public static final String EVENT_CONFIGURATION_VALUE_EDIT = "CONFIGURATION.VALUE.EDIT";
|
||||
@ -1164,6 +1165,7 @@ public class EventTypes {
|
||||
|
||||
entityEventDetails.put(EVENT_IMAGE_STORE_DATA_MIGRATE, ImageStore.class);
|
||||
entityEventDetails.put(EVENT_IMAGE_STORE_OBJECT_DOWNLOAD, ImageStore.class);
|
||||
entityEventDetails.put(EVENT_UPDATE_IMAGE_STORE_ACCESS_STATE, ImageStore.class);
|
||||
entityEventDetails.put(EVENT_LIVE_PATCH_SYSTEMVM, "SystemVMs");
|
||||
|
||||
//Object Store
|
||||
|
||||
@ -52,7 +52,7 @@ public interface AlertService {
|
||||
public static final AlertType ALERT_TYPE_ROUTING = new AlertType((short)11, "ALERT.NETWORK.ROUTING", true);
|
||||
public static final AlertType ALERT_TYPE_STORAGE_MISC = new AlertType((short)12, "ALERT.STORAGE.MISC", true);
|
||||
public static final AlertType ALERT_TYPE_USAGE_SERVER = new AlertType((short)13, "ALERT.USAGE", true);
|
||||
public static final AlertType ALERT_TYPE_MANAGMENT_NODE = new AlertType((short)14, "ALERT.MANAGEMENT", true);
|
||||
public static final AlertType ALERT_TYPE_MANAGEMENT_NODE = new AlertType((short)14, "ALERT.MANAGEMENT", true);
|
||||
public static final AlertType ALERT_TYPE_DOMAIN_ROUTER_MIGRATE = new AlertType((short)15, "ALERT.NETWORK.DOMAINROUTERMIGRATE", true);
|
||||
public static final AlertType ALERT_TYPE_CONSOLE_PROXY_MIGRATE = new AlertType((short)16, "ALERT.SERVICE.CONSOLEPROXYMIGRATE", true);
|
||||
public static final AlertType ALERT_TYPE_USERVM_MIGRATE = new AlertType((short)17, "ALERT.USERVM.MIGRATE", true);
|
||||
|
||||
@ -39,7 +39,7 @@ import com.cloud.user.User;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
@APICommand(name = "moveUser",
|
||||
description = "Moves a user to another account",
|
||||
description = "Moves a user to another account in the same domain.",
|
||||
responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false,
|
||||
@ -56,18 +56,18 @@ public class MoveUserCmd extends BaseCmd {
|
||||
type = CommandType.UUID,
|
||||
entityType = UserResponse.class,
|
||||
required = true,
|
||||
description = "id of the user to be deleted")
|
||||
description = "id of the user to be moved.")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT,
|
||||
type = CommandType.STRING,
|
||||
description = "Creates the user under the specified account. If no account is specified, the username will be used as the account name.")
|
||||
description = "Moves the user under the specified account. If no account name is specified, it is necessary to provide an account id.")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = AccountResponse.class,
|
||||
description = "Creates the user under the specified domain. Has to be accompanied with the account parameter")
|
||||
description = "Moves the user under the specified account. If no account id is specified, it is necessary to provide an account name.")
|
||||
private Long accountId;
|
||||
|
||||
@Inject
|
||||
|
||||
@ -17,9 +17,21 @@
|
||||
package com.cloud.vm;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.cloud.serializer.GsonHelper;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class VmWork implements Serializable {
|
||||
private static final long serialVersionUID = -6946320465729853589L;
|
||||
private static final Gson gsonLogger = GsonHelper.getGsonLogger();
|
||||
|
||||
long userId;
|
||||
long accountId;
|
||||
@ -56,4 +68,31 @@ public class VmWork implements Serializable {
|
||||
public String getHandlerName() {
|
||||
return handlerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return gsonLogger.toJson(this);
|
||||
}
|
||||
|
||||
protected String toStringAfterRemoveParams(String paramsObjName, List<String> params) {
|
||||
String ObjJsonStr = gsonLogger.toJson(this);
|
||||
if (StringUtils.isBlank(ObjJsonStr) || StringUtils.isBlank(paramsObjName) || CollectionUtils.isEmpty(params)) {
|
||||
return ObjJsonStr;
|
||||
}
|
||||
|
||||
try {
|
||||
Map<String, Object> ObjMap = new ObjectMapper().readValue(ObjJsonStr, HashMap.class);
|
||||
if (ObjMap != null && ObjMap.containsKey(paramsObjName)) {
|
||||
for (String param : params) {
|
||||
((Map<String, String>)ObjMap.get(paramsObjName)).remove(param);
|
||||
}
|
||||
String resultJson = new ObjectMapper().writeValueAsString(ObjMap);
|
||||
return resultJson;
|
||||
}
|
||||
} catch (final JsonProcessingException e) {
|
||||
// Ignore json exception
|
||||
}
|
||||
|
||||
return ObjJsonStr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,15 +21,13 @@ import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
|
||||
import org.apache.cloudstack.jobs.JobInfo;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.serializer.GsonHelper;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
* VmWorkJobHandlerProxy can not be used as standalone due to run-time
|
||||
@ -102,12 +100,12 @@ public class VmWorkJobHandlerProxy implements VmWorkJobHandler {
|
||||
|
||||
try {
|
||||
if (s_logger.isDebugEnabled())
|
||||
s_logger.debug("Execute VM work job: " + work.getClass().getName() + _gsonLogger.toJson(work));
|
||||
s_logger.debug("Execute VM work job: " + work.getClass().getName() + work);
|
||||
|
||||
Object obj = method.invoke(_target, work);
|
||||
|
||||
if (s_logger.isDebugEnabled())
|
||||
s_logger.debug("Done executing VM work job: " + work.getClass().getName() + _gsonLogger.toJson(work));
|
||||
s_logger.debug("Done executing VM work job: " + work.getClass().getName() + work);
|
||||
|
||||
assert (obj instanceof Pair);
|
||||
return (Pair<JobInfo.Status, String>)obj;
|
||||
|
||||
@ -17,7 +17,9 @@
|
||||
package com.cloud.vm;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
|
||||
@ -62,4 +64,11 @@ public class VmWorkReboot extends VmWork {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
List<String> params = new ArrayList<>();
|
||||
params.add(VirtualMachineProfile.Param.VmPassword.getName());
|
||||
return super.toStringAfterRemoveParams("rawParams", params);
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,9 @@
|
||||
package com.cloud.vm;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
@ -135,4 +137,11 @@ public class VmWorkStart extends VmWork {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
List<String> params = new ArrayList<>();
|
||||
params.add(VirtualMachineProfile.Param.VmPassword.getName());
|
||||
return super.toStringAfterRemoveParams("rawParams", params);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
// 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.vm;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class VmWorkRebootTest {
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
VmWork vmWork = new VmWork(1l, 1l, 1l, "testhandler");
|
||||
Map<VirtualMachineProfile.Param, Object> params = new HashMap<>();
|
||||
String lastHost = "rO0ABXQABHRydWU";
|
||||
String lastHostSerialized = JobSerializerHelper.toObjectSerializedString(lastHost);
|
||||
params.put(VirtualMachineProfile.Param.ConsiderLastHost, lastHost);
|
||||
params.put(VirtualMachineProfile.Param.VmPassword, "rO0ABXQADnNhdmVkX3Bhc3N3b3Jk");
|
||||
VmWorkReboot workInfo = new VmWorkReboot(vmWork, params);
|
||||
String expectedVmWorkRebootStr = "{\"accountId\":1,\"vmId\":1,\"handlerName\":\"testhandler\",\"userId\":1,\"rawParams\":{\"ConsiderLastHost\":\"" + lastHostSerialized + "\"}}";
|
||||
|
||||
String vmWorkRebootStr = workInfo.toString();
|
||||
Assert.assertEquals(expectedVmWorkRebootStr, vmWorkRebootStr);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
// 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.vm;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class VmWorkStartTest {
|
||||
|
||||
@Test
|
||||
public void testToStringWithParams() {
|
||||
VmWork vmWork = new VmWork(1l, 1l, 1l, "testhandler");
|
||||
VmWorkStart workInfo = new VmWorkStart(vmWork);
|
||||
Map<VirtualMachineProfile.Param, Object> params = new HashMap<>();
|
||||
String lastHost = "rO0ABXQABHRydWU";
|
||||
String lastHostSerialized = JobSerializerHelper.toObjectSerializedString(lastHost);
|
||||
params.put(VirtualMachineProfile.Param.ConsiderLastHost, lastHost);
|
||||
params.put(VirtualMachineProfile.Param.VmPassword, "rO0ABXQADnNhdmVkX3Bhc3N3b3Jk");
|
||||
workInfo.setParams(params);
|
||||
String expectedVmWorkStartStr = "{\"accountId\":1,\"dcId\":0,\"vmId\":1,\"handlerName\":\"testhandler\",\"userId\":1,\"rawParams\":{\"ConsiderLastHost\":\"" + lastHostSerialized + "\"}}";
|
||||
|
||||
String vmWorkStartStr = workInfo.toString();
|
||||
Assert.assertEquals(expectedVmWorkStartStr, vmWorkStartStr);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToStringWithRawParams() {
|
||||
VmWork vmWork = new VmWork(1l, 1l, 1l, "testhandler");
|
||||
VmWorkStart workInfo = new VmWorkStart(vmWork);
|
||||
Map<String, String> rawParams = new HashMap<>();
|
||||
rawParams.put(VirtualMachineProfile.Param.ConsiderLastHost.getName(), "rO0ABXQABHRydWU");
|
||||
rawParams.put(VirtualMachineProfile.Param.VmPassword.getName(), "rO0ABXQADnNhdmVkX3Bhc3N3b3Jk");
|
||||
workInfo.setRawParams(rawParams);
|
||||
String expectedVmWorkStartStr = "{\"accountId\":1,\"dcId\":0,\"vmId\":1,\"handlerName\":\"testhandler\",\"userId\":1,\"rawParams\":{\"ConsiderLastHost\":\"rO0ABXQABHRydWU\"}}";
|
||||
|
||||
String vmWorkStartStr = workInfo.toString();
|
||||
Assert.assertEquals(expectedVmWorkStartStr, vmWorkStartStr);
|
||||
}
|
||||
}
|
||||
@ -85,7 +85,6 @@ import org.libvirt.DomainInfo;
|
||||
import org.libvirt.DomainInfo.DomainState;
|
||||
import org.libvirt.DomainInterfaceStats;
|
||||
import org.libvirt.DomainSnapshot;
|
||||
import org.libvirt.Library;
|
||||
import org.libvirt.LibvirtException;
|
||||
import org.libvirt.MemoryStatistic;
|
||||
import org.libvirt.Network;
|
||||
@ -3694,20 +3693,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
}
|
||||
|
||||
private void setupLibvirtEventListener() {
|
||||
final Thread libvirtListenerThread = new Thread(() -> {
|
||||
try {
|
||||
Library.runEventLoop();
|
||||
} catch (LibvirtException e) {
|
||||
s_logger.error("LibvirtException was thrown in event loop: ", e);
|
||||
} catch (InterruptedException e) {
|
||||
s_logger.error("Libvirt event loop was interrupted: ", e);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
libvirtListenerThread.setDaemon(true);
|
||||
libvirtListenerThread.start();
|
||||
|
||||
Connect conn = LibvirtConnection.getConnection();
|
||||
conn.addLifecycleListener(this::onDomainLifecycleChange);
|
||||
|
||||
@ -3727,7 +3713,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
* Checking for this helps us differentiate between events where cloudstack or admin stopped the VM vs guest
|
||||
* initiated, and avoid pushing extra updates for actions we are initiating without a need for extra tracking */
|
||||
DomainEventDetail detail = domainEvent.getDetail();
|
||||
if (StoppedDetail.SHUTDOWN.equals(detail) || StoppedDetail.CRASHED.equals(detail)) {
|
||||
if (StoppedDetail.SHUTDOWN.equals(detail) || StoppedDetail.CRASHED.equals(detail) || StoppedDetail.FAILED.equals(detail)) {
|
||||
s_logger.info("Triggering out of band status update due to completed self-shutdown or crash of VM");
|
||||
_agentStatusUpdater.triggerUpdate();
|
||||
} else {
|
||||
|
||||
@ -23,6 +23,7 @@ import com.cloud.agent.properties.AgentProperties;
|
||||
import com.cloud.agent.properties.AgentPropertiesFileHandler;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.libvirt.Connect;
|
||||
import org.libvirt.Library;
|
||||
import org.libvirt.LibvirtException;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
@ -34,6 +35,7 @@ public class LibvirtConnection {
|
||||
|
||||
static private Connect s_connection;
|
||||
static private String s_hypervisorURI;
|
||||
static private Thread libvirtEventThread;
|
||||
|
||||
static public Connect getConnection() throws LibvirtException {
|
||||
return getConnection(s_hypervisorURI);
|
||||
@ -45,6 +47,8 @@ public class LibvirtConnection {
|
||||
|
||||
if (conn == null) {
|
||||
s_logger.info("No existing libvirtd connection found. Opening a new one");
|
||||
|
||||
setupEventListener();
|
||||
conn = new Connect(hypervisorURI, false);
|
||||
s_logger.debug("Successfully connected to libvirt at: " + hypervisorURI);
|
||||
s_connections.put(hypervisorURI, conn);
|
||||
@ -53,7 +57,15 @@ public class LibvirtConnection {
|
||||
conn.getVersion();
|
||||
} catch (LibvirtException e) {
|
||||
s_logger.error("Connection with libvirtd is broken: " + e.getMessage());
|
||||
|
||||
try {
|
||||
conn.close();
|
||||
} catch (LibvirtException closeEx) {
|
||||
s_logger.debug("Ignoring error while trying to close broken connection:" + closeEx.getMessage());
|
||||
}
|
||||
|
||||
s_logger.debug("Opening a new libvirtd connection to: " + hypervisorURI);
|
||||
setupEventListener();
|
||||
conn = new Connect(hypervisorURI, false);
|
||||
s_connections.put(hypervisorURI, conn);
|
||||
}
|
||||
@ -101,4 +113,33 @@ public class LibvirtConnection {
|
||||
|
||||
return "qemu:///system";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up Libvirt event handling and polling. This is not specific to a connection object instance, but needs
|
||||
* to be done prior to creating connections. See the Libvirt documentation for virEventRegisterDefaultImpl and
|
||||
* virEventRunDefaultImpl or the libvirt-java Library Javadoc for more information.
|
||||
* @throws LibvirtException
|
||||
*/
|
||||
private static synchronized void setupEventListener() throws LibvirtException {
|
||||
if (libvirtEventThread == null || !libvirtEventThread.isAlive()) {
|
||||
// Registers a default event loop, must be called before connecting to hypervisor
|
||||
Library.initEventLoop();
|
||||
libvirtEventThread = new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
// This blocking call contains a loop of its own that will process events until the event loop is stopped or exception is thrown.
|
||||
Library.runEventLoop();
|
||||
} catch (LibvirtException e) {
|
||||
s_logger.error("LibvirtException was thrown in event loop: ", e);
|
||||
} catch (InterruptedException e) {
|
||||
s_logger.error("Libvirt event loop was interrupted: ", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Process events in separate thread. Failure to run event loop regularly will cause connections to close due to keepalive timeout.
|
||||
libvirtEventThread.setDaemon(true);
|
||||
libvirtEventThread.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,6 +117,8 @@ SP_API_HTTP - address of StorPool Api
|
||||
SP_AUTH_TOKEN - StorPool's token
|
||||
SP_TEMPLATE - name of StorPool's template
|
||||
|
||||
> **NOTE:** You can use the alternative format option for the URL - storpool://{SP_AUTH_TOKEN}@{SP_API_HTTP}:{SP_API_HTTP_PORT}/{SP_TEMPLATE}
|
||||
|
||||
Storage Tags: If left blank, the StorPool storage plugin will use the pool name to create a corresponding storage tag.
|
||||
This storage tag may be used later, when defining service or disk offerings.
|
||||
|
||||
|
||||
@ -172,6 +172,12 @@ public class StorPoolUtil {
|
||||
private String templateName;
|
||||
|
||||
public SpConnectionDesc(String url) {
|
||||
try {
|
||||
extractUriParams(url);
|
||||
return;
|
||||
} catch (URISyntaxException e) {
|
||||
log.debug("[ignore] the uri is not valid");
|
||||
}
|
||||
String[] urlSplit = url.split(";");
|
||||
if (urlSplit.length == 1 && !urlSplit[0].contains("=")) {
|
||||
this.templateName = url;
|
||||
@ -240,6 +246,16 @@ public class StorPoolUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private void extractUriParams(String url) throws URISyntaxException {
|
||||
URI uri = new URI(url);
|
||||
if (!StringUtils.equalsIgnoreCase(uri.getScheme(), "storpool")) {
|
||||
throw new CloudRuntimeException("The scheme is invalid. The URL should be with a format storpool://{SP_AUTH_TOKEN}@{SP_API_HTTP}:{SP_API_HTTP_PORT}/{SP_TEMPLATE}");
|
||||
}
|
||||
hostPort = uri.getHost() + ":" + uri.getPort();
|
||||
authToken = uri.getUserInfo();
|
||||
templateName = uri.getPath().replace("/", "");
|
||||
}
|
||||
|
||||
public SpConnectionDesc(String host, String authToken2, String templateName2) {
|
||||
this.hostPort = host;
|
||||
this.authToken = authToken2;
|
||||
|
||||
@ -727,7 +727,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
||||
if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) && (alertType != AlertManager.AlertType.ALERT_TYPE_USERVM)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER) && (alertType != AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_SSVM) && (alertType != AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE) && (alertType != AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_MANAGEMENT_NODE) && (alertType != AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED) && (alertType != AlertManager.AlertType.ALERT_TYPE_OOBM_AUTH_ERROR)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_HA_ACTION) && (alertType != AlertManager.AlertType.ALERT_TYPE_CA_CERT)) {
|
||||
alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId, clusterId);
|
||||
|
||||
@ -70,7 +70,7 @@ public class ClusterAlertAdapter extends AdapterBase implements AlertAdapter {
|
||||
s_logger.debug("Management server node " + mshost.getServiceIP() + " is up, send alert");
|
||||
}
|
||||
|
||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management server node " + mshost.getServiceIP() + " is up", "");
|
||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGEMENT_NODE, 0, new Long(0), "Management server node " + mshost.getServiceIP() + " is up", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -90,7 +90,7 @@ public class ClusterAlertAdapter extends AdapterBase implements AlertAdapter {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Detected management server node " + mshost.getServiceIP() + " is down, send alert");
|
||||
}
|
||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management server node " + mshost.getServiceIP() + " is down",
|
||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGEMENT_NODE, 0, new Long(0), "Management server node " + mshost.getServiceIP() + " is down",
|
||||
"");
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
|
||||
@ -651,12 +651,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
if (localCidrs != null && localCidrs.length > 0) {
|
||||
s_logger.warn("Management network CIDR is not configured originally. Set it default to " + localCidrs[0]);
|
||||
|
||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management network CIDR is not configured originally. Set it default to "
|
||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGEMENT_NODE, 0, new Long(0), "Management network CIDR is not configured originally. Set it default to "
|
||||
+ localCidrs[0], "");
|
||||
_configDao.update(Config.ManagementNetwork.key(), Config.ManagementNetwork.getCategory(), localCidrs[0]);
|
||||
} else {
|
||||
s_logger.warn("Management network CIDR is not properly configured and we are not able to find a default setting");
|
||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0),
|
||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGEMENT_NODE, 0, new Long(0),
|
||||
"Management network CIDR is not properly configured and we are not able to find a default setting", "");
|
||||
}
|
||||
}
|
||||
|
||||
@ -3261,6 +3261,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_UPDATE_IMAGE_STORE_ACCESS_STATE,
|
||||
eventDescription = "image store access updated")
|
||||
public ImageStore updateImageStoreStatus(Long id, Boolean readonly) {
|
||||
// Input validation
|
||||
ImageStoreVO imageStoreVO = _imageStoreDao.findById(id);
|
||||
|
||||
@ -354,6 +354,7 @@ import com.cloud.utils.db.GlobalLock;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.TransactionCallbackNoReturn;
|
||||
import com.cloud.utils.db.TransactionCallbackWithException;
|
||||
import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
|
||||
import com.cloud.utils.db.TransactionStatus;
|
||||
import com.cloud.utils.db.UUIDManager;
|
||||
@ -7765,49 +7766,68 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
|
||||
List<Volume> newVols = new ArrayList<>();
|
||||
for (VolumeVO root : rootVols) {
|
||||
if ( !Volume.State.Allocated.equals(root.getState()) || newTemplateId != null ){
|
||||
Long templateId = root.getTemplateId();
|
||||
boolean isISO = false;
|
||||
if (templateId == null) {
|
||||
// Assuming that for a vm deployed using ISO, template ID is set to NULL
|
||||
isISO = true;
|
||||
templateId = vm.getIsoId();
|
||||
}
|
||||
if ( !Volume.State.Allocated.equals(root.getState()) || newTemplateId != null ) {
|
||||
final UserVmVO userVm = vm;
|
||||
Pair<UserVmVO, Volume> vmAndNewVol = Transaction.execute(new TransactionCallbackWithException<Pair<UserVmVO, Volume>, CloudRuntimeException>() {
|
||||
@Override
|
||||
public Pair<UserVmVO, Volume> doInTransaction(final TransactionStatus status) throws CloudRuntimeException {
|
||||
Long templateId = root.getTemplateId();
|
||||
boolean isISO = false;
|
||||
if (templateId == null) {
|
||||
// Assuming that for a vm deployed using ISO, template ID is set to NULL
|
||||
isISO = true;
|
||||
templateId = userVm.getIsoId();
|
||||
}
|
||||
|
||||
/* If new template/ISO is provided allocate a new volume from new template/ISO otherwise allocate new volume from original template/ISO */
|
||||
Volume newVol = null;
|
||||
if (newTemplateId != null) {
|
||||
if (isISO) {
|
||||
newVol = volumeMgr.allocateDuplicateVolume(root, null);
|
||||
vm.setIsoId(newTemplateId);
|
||||
vm.setGuestOSId(template.getGuestOSId());
|
||||
vm.setTemplateId(newTemplateId);
|
||||
} else {
|
||||
newVol = volumeMgr.allocateDuplicateVolume(root, newTemplateId);
|
||||
vm.setGuestOSId(template.getGuestOSId());
|
||||
vm.setTemplateId(newTemplateId);
|
||||
/* If new template/ISO is provided allocate a new volume from new template/ISO otherwise allocate new volume from original template/ISO */
|
||||
Volume newVol = null;
|
||||
if (newTemplateId != null) {
|
||||
if (isISO) {
|
||||
newVol = volumeMgr.allocateDuplicateVolume(root, null);
|
||||
userVm.setIsoId(newTemplateId);
|
||||
userVm.setGuestOSId(template.getGuestOSId());
|
||||
userVm.setTemplateId(newTemplateId);
|
||||
} else {
|
||||
newVol = volumeMgr.allocateDuplicateVolume(root, newTemplateId);
|
||||
userVm.setGuestOSId(template.getGuestOSId());
|
||||
userVm.setTemplateId(newTemplateId);
|
||||
}
|
||||
// check and update VM if it can be dynamically scalable with the new template
|
||||
updateVMDynamicallyScalabilityUsingTemplate(userVm, newTemplateId);
|
||||
} else {
|
||||
newVol = volumeMgr.allocateDuplicateVolume(root, null);
|
||||
}
|
||||
newVols.add(newVol);
|
||||
|
||||
if (userVmDetailsDao.findDetail(userVm.getId(), VmDetailConstants.ROOT_DISK_SIZE) == null && !newVol.getSize().equals(template.getSize())) {
|
||||
VolumeVO resizedVolume = (VolumeVO) newVol;
|
||||
if (template.getSize() != null) {
|
||||
resizedVolume.setSize(template.getSize());
|
||||
_volsDao.update(resizedVolume.getId(), resizedVolume);
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Save usage event and update resource count for user vm volumes
|
||||
try {
|
||||
_resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.volume, newVol.isDisplay());
|
||||
_resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.primary_storage, newVol.isDisplay(), new Long(newVol.getSize()));
|
||||
} catch (final CloudRuntimeException e) {
|
||||
throw e;
|
||||
} catch (final Exception e) {
|
||||
s_logger.error("Unable to restore VM " + userVm.getUuid(), e);
|
||||
throw new CloudRuntimeException(e);
|
||||
}
|
||||
|
||||
// 2. Create Usage event for the newly created volume
|
||||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, newVol.getAccountId(), newVol.getDataCenterId(), newVol.getId(), newVol.getName(), newVol.getDiskOfferingId(), template.getId(), newVol.getSize());
|
||||
_usageEventDao.persist(usageEvent);
|
||||
|
||||
return new Pair<>(userVm, newVol);
|
||||
}
|
||||
// check and update VM if it can be dynamically scalable with the new template
|
||||
updateVMDynamicallyScalabilityUsingTemplate(vm, newTemplateId);
|
||||
} else {
|
||||
newVol = volumeMgr.allocateDuplicateVolume(root, null);
|
||||
}
|
||||
newVols.add(newVol);
|
||||
});
|
||||
|
||||
if (userVmDetailsDao.findDetail(vm.getId(), VmDetailConstants.ROOT_DISK_SIZE) == null && !newVol.getSize().equals(template.getSize())) {
|
||||
VolumeVO resizedVolume = (VolumeVO) newVol;
|
||||
if (template.getSize() != null) {
|
||||
resizedVolume.setSize(template.getSize());
|
||||
_volsDao.update(resizedVolume.getId(), resizedVolume);
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Save usage event and update resource count for user vm volumes
|
||||
_resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.volume, newVol.isDisplay());
|
||||
_resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.primary_storage, newVol.isDisplay(), new Long(newVol.getSize()));
|
||||
// 2. Create Usage event for the newly created volume
|
||||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, newVol.getAccountId(), newVol.getDataCenterId(), newVol.getId(), newVol.getName(), newVol.getDiskOfferingId(), template.getId(), newVol.getSize());
|
||||
_usageEventDao.persist(usageEvent);
|
||||
vm = vmAndNewVol.first();
|
||||
Volume newVol = vmAndNewVol.second();
|
||||
|
||||
handleManagedStorage(vm, root);
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InsufficientServerCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.host.Host;
|
||||
@ -47,6 +48,8 @@ import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.GuestOSVO;
|
||||
import com.cloud.storage.ScopeType;
|
||||
import com.cloud.storage.Snapshot;
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.Volume;
|
||||
@ -54,6 +57,7 @@ import com.cloud.storage.VolumeApiService;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.GuestOSDao;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.template.VirtualMachineTemplate;
|
||||
@ -66,6 +70,7 @@ import com.cloud.user.UserData;
|
||||
import com.cloud.user.UserDataVO;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.user.dao.UserDataDao;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.Pair;
|
||||
@ -74,10 +79,14 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
|
||||
import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
|
||||
import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.DeployVnfApplianceCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ResetVMUserDataCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
@ -191,6 +200,9 @@ public class UserVmManagerImplTest {
|
||||
@Mock
|
||||
private AccountDao accountDao;
|
||||
|
||||
@Mock
|
||||
private UserDao userDao;
|
||||
|
||||
@Mock
|
||||
ResourceLimitService resourceLimitMgr;
|
||||
|
||||
@ -218,6 +230,12 @@ public class UserVmManagerImplTest {
|
||||
@Mock
|
||||
private VolumeDao volumeDaoMock;
|
||||
|
||||
@Mock
|
||||
private SnapshotDao snapshotDaoMock;
|
||||
|
||||
@Mock
|
||||
private VMSnapshotDao vmSnapshotDaoMock;
|
||||
|
||||
@Mock
|
||||
AccountVO account;
|
||||
|
||||
@ -1221,4 +1239,160 @@ public class UserVmManagerImplTest {
|
||||
Mockito.verify(userVmVoMock).setLastHostId(2L);
|
||||
Mockito.verify(userVmVoMock).setState(VirtualMachine.State.Running);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testRestoreVMNoVM() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
CallContext callContextMock = Mockito.mock(CallContext.class);
|
||||
Mockito.lenient().doReturn(accountMock).when(callContextMock).getCallingAccount();
|
||||
|
||||
RestoreVMCmd cmd = Mockito.mock(RestoreVMCmd.class);
|
||||
when(cmd.getVmId()).thenReturn(vmId);
|
||||
when(cmd.getTemplateId()).thenReturn(2L);
|
||||
when(userVmDao.findById(vmId)).thenReturn(null);
|
||||
|
||||
userVmManagerImpl.restoreVM(cmd);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testRestoreVMWithVolumeSnapshots() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
CallContext callContextMock = Mockito.mock(CallContext.class);
|
||||
Mockito.lenient().doReturn(accountMock).when(callContextMock).getCallingAccount();
|
||||
Mockito.lenient().doNothing().when(accountManager).checkAccess(accountMock, null, true, userVmVoMock);
|
||||
|
||||
RestoreVMCmd cmd = Mockito.mock(RestoreVMCmd.class);
|
||||
when(cmd.getVmId()).thenReturn(vmId);
|
||||
when(cmd.getTemplateId()).thenReturn(2L);
|
||||
when(userVmDao.findById(vmId)).thenReturn(userVmVoMock);
|
||||
|
||||
List<VolumeVO> volumes = new ArrayList<>();
|
||||
long rootVolumeId = 1l;
|
||||
VolumeVO rootVolumeOfVm = Mockito.mock(VolumeVO.class);
|
||||
Mockito.when(rootVolumeOfVm.getId()).thenReturn(rootVolumeId);
|
||||
volumes.add(rootVolumeOfVm);
|
||||
when(volumeDaoMock.findByInstanceAndType(vmId, Volume.Type.ROOT)).thenReturn(volumes);
|
||||
|
||||
List<SnapshotVO> snapshots = new ArrayList<>();
|
||||
SnapshotVO snapshot = Mockito.mock(SnapshotVO.class);
|
||||
snapshots.add(snapshot);
|
||||
when(snapshotDaoMock.listByStatus(rootVolumeId, Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp)).thenReturn(snapshots);
|
||||
|
||||
userVmManagerImpl.restoreVM(cmd);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testRestoreVirtualMachineNoOwner() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
long userId = 1l;
|
||||
long accountId = 2l;
|
||||
long newTemplateId = 2l;
|
||||
when(accountMock.getId()).thenReturn(userId);
|
||||
when(userVmDao.findById(vmId)).thenReturn(userVmVoMock);
|
||||
when(userVmVoMock.getAccountId()).thenReturn(accountId);
|
||||
when(accountDao.findById(accountId)).thenReturn(null);
|
||||
|
||||
userVmManagerImpl.restoreVirtualMachine(accountMock, vmId, newTemplateId);
|
||||
}
|
||||
|
||||
@Test(expected = PermissionDeniedException.class)
|
||||
public void testRestoreVirtualMachineOwnerDisabled() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
long userId = 1l;
|
||||
long accountId = 2l;
|
||||
long newTemplateId = 2l;
|
||||
when(accountMock.getId()).thenReturn(userId);
|
||||
when(userVmDao.findById(vmId)).thenReturn(userVmVoMock);
|
||||
when(userVmVoMock.getAccountId()).thenReturn(accountId);
|
||||
when(accountDao.findById(accountId)).thenReturn(callerAccount);
|
||||
when(callerAccount.getState()).thenReturn(Account.State.DISABLED);
|
||||
|
||||
userVmManagerImpl.restoreVirtualMachine(accountMock, vmId, newTemplateId);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testRestoreVirtualMachineNotInRightState() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
long userId = 1l;
|
||||
long accountId = 2l;
|
||||
long newTemplateId = 2l;
|
||||
when(accountMock.getId()).thenReturn(userId);
|
||||
when(userVmDao.findById(vmId)).thenReturn(userVmVoMock);
|
||||
when(userVmVoMock.getAccountId()).thenReturn(accountId);
|
||||
when(userVmVoMock.getUuid()).thenReturn("a967643d-7633-4ab4-ac26-9c0b63f50cc1");
|
||||
when(accountDao.findById(accountId)).thenReturn(callerAccount);
|
||||
when(userVmVoMock.getState()).thenReturn(VirtualMachine.State.Starting);
|
||||
|
||||
userVmManagerImpl.restoreVirtualMachine(accountMock, vmId, newTemplateId);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testRestoreVirtualMachineNoRootVolume() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
long userId = 1l;
|
||||
long accountId = 2l;
|
||||
long currentTemplateId = 1l;
|
||||
long newTemplateId = 2l;
|
||||
when(accountMock.getId()).thenReturn(userId);
|
||||
when(userVmDao.findById(vmId)).thenReturn(userVmVoMock);
|
||||
when(userVmVoMock.getAccountId()).thenReturn(accountId);
|
||||
when(userVmVoMock.getUuid()).thenReturn("a967643d-7633-4ab4-ac26-9c0b63f50cc1");
|
||||
when(accountDao.findById(accountId)).thenReturn(callerAccount);
|
||||
when(userVmVoMock.getState()).thenReturn(VirtualMachine.State.Running);
|
||||
when(userVmVoMock.getTemplateId()).thenReturn(currentTemplateId);
|
||||
|
||||
VMTemplateVO currentTemplate = Mockito.mock(VMTemplateVO.class);
|
||||
when(templateDao.findById(currentTemplateId)).thenReturn(currentTemplate);
|
||||
when(volumeDaoMock.findByInstanceAndType(vmId, Volume.Type.ROOT)).thenReturn(new ArrayList<VolumeVO>());
|
||||
|
||||
userVmManagerImpl.restoreVirtualMachine(accountMock, vmId, newTemplateId);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testRestoreVirtualMachineMoreThanOneRootVolume() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
long userId = 1l;
|
||||
long accountId = 2l;
|
||||
long currentTemplateId = 1l;
|
||||
long newTemplateId = 2l;
|
||||
when(accountMock.getId()).thenReturn(userId);
|
||||
when(userVmDao.findById(vmId)).thenReturn(userVmVoMock);
|
||||
when(userVmVoMock.getAccountId()).thenReturn(accountId);
|
||||
when(userVmVoMock.getUuid()).thenReturn("a967643d-7633-4ab4-ac26-9c0b63f50cc1");
|
||||
when(accountDao.findById(accountId)).thenReturn(callerAccount);
|
||||
when(userVmVoMock.getState()).thenReturn(VirtualMachine.State.Running);
|
||||
when(userVmVoMock.getTemplateId()).thenReturn(currentTemplateId);
|
||||
|
||||
VMTemplateVO currentTemplate = Mockito.mock(VMTemplateVO.class);
|
||||
when(currentTemplate.isDeployAsIs()).thenReturn(false);
|
||||
when(templateDao.findById(currentTemplateId)).thenReturn(currentTemplate);
|
||||
List<VolumeVO> volumes = new ArrayList<>();
|
||||
VolumeVO rootVolume1 = Mockito.mock(VolumeVO.class);
|
||||
volumes.add(rootVolume1);
|
||||
VolumeVO rootVolume2 = Mockito.mock(VolumeVO.class);
|
||||
volumes.add(rootVolume2);
|
||||
when(volumeDaoMock.findByInstanceAndType(vmId, Volume.Type.ROOT)).thenReturn(volumes);
|
||||
|
||||
userVmManagerImpl.restoreVirtualMachine(accountMock, vmId, newTemplateId);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testRestoreVirtualMachineWithVMSnapshots() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
long userId = 1l;
|
||||
long accountId = 2l;
|
||||
long currentTemplateId = 1l;
|
||||
long newTemplateId = 2l;
|
||||
when(accountMock.getId()).thenReturn(userId);
|
||||
when(userVmDao.findById(vmId)).thenReturn(userVmVoMock);
|
||||
when(userVmVoMock.getAccountId()).thenReturn(accountId);
|
||||
when(accountDao.findById(accountId)).thenReturn(callerAccount);
|
||||
when(userVmVoMock.getState()).thenReturn(VirtualMachine.State.Running);
|
||||
when(userVmVoMock.getTemplateId()).thenReturn(currentTemplateId);
|
||||
|
||||
VMTemplateVO currentTemplate = Mockito.mock(VMTemplateVO.class);
|
||||
when(templateDao.findById(currentTemplateId)).thenReturn(currentTemplate);
|
||||
List<VolumeVO> volumes = new ArrayList<>();
|
||||
VolumeVO rootVolumeOfVm = Mockito.mock(VolumeVO.class);
|
||||
volumes.add(rootVolumeOfVm);
|
||||
when(volumeDaoMock.findByInstanceAndType(vmId, Volume.Type.ROOT)).thenReturn(volumes);
|
||||
List<VMSnapshotVO> vmSnapshots = new ArrayList<>();
|
||||
VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
|
||||
vmSnapshots.add(vmSnapshot);
|
||||
when(vmSnapshotDaoMock.findByVm(vmId)).thenReturn(vmSnapshots);
|
||||
|
||||
userVmManagerImpl.restoreVirtualMachine(accountMock, vmId, newTemplateId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,7 +340,7 @@
|
||||
<template v-if="column.key === 'softwareversion'">
|
||||
<span> {{ record.softwareversion ? record.softwareversion : 'N/A' }} </span>
|
||||
</template>
|
||||
<template v-if="column.key === 'access'">
|
||||
<template v-if="column.key === 'readonly'">
|
||||
<status :text="record.readonly ? 'ReadOnly' : 'ReadWrite'" displayText />
|
||||
</template>
|
||||
<template v-if="column.key === 'requiresupgrade'">
|
||||
|
||||
@ -83,7 +83,7 @@ public class UsageAlertManagerImpl extends ManagerBase implements AlertManager {
|
||||
if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) && (alertType != AlertManager.AlertType.ALERT_TYPE_USERVM)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER) && (alertType != AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_SSVM) && (alertType != AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE)) {
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_MANAGEMENT_NODE)) {
|
||||
alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId);
|
||||
}
|
||||
if (alert == null) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user