mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
server: add Host Control Plane State to uservm and systemvm response (#6946)
Co-authored-by: dahn <daan.hoogland@gmail.com>
This commit is contained in:
parent
d0b34b7576
commit
1380c604b1
41
api/src/main/java/com/cloud/host/ControlState.java
Normal file
41
api/src/main/java/com/cloud/host/ControlState.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// 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.host;
|
||||||
|
|
||||||
|
import com.cloud.resource.ResourceState;
|
||||||
|
|
||||||
|
public enum ControlState {
|
||||||
|
Enabled,
|
||||||
|
Disabled,
|
||||||
|
Offline,
|
||||||
|
Maintenance,
|
||||||
|
Unknown;
|
||||||
|
|
||||||
|
public static ControlState getControlState(Status hostStatus, ResourceState hostResourceState) {
|
||||||
|
if (hostStatus == null || Status.Unknown.equals(hostStatus) || hostResourceState == null) {
|
||||||
|
return ControlState.Unknown;
|
||||||
|
} else if (hostStatus.lostConnection()) {
|
||||||
|
return Offline;
|
||||||
|
} else if (ResourceState.isMaintenanceState(hostResourceState)) {
|
||||||
|
return Maintenance;
|
||||||
|
} else if (ResourceState.Enabled.equals(hostResourceState)) {
|
||||||
|
return Enabled;
|
||||||
|
} else {
|
||||||
|
return Disabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -203,6 +203,7 @@ public class ApiConstants {
|
|||||||
public static final String HOST_ID = "hostid";
|
public static final String HOST_ID = "hostid";
|
||||||
public static final String HOST_IDS = "hostids";
|
public static final String HOST_IDS = "hostids";
|
||||||
public static final String HOST_NAME = "hostname";
|
public static final String HOST_NAME = "hostname";
|
||||||
|
public static final String HOST_CONTROL_STATE = "hostcontrolstate";
|
||||||
public static final String HOSTS_MAP = "hostsmap";
|
public static final String HOSTS_MAP = "hostsmap";
|
||||||
public static final String HYPERVISOR = "hypervisor";
|
public static final String HYPERVISOR = "hypervisor";
|
||||||
public static final String INLINE = "inline";
|
public static final String INLINE = "inline";
|
||||||
|
|||||||
@ -89,6 +89,10 @@ public class DomainRouterResponse extends BaseResponseWithAnnotations implements
|
|||||||
@Param(description = "the hostname for the router")
|
@Param(description = "the hostname for the router")
|
||||||
private String hostName;
|
private String hostName;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.HOST_CONTROL_STATE)
|
||||||
|
@Param(description = "the control state of the host for the router")
|
||||||
|
private String hostControlState;
|
||||||
|
|
||||||
@SerializedName("hypervisor")
|
@SerializedName("hypervisor")
|
||||||
@Param(description = "the hypervisor on which the template runs")
|
@Param(description = "the hypervisor on which the template runs")
|
||||||
private String hypervisor;
|
private String hypervisor;
|
||||||
@ -302,6 +306,10 @@ public class DomainRouterResponse extends BaseResponseWithAnnotations implements
|
|||||||
this.hostName = hostName;
|
this.hostName = hostName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHostControlState(String hostControlState) {
|
||||||
|
this.hostControlState = hostControlState;
|
||||||
|
}
|
||||||
|
|
||||||
public String getHypervisor() {
|
public String getHypervisor() {
|
||||||
return hypervisor;
|
return hypervisor;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,6 +90,10 @@ public class SystemVmResponse extends BaseResponseWithAnnotations {
|
|||||||
@Param(description = "the hostname for the system VM")
|
@Param(description = "the hostname for the system VM")
|
||||||
private String hostName;
|
private String hostName;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.HOST_CONTROL_STATE)
|
||||||
|
@Param(description = "the control state of the host for the system VM")
|
||||||
|
private String hostControlState;
|
||||||
|
|
||||||
@SerializedName("hypervisor")
|
@SerializedName("hypervisor")
|
||||||
@Param(description = "the hypervisor on which the template runs")
|
@Param(description = "the hypervisor on which the template runs")
|
||||||
private String hypervisor;
|
private String hypervisor;
|
||||||
@ -283,6 +287,14 @@ public class SystemVmResponse extends BaseResponseWithAnnotations {
|
|||||||
this.hostName = hostName;
|
this.hostName = hostName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getHostControlState() {
|
||||||
|
return hostControlState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHostControlState(String hostControlState) {
|
||||||
|
this.hostControlState = hostControlState;
|
||||||
|
}
|
||||||
|
|
||||||
public String getHypervisor() {
|
public String getHypervisor() {
|
||||||
return hypervisor;
|
return hypervisor;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,6 +118,10 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
|||||||
@Param(description = "the name of the host for the virtual machine")
|
@Param(description = "the name of the host for the virtual machine")
|
||||||
private String hostName;
|
private String hostName;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.HOST_CONTROL_STATE)
|
||||||
|
@Param(description = "the control state of the host for the virtual machine")
|
||||||
|
private String hostControlState;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.TEMPLATE_ID)
|
@SerializedName(ApiConstants.TEMPLATE_ID)
|
||||||
@Param(description = "the ID of the template for the virtual machine. A -1 is returned if the virtual machine was created from an ISO file.")
|
@Param(description = "the ID of the template for the virtual machine. A -1 is returned if the virtual machine was created from an ISO file.")
|
||||||
private String templateId;
|
private String templateId;
|
||||||
@ -461,6 +465,10 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
|||||||
return hostName;
|
return hostName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getHostControlState() {
|
||||||
|
return hostControlState;
|
||||||
|
}
|
||||||
|
|
||||||
public String getTemplateId() {
|
public String getTemplateId() {
|
||||||
return templateId;
|
return templateId;
|
||||||
}
|
}
|
||||||
@ -703,6 +711,10 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
|||||||
this.hostName = hostName;
|
this.hostName = hostName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHostControlState(String hostControlState) {
|
||||||
|
this.hostControlState = hostControlState;
|
||||||
|
}
|
||||||
|
|
||||||
public void setTemplateId(String templateId) {
|
public void setTemplateId(String templateId) {
|
||||||
this.templateId = templateId;
|
this.templateId = templateId;
|
||||||
}
|
}
|
||||||
|
|||||||
109
api/src/test/java/com/cloud/host/ControlStateTest.java
Normal file
109
api/src/test/java/com/cloud/host/ControlStateTest.java
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// 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.host;
|
||||||
|
|
||||||
|
import com.cloud.resource.ResourceState;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ControlStateTest extends TestCase {
|
||||||
|
|
||||||
|
void verifyHostControlState(Status hostStatus, ResourceState hostResourceState, ControlState expectedControlState) {
|
||||||
|
Assert.assertEquals(expectedControlState, ControlState.getControlState(hostStatus, hostResourceState));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHostControlState1() {
|
||||||
|
// Unknown state
|
||||||
|
verifyHostControlState(null, null, ControlState.Unknown);
|
||||||
|
verifyHostControlState(null, ResourceState.Enabled, ControlState.Unknown);
|
||||||
|
verifyHostControlState(Status.Up, null, ControlState.Unknown);
|
||||||
|
verifyHostControlState(Status.Disconnected, null, ControlState.Unknown);
|
||||||
|
verifyHostControlState(Status.Down, null, ControlState.Unknown);
|
||||||
|
|
||||||
|
verifyHostControlState(Status.Unknown, null, ControlState.Unknown);
|
||||||
|
verifyHostControlState(Status.Unknown, ResourceState.Enabled, ControlState.Unknown);
|
||||||
|
verifyHostControlState(Status.Unknown, ResourceState.ErrorInPrepareForMaintenance, ControlState.Unknown);
|
||||||
|
verifyHostControlState(Status.Unknown, ResourceState.PrepareForMaintenance, ControlState.Unknown);
|
||||||
|
verifyHostControlState(Status.Unknown, ResourceState.ErrorInMaintenance, ControlState.Unknown);
|
||||||
|
verifyHostControlState(Status.Unknown, ResourceState.Maintenance, ControlState.Unknown);
|
||||||
|
verifyHostControlState(Status.Unknown, ResourceState.Creating, ControlState.Unknown);
|
||||||
|
verifyHostControlState(Status.Unknown, ResourceState.Disabled, ControlState.Unknown);
|
||||||
|
verifyHostControlState(Status.Unknown, ResourceState.Error, ControlState.Unknown);
|
||||||
|
verifyHostControlState(Status.Unknown, ResourceState.Degraded, ControlState.Unknown);
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void testHostControlState2() {
|
||||||
|
// Host is Up and Enabled
|
||||||
|
verifyHostControlState(Status.Creating, ResourceState.Enabled, ControlState.Enabled);
|
||||||
|
verifyHostControlState(Status.Connecting, ResourceState.Enabled, ControlState.Enabled);
|
||||||
|
verifyHostControlState(Status.Up, ResourceState.Enabled, ControlState.Enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHostControlState3() {
|
||||||
|
// Host is Up and not Enabled
|
||||||
|
verifyHostControlState(Status.Up, ResourceState.Creating, ControlState.Disabled);
|
||||||
|
verifyHostControlState(Status.Up, ResourceState.Disabled, ControlState.Disabled);
|
||||||
|
verifyHostControlState(Status.Up, ResourceState.Error, ControlState.Disabled);
|
||||||
|
verifyHostControlState(Status.Up, ResourceState.Degraded, ControlState.Disabled);
|
||||||
|
|
||||||
|
// Host is Creating and not Enabled
|
||||||
|
verifyHostControlState(Status.Creating, ResourceState.Creating, ControlState.Disabled);
|
||||||
|
verifyHostControlState(Status.Creating, ResourceState.Disabled, ControlState.Disabled);
|
||||||
|
verifyHostControlState(Status.Creating, ResourceState.Error, ControlState.Disabled);
|
||||||
|
verifyHostControlState(Status.Creating, ResourceState.Degraded, ControlState.Disabled);
|
||||||
|
|
||||||
|
// Host is Connecting and not Enabled
|
||||||
|
verifyHostControlState(Status.Connecting, ResourceState.Creating, ControlState.Disabled);
|
||||||
|
verifyHostControlState(Status.Connecting, ResourceState.Disabled, ControlState.Disabled);
|
||||||
|
verifyHostControlState(Status.Connecting, ResourceState.Error, ControlState.Disabled);
|
||||||
|
verifyHostControlState(Status.Connecting, ResourceState.Degraded, ControlState.Disabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHostControlState4() {
|
||||||
|
// Host is Up and Maintenance mode
|
||||||
|
verifyHostControlState(Status.Up, ResourceState.ErrorInPrepareForMaintenance, ControlState.Maintenance);
|
||||||
|
verifyHostControlState(Status.Up, ResourceState.PrepareForMaintenance, ControlState.Maintenance);
|
||||||
|
verifyHostControlState(Status.Up, ResourceState.ErrorInMaintenance, ControlState.Maintenance);
|
||||||
|
verifyHostControlState(Status.Up, ResourceState.Maintenance, ControlState.Maintenance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHostControlState5() {
|
||||||
|
// Host in other states and Enabled
|
||||||
|
verifyHostControlState(Status.Down, ResourceState.Enabled, ControlState.Offline);
|
||||||
|
verifyHostControlState(Status.Disconnected, ResourceState.Enabled, ControlState.Offline);
|
||||||
|
verifyHostControlState(Status.Alert, ResourceState.Enabled, ControlState.Offline);
|
||||||
|
verifyHostControlState(Status.Removed, ResourceState.Enabled, ControlState.Offline);
|
||||||
|
verifyHostControlState(Status.Error, ResourceState.Enabled, ControlState.Offline);
|
||||||
|
verifyHostControlState(Status.Rebalancing, ResourceState.Enabled, ControlState.Offline);
|
||||||
|
|
||||||
|
// Host in other states and Disabled
|
||||||
|
verifyHostControlState(Status.Down, ResourceState.Disabled, ControlState.Offline);
|
||||||
|
verifyHostControlState(Status.Disconnected, ResourceState.Disabled, ControlState.Offline);
|
||||||
|
verifyHostControlState(Status.Alert, ResourceState.Disabled, ControlState.Offline);
|
||||||
|
verifyHostControlState(Status.Removed, ResourceState.Disabled, ControlState.Offline);
|
||||||
|
verifyHostControlState(Status.Error, ResourceState.Disabled, ControlState.Offline);
|
||||||
|
verifyHostControlState(Status.Rebalancing, ResourceState.Disabled, ControlState.Offline);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -65,6 +65,8 @@ CREATE VIEW `cloud`.`domain_router_view` AS
|
|||||||
host.name host_name,
|
host.name host_name,
|
||||||
host.hypervisor_type,
|
host.hypervisor_type,
|
||||||
host.cluster_id cluster_id,
|
host.cluster_id cluster_id,
|
||||||
|
host.status host_status,
|
||||||
|
host.resource_state host_resource_state,
|
||||||
vm_template.id template_id,
|
vm_template.id template_id,
|
||||||
vm_template.uuid template_uuid,
|
vm_template.uuid template_uuid,
|
||||||
service_offering.id service_offering_id,
|
service_offering.id service_offering_id,
|
||||||
@ -744,6 +746,8 @@ SELECT
|
|||||||
`host`.`uuid` AS `host_uuid`,
|
`host`.`uuid` AS `host_uuid`,
|
||||||
`host`.`name` AS `host_name`,
|
`host`.`name` AS `host_name`,
|
||||||
`host`.`cluster_id` AS `cluster_id`,
|
`host`.`cluster_id` AS `cluster_id`,
|
||||||
|
`host`.`status` AS `host_status`,
|
||||||
|
`host`.`resource_state` AS `host_resource_state`,
|
||||||
`vm_template`.`id` AS `template_id`,
|
`vm_template`.`id` AS `template_id`,
|
||||||
`vm_template`.`uuid` AS `template_uuid`,
|
`vm_template`.`uuid` AS `template_uuid`,
|
||||||
`vm_template`.`name` AS `template_name`,
|
`vm_template`.`name` AS `template_name`,
|
||||||
|
|||||||
@ -37,6 +37,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.cloud.host.ControlState;
|
||||||
import com.cloud.utils.security.CertificateHelper;
|
import com.cloud.utils.security.CertificateHelper;
|
||||||
import com.cloud.user.UserData;
|
import com.cloud.user.UserData;
|
||||||
import com.cloud.api.query.dao.UserVmJoinDao;
|
import com.cloud.api.query.dao.UserVmJoinDao;
|
||||||
@ -1549,6 +1550,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||||||
if (host != null) {
|
if (host != null) {
|
||||||
vmResponse.setHostId(host.getUuid());
|
vmResponse.setHostId(host.getUuid());
|
||||||
vmResponse.setHostName(host.getName());
|
vmResponse.setHostName(host.getName());
|
||||||
|
vmResponse.setHostControlState(ControlState.getControlState(host.getStatus(), host.getResourceState()).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import com.cloud.api.ApiDBUtils;
|
|||||||
import com.cloud.api.ApiResponseHelper;
|
import com.cloud.api.ApiResponseHelper;
|
||||||
import com.cloud.api.query.vo.DomainRouterJoinVO;
|
import com.cloud.api.query.vo.DomainRouterJoinVO;
|
||||||
import com.cloud.dc.HostPodVO;
|
import com.cloud.dc.HostPodVO;
|
||||||
|
import com.cloud.host.ControlState;
|
||||||
import com.cloud.network.Networks.TrafficType;
|
import com.cloud.network.Networks.TrafficType;
|
||||||
import com.cloud.network.router.VirtualRouter;
|
import com.cloud.network.router.VirtualRouter;
|
||||||
import com.cloud.network.router.VirtualRouter.Role;
|
import com.cloud.network.router.VirtualRouter.Role;
|
||||||
@ -135,6 +136,7 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO,
|
|||||||
if (router.getHostId() != null) {
|
if (router.getHostId() != null) {
|
||||||
routerResponse.setHostId(router.getHostUuid());
|
routerResponse.setHostId(router.getHostUuid());
|
||||||
routerResponse.setHostName(router.getHostName());
|
routerResponse.setHostName(router.getHostName());
|
||||||
|
routerResponse.setHostControlState(ControlState.getControlState(router.getHostStatus(), router.getHostResourceState()).toString());
|
||||||
}
|
}
|
||||||
routerResponse.setPodId(router.getPodUuid());
|
routerResponse.setPodId(router.getPodUuid());
|
||||||
HostPodVO pod = ApiDBUtils.findPodById(router.getPodId());
|
HostPodVO pod = ApiDBUtils.findPodById(router.getPodId());
|
||||||
|
|||||||
@ -52,6 +52,7 @@ import com.cloud.api.ApiDBUtils;
|
|||||||
import com.cloud.api.ApiResponseHelper;
|
import com.cloud.api.ApiResponseHelper;
|
||||||
import com.cloud.api.query.vo.UserVmJoinVO;
|
import com.cloud.api.query.vo.UserVmJoinVO;
|
||||||
import com.cloud.gpu.GPU;
|
import com.cloud.gpu.GPU;
|
||||||
|
import com.cloud.host.ControlState;
|
||||||
import com.cloud.service.ServiceOfferingDetailsVO;
|
import com.cloud.service.ServiceOfferingDetailsVO;
|
||||||
import com.cloud.storage.GuestOS;
|
import com.cloud.storage.GuestOS;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
@ -172,6 +173,9 @@ public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation<UserVmJo
|
|||||||
userVmResponse.setHostId(userVm.getHostUuid());
|
userVmResponse.setHostId(userVm.getHostUuid());
|
||||||
userVmResponse.setHostName(userVm.getHostName());
|
userVmResponse.setHostName(userVm.getHostName());
|
||||||
}
|
}
|
||||||
|
if (userVm.getHostStatus() != null) {
|
||||||
|
userVmResponse.setHostControlState(ControlState.getControlState(userVm.getHostStatus(), userVm.getHostResourceState()).toString());
|
||||||
|
}
|
||||||
|
|
||||||
if (details.contains(VMDetails.all) || details.contains(VMDetails.tmpl)) {
|
if (details.contains(VMDetails.all) || details.contains(VMDetails.tmpl)) {
|
||||||
userVmResponse.setTemplateId(userVm.getTemplateUuid());
|
userVmResponse.setTemplateId(userVm.getTemplateUuid());
|
||||||
|
|||||||
@ -26,11 +26,13 @@ import javax.persistence.Enumerated;
|
|||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import com.cloud.host.Status;
|
||||||
import com.cloud.hypervisor.Hypervisor;
|
import com.cloud.hypervisor.Hypervisor;
|
||||||
import com.cloud.network.Network.GuestType;
|
import com.cloud.network.Network.GuestType;
|
||||||
import com.cloud.network.Networks.TrafficType;
|
import com.cloud.network.Networks.TrafficType;
|
||||||
import com.cloud.network.router.VirtualRouter;
|
import com.cloud.network.router.VirtualRouter;
|
||||||
import com.cloud.network.router.VirtualRouter.RedundantState;
|
import com.cloud.network.router.VirtualRouter.RedundantState;
|
||||||
|
import com.cloud.resource.ResourceState;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
@ -129,6 +131,12 @@ public class DomainRouterJoinVO extends BaseViewVO implements ControlledViewEnti
|
|||||||
@Column(name = "host_name", nullable = false)
|
@Column(name = "host_name", nullable = false)
|
||||||
private String hostName;
|
private String hostName;
|
||||||
|
|
||||||
|
@Column(name = "host_status")
|
||||||
|
private Status hostStatus;
|
||||||
|
|
||||||
|
@Column(name = "host_resource_state")
|
||||||
|
private ResourceState hostResourceState;
|
||||||
|
|
||||||
@Column(name="hypervisor_type")
|
@Column(name="hypervisor_type")
|
||||||
@Enumerated(value=EnumType.STRING)
|
@Enumerated(value=EnumType.STRING)
|
||||||
private Hypervisor.HypervisorType hypervisorType;
|
private Hypervisor.HypervisorType hypervisorType;
|
||||||
@ -354,6 +362,14 @@ public class DomainRouterJoinVO extends BaseViewVO implements ControlledViewEnti
|
|||||||
return hostName;
|
return hostName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Status getHostStatus() {
|
||||||
|
return hostStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceState getHostResourceState() {
|
||||||
|
return hostResourceState;
|
||||||
|
}
|
||||||
|
|
||||||
public Hypervisor.HypervisorType getHypervisorType() {
|
public Hypervisor.HypervisorType getHypervisorType() {
|
||||||
return hypervisorType;
|
return hypervisorType;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,9 +29,11 @@ import javax.persistence.Id;
|
|||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.Transient;
|
import javax.persistence.Transient;
|
||||||
|
|
||||||
|
import com.cloud.host.Status;
|
||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
import com.cloud.network.Network.GuestType;
|
import com.cloud.network.Network.GuestType;
|
||||||
import com.cloud.network.Networks.TrafficType;
|
import com.cloud.network.Networks.TrafficType;
|
||||||
|
import com.cloud.resource.ResourceState;
|
||||||
import com.cloud.storage.Storage.StoragePoolType;
|
import com.cloud.storage.Storage.StoragePoolType;
|
||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
@ -171,9 +173,15 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
|
|||||||
@Column(name = "host_uuid")
|
@Column(name = "host_uuid")
|
||||||
private String hostUuid;
|
private String hostUuid;
|
||||||
|
|
||||||
@Column(name = "host_name", nullable = false)
|
@Column(name = "host_name")
|
||||||
private String hostName;
|
private String hostName;
|
||||||
|
|
||||||
|
@Column(name = "host_status")
|
||||||
|
private Status hostStatus;
|
||||||
|
|
||||||
|
@Column(name = "host_resource_state")
|
||||||
|
private ResourceState hostResourceState;
|
||||||
|
|
||||||
@Column(name = "template_id", updatable = true, nullable = true, length = 17)
|
@Column(name = "template_id", updatable = true, nullable = true, length = 17)
|
||||||
private long templateId;
|
private long templateId;
|
||||||
|
|
||||||
@ -604,6 +612,14 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
|
|||||||
return hostName;
|
return hostName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Status getHostStatus() {
|
||||||
|
return hostStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceState getHostResourceState() {
|
||||||
|
return hostResourceState;
|
||||||
|
}
|
||||||
|
|
||||||
public long getTemplateId() {
|
public long getTemplateId() {
|
||||||
return templateId;
|
return templateId;
|
||||||
}
|
}
|
||||||
|
|||||||
252
test/integration/smoke/test_host_control_state.py
Normal file
252
test/integration/smoke/test_host_control_state.py
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Tests for host control state
|
||||||
|
"""
|
||||||
|
|
||||||
|
from marvin.cloudstackAPI import updateHost
|
||||||
|
from nose.plugins.attrib import attr
|
||||||
|
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||||
|
from marvin.lib.common import (get_domain,
|
||||||
|
get_zone,
|
||||||
|
get_template,
|
||||||
|
list_hosts,
|
||||||
|
list_routers,
|
||||||
|
list_ssvms)
|
||||||
|
from marvin.lib.base import (Account,
|
||||||
|
Domain,
|
||||||
|
Host,
|
||||||
|
ServiceOffering,
|
||||||
|
VirtualMachine)
|
||||||
|
from marvin.sshClient import SshClient
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
class TestHostControlState(cloudstackTestCase):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
cls.testClient = super(TestHostControlState, cls).getClsTestClient()
|
||||||
|
cls.apiclient = cls.testClient.getApiClient()
|
||||||
|
cls.services = cls.testClient.getParsedTestDataConfig()
|
||||||
|
# Get Zone, Domain and templates
|
||||||
|
cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
|
||||||
|
cls.hypervisor = cls.testClient.getHypervisorInfo()
|
||||||
|
cls.hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][0].__dict__
|
||||||
|
|
||||||
|
cls.template = get_template(
|
||||||
|
cls.apiclient,
|
||||||
|
cls.zone.id,
|
||||||
|
cls.hypervisor
|
||||||
|
)
|
||||||
|
|
||||||
|
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||||
|
cls.services["template"] = cls.template.id
|
||||||
|
cls.services["zoneid"] = cls.zone.id
|
||||||
|
|
||||||
|
cls._cleanup = []
|
||||||
|
|
||||||
|
cls.domain = Domain.create(
|
||||||
|
cls.apiclient,
|
||||||
|
cls.services["acl"]["domain1"]
|
||||||
|
)
|
||||||
|
cls._cleanup.append(cls.domain)
|
||||||
|
cls.account = Account.create(
|
||||||
|
cls.apiclient,
|
||||||
|
cls.services["account"],
|
||||||
|
domainid=cls.domain.id
|
||||||
|
)
|
||||||
|
cls._cleanup.append(cls.account)
|
||||||
|
cls.service_offering = ServiceOffering.create(
|
||||||
|
cls.apiclient,
|
||||||
|
cls.services["service_offerings"]["tiny"]
|
||||||
|
)
|
||||||
|
cls._cleanup.append(cls.service_offering)
|
||||||
|
cls.vm = VirtualMachine.create(
|
||||||
|
cls.apiclient,
|
||||||
|
cls.services["virtual_machine"],
|
||||||
|
templateid=cls.template.id,
|
||||||
|
accountid=cls.account.name,
|
||||||
|
domainid=cls.account.domainid,
|
||||||
|
serviceofferingid=cls.service_offering.id
|
||||||
|
)
|
||||||
|
cls._cleanup.append(cls.vm)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
super(TestHostControlState, cls).tearDownClass()
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.apiclient = self.testClient.getApiClient()
|
||||||
|
self.cleanup = []
|
||||||
|
return
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(TestHostControlState, self).tearDown()
|
||||||
|
|
||||||
|
def disable_host(self, id):
|
||||||
|
cmd = updateHost.updateHostCmd()
|
||||||
|
cmd.id = id
|
||||||
|
cmd.allocationstate = "Disable"
|
||||||
|
response = self.apiclient.updateHost(cmd)
|
||||||
|
self.assertEqual(response.resourcestate, "Disabled")
|
||||||
|
|
||||||
|
def enable_host(self, id):
|
||||||
|
cmd = updateHost.updateHostCmd()
|
||||||
|
cmd.id = id
|
||||||
|
cmd.allocationstate = "Enable"
|
||||||
|
response = self.apiclient.updateHost(cmd)
|
||||||
|
self.assertEqual(response.resourcestate, "Enabled")
|
||||||
|
|
||||||
|
def get_host_ipaddress(self, hostId):
|
||||||
|
hosts = list_hosts(
|
||||||
|
self.apiclient,
|
||||||
|
type='Routing',
|
||||||
|
id=hostId
|
||||||
|
)
|
||||||
|
return hosts[0].ipaddress
|
||||||
|
|
||||||
|
def stop_agent(self, host_ipaddress):
|
||||||
|
SshClient(host_ipaddress, port=22, user=self.hostConfig["username"], passwd=self.hostConfig["password"]).execute\
|
||||||
|
("systemctl stop cloudstack-agent || service cloudstack-agent stop")
|
||||||
|
|
||||||
|
def start_agent(self, host_ipaddress):
|
||||||
|
SshClient(host_ipaddress, port=22, user=self.hostConfig["username"], passwd=self.hostConfig["password"]).execute\
|
||||||
|
("systemctl start cloudstack-agent || service cloudstack-agent start")
|
||||||
|
|
||||||
|
def verify_uservm_host_control_state(self, vm_id, state):
|
||||||
|
list_vms = VirtualMachine.list(
|
||||||
|
self.apiclient,
|
||||||
|
id=vm_id
|
||||||
|
)
|
||||||
|
vm = list_vms[0]
|
||||||
|
self.assertEqual(vm.hostcontrolstate,
|
||||||
|
state,
|
||||||
|
msg="host control state should be %s, but it is %s" % (state, vm.hostcontrolstate))
|
||||||
|
|
||||||
|
def verify_ssvm_host_control_state(self, vm_id, state):
|
||||||
|
list_ssvm_response = list_ssvms(
|
||||||
|
self.apiclient,
|
||||||
|
id=vm_id
|
||||||
|
)
|
||||||
|
vm = list_ssvm_response[0]
|
||||||
|
self.assertEqual(vm.hostcontrolstate,
|
||||||
|
state,
|
||||||
|
msg="host control state should be %s, but it is %s" % (state, vm.hostcontrolstate))
|
||||||
|
|
||||||
|
def verify_router_host_control_state(self, vm_id, state):
|
||||||
|
list_router_response = list_routers(
|
||||||
|
self.apiclient,
|
||||||
|
id=vm_id
|
||||||
|
)
|
||||||
|
vm = list_router_response[0]
|
||||||
|
self.assertEqual(vm.hostcontrolstate,
|
||||||
|
state,
|
||||||
|
msg="host control state should be %s, but it is %s" % (state, vm.hostcontrolstate))
|
||||||
|
|
||||||
|
@attr(tags=["basic", "advanced"], required_hardware="false")
|
||||||
|
def test_uservm_host_control_state(self):
|
||||||
|
""" Verify host control state for user vm """
|
||||||
|
# 1. verify hostcontrolstate = Enabled
|
||||||
|
# 2. Disable the host, verify hostcontrolstate = Disabled
|
||||||
|
|
||||||
|
list_vms = VirtualMachine.list(
|
||||||
|
self.apiclient,
|
||||||
|
id=self.vm.id
|
||||||
|
)
|
||||||
|
host_id = list_vms[0].hostid
|
||||||
|
|
||||||
|
self.verify_uservm_host_control_state(self.vm.id, "Enabled")
|
||||||
|
|
||||||
|
self.disable_host(host_id)
|
||||||
|
self.verify_uservm_host_control_state(self.vm.id, "Disabled")
|
||||||
|
|
||||||
|
if self.hypervisor == "kvm":
|
||||||
|
host_ipaddress = self.get_host_ipaddress(host_id)
|
||||||
|
|
||||||
|
self.stop_agent(host_ipaddress)
|
||||||
|
time.sleep(5) # wait for the host to be Disconnected
|
||||||
|
self.verify_uservm_host_control_state(self.vm.id, "Offline")
|
||||||
|
|
||||||
|
self.enable_host(host_id)
|
||||||
|
self.verify_uservm_host_control_state(self.vm.id, "Offline")
|
||||||
|
|
||||||
|
self.start_agent(host_ipaddress)
|
||||||
|
time.sleep(10) # wait for the host to be Up
|
||||||
|
self.verify_uservm_host_control_state(self.vm.id, "Enabled")
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.enable_host(host_id)
|
||||||
|
self.verify_uservm_host_control_state(self.vm.id, "Enabled")
|
||||||
|
|
||||||
|
@attr(tags=["basic", "advanced"], required_hardware="false")
|
||||||
|
def test_ssvm_host_control_state(self):
|
||||||
|
""" Verify host control state for systemvm """
|
||||||
|
# 1. verify hostcontrolstate = Enabled
|
||||||
|
# 2. Disable the host, verify hostcontrolstate = Disabled
|
||||||
|
|
||||||
|
list_ssvm_response = list_ssvms(
|
||||||
|
self.apiclient,
|
||||||
|
systemvmtype='secondarystoragevm',
|
||||||
|
state='Running',
|
||||||
|
zoneid=self.zone.id
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
isinstance(list_ssvm_response, list),
|
||||||
|
True,
|
||||||
|
"Check list response returns a valid list"
|
||||||
|
)
|
||||||
|
ssvm = list_ssvm_response[0]
|
||||||
|
host_id = ssvm.hostid
|
||||||
|
|
||||||
|
self.verify_ssvm_host_control_state(ssvm.id, "Enabled")
|
||||||
|
|
||||||
|
self.disable_host(host_id)
|
||||||
|
self.verify_ssvm_host_control_state(ssvm.id, "Disabled")
|
||||||
|
|
||||||
|
self.enable_host(host_id)
|
||||||
|
self.verify_ssvm_host_control_state(ssvm.id, "Enabled")
|
||||||
|
|
||||||
|
@attr(tags=["basic", "advanced"], required_hardware="false")
|
||||||
|
def test_router_host_control_state(self):
|
||||||
|
""" Verify host control state for router """
|
||||||
|
# 1. verify hostcontrolstate = Enabled
|
||||||
|
# 2. Disable the host, verify hostcontrolstate = Disabled
|
||||||
|
|
||||||
|
list_router_response = list_routers(
|
||||||
|
self.apiclient,
|
||||||
|
state='Running',
|
||||||
|
listall=True,
|
||||||
|
zoneid=self.zone.id
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
isinstance(list_router_response, list),
|
||||||
|
True,
|
||||||
|
"Check list response returns a valid list"
|
||||||
|
)
|
||||||
|
router = list_router_response[0]
|
||||||
|
host_id = router.hostid
|
||||||
|
|
||||||
|
self.verify_router_host_control_state(router.id, "Enabled")
|
||||||
|
|
||||||
|
self.disable_host(host_id)
|
||||||
|
self.verify_router_host_control_state(router.id, "Disabled")
|
||||||
|
|
||||||
|
self.enable_host(host_id)
|
||||||
|
self.verify_router_host_control_state(router.id, "Enabled")
|
||||||
@ -821,6 +821,7 @@
|
|||||||
"label.host.alerts": "Hosts in alert state",
|
"label.host.alerts": "Hosts in alert state",
|
||||||
"label.host.name": "Host name",
|
"label.host.name": "Host name",
|
||||||
"label.host.tag": "Host tag",
|
"label.host.tag": "Host tag",
|
||||||
|
"label.hostcontrolstate": "Control Plane Status",
|
||||||
"label.hostid": "Host",
|
"label.hostid": "Host",
|
||||||
"label.hostname": "Host",
|
"label.hostname": "Host",
|
||||||
"label.hostnamelabel": "Host name",
|
"label.hostnamelabel": "Host name",
|
||||||
@ -2424,6 +2425,8 @@
|
|||||||
"message.chart.statistic.info": "The shown charts are self-adjustable, that means, if the value gets close to the limit or overpass it, it will grow to adjust the shown value",
|
"message.chart.statistic.info": "The shown charts are self-adjustable, that means, if the value gets close to the limit or overpass it, it will grow to adjust the shown value",
|
||||||
"message.guest.traffic.in.advanced.zone": "Guest network traffic is communication between end-user virtual machines. Specify a range of VLAN IDs or VXLAN network identifiers (VNIs) to carry guest traffic for each physical network.",
|
"message.guest.traffic.in.advanced.zone": "Guest network traffic is communication between end-user virtual machines. Specify a range of VLAN IDs or VXLAN network identifiers (VNIs) to carry guest traffic for each physical network.",
|
||||||
"message.guest.traffic.in.basic.zone": "Guest network traffic is communication between end-user virtual machines. Specify a range of IP addresses that CloudStack can assign to guest VMs. Make sure this range does not overlap the reserved system IP range.",
|
"message.guest.traffic.in.basic.zone": "Guest network traffic is communication between end-user virtual machines. Specify a range of IP addresses that CloudStack can assign to guest VMs. Make sure this range does not overlap the reserved system IP range.",
|
||||||
|
"message.host.controlstate": "The Control Plane Status of this instance is ",
|
||||||
|
"message.host.controlstate.retry": "Some actions on this instance will fail, if so please wait a while and retry.",
|
||||||
"message.host.dedicated": "Host Dedicated",
|
"message.host.dedicated": "Host Dedicated",
|
||||||
"message.host.dedication.released": "Host dedication released.",
|
"message.host.dedication.released": "Host dedication released.",
|
||||||
"message.info.cloudian.console": "Cloudian Management Console should open in another window.",
|
"message.info.cloudian.console": "Cloudian Management Console should open in another window.",
|
||||||
|
|||||||
@ -16,6 +16,13 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<a-alert type="error" v-if="['vm', 'systemvm', 'router', 'ilbvm'].includes($route.meta.name) && 'hostcontrolstate' in resource && resource.hostcontrolstate !== 'Enabled'">
|
||||||
|
<template #message>
|
||||||
|
<div class="title">
|
||||||
|
{{ $t('message.host.controlstate') }} {{ resource.hostcontrolstate }}. {{ $t('message.host.controlstate.retry') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-alert>
|
||||||
<a-alert v-if="ip6routes" type="info" :showIcon="true" :message="$t('label.add.upstream.ipv6.routes')">
|
<a-alert v-if="ip6routes" type="info" :showIcon="true" :message="$t('label.add.upstream.ipv6.routes')">
|
||||||
<template #description>
|
<template #description>
|
||||||
<p v-html="ip6routes" />
|
<p v-html="ip6routes" />
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
<a
|
<a
|
||||||
v-if="['vm', 'systemvm', 'router', 'ilbvm'].includes($route.meta.name) && 'listVirtualMachines' in $store.getters.apis && 'createConsoleEndpoint' in $store.getters.apis"
|
v-if="['vm', 'systemvm', 'router', 'ilbvm'].includes($route.meta.name) && 'listVirtualMachines' in $store.getters.apis && 'createConsoleEndpoint' in $store.getters.apis"
|
||||||
@click="consoleUrl">
|
@click="consoleUrl">
|
||||||
<a-button style="margin-left: 5px" shape="circle" type="dashed" :size="size" :disabled="['Stopped', 'Error', 'Destroyed'].includes(resource.state)" >
|
<a-button style="margin-left: 5px" shape="circle" type="dashed" :size="size" :disabled="['Stopped', 'Error', 'Destroyed'].includes(resource.state) || resource.hostcontrolstate === 'Offline'" >
|
||||||
<code-outlined />
|
<code-outlined />
|
||||||
</a-button>
|
</a-button>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@ -79,7 +79,7 @@ export default {
|
|||||||
details: () => {
|
details: () => {
|
||||||
var fields = ['displayname', 'name', 'id', 'state', 'ipaddress', 'ip6address', 'templatename', 'ostypename',
|
var fields = ['displayname', 'name', 'id', 'state', 'ipaddress', 'ip6address', 'templatename', 'ostypename',
|
||||||
'serviceofferingname', 'isdynamicallyscalable', 'haenable', 'hypervisor', 'boottype', 'bootmode', 'account',
|
'serviceofferingname', 'isdynamicallyscalable', 'haenable', 'hypervisor', 'boottype', 'bootmode', 'account',
|
||||||
'domain', 'zonename', 'userdataid', 'userdataname', 'userdataparams', 'userdatadetails', 'userdatapolicy']
|
'domain', 'zonename', 'userdataid', 'userdataname', 'userdataparams', 'userdatadetails', 'userdatapolicy', 'hostcontrolstate']
|
||||||
const listZoneHaveSGEnabled = store.getters.zones.filter(zone => zone.securitygroupsenabled === true)
|
const listZoneHaveSGEnabled = store.getters.zones.filter(zone => zone.securitygroupsenabled === true)
|
||||||
if (!listZoneHaveSGEnabled || listZoneHaveSGEnabled.length === 0) {
|
if (!listZoneHaveSGEnabled || listZoneHaveSGEnabled.length === 0) {
|
||||||
return fields
|
return fields
|
||||||
@ -142,6 +142,7 @@ export default {
|
|||||||
docHelp: 'adminguide/virtual_machines.html#stopping-and-starting-vms',
|
docHelp: 'adminguide/virtual_machines.html#stopping-and-starting-vms',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
show: (record) => { return ['Running'].includes(record.state) },
|
show: (record) => { return ['Running'].includes(record.state) },
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' },
|
||||||
args: (record, store) => {
|
args: (record, store) => {
|
||||||
var fields = []
|
var fields = []
|
||||||
fields.push('forced')
|
fields.push('forced')
|
||||||
@ -169,6 +170,7 @@ export default {
|
|||||||
value: (record) => { return record.id }
|
value: (record) => { return record.id }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' },
|
||||||
successMethod: (obj, result) => {
|
successMethod: (obj, result) => {
|
||||||
const vm = result.jobresult.virtualmachine || {}
|
const vm = result.jobresult.virtualmachine || {}
|
||||||
if (result.jobstatus === 1 && vm.password) {
|
if (result.jobstatus === 1 && vm.password) {
|
||||||
@ -193,6 +195,7 @@ export default {
|
|||||||
(['Stopped'].includes(record.state) && ((record.hypervisor !== 'KVM' && record.hypervisor !== 'LXC') ||
|
(['Stopped'].includes(record.state) && ((record.hypervisor !== 'KVM' && record.hypervisor !== 'LXC') ||
|
||||||
(record.hypervisor === 'KVM' && record.pooltype === 'PowerFlex'))))
|
(record.hypervisor === 'KVM' && record.pooltype === 'PowerFlex'))))
|
||||||
},
|
},
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' && record.hypervisor === 'KVM' },
|
||||||
mapping: {
|
mapping: {
|
||||||
virtualmachineid: {
|
virtualmachineid: {
|
||||||
value: (record, params) => { return record.id }
|
value: (record, params) => { return record.id }
|
||||||
@ -210,6 +213,7 @@ export default {
|
|||||||
return ((['Running'].includes(record.state) && record.hypervisor !== 'LXC') ||
|
return ((['Running'].includes(record.state) && record.hypervisor !== 'LXC') ||
|
||||||
(['Stopped'].includes(record.state) && !['KVM', 'LXC'].includes(record.hypervisor)))
|
(['Stopped'].includes(record.state) && !['KVM', 'LXC'].includes(record.hypervisor)))
|
||||||
},
|
},
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' && record.hypervisor === 'KVM' },
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/CreateSnapshotWizard.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/CreateSnapshotWizard.vue')))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -283,6 +287,7 @@ export default {
|
|||||||
dataView: true,
|
dataView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
show: (record) => { return ['Running', 'Stopped'].includes(record.state) && !record.isoid },
|
show: (record) => { return ['Running', 'Stopped'].includes(record.state) && !record.isoid },
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' || record.hostcontrolstate === 'Maintenance' },
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/AttachIso.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/AttachIso.vue')))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -299,6 +304,7 @@ export default {
|
|||||||
return args
|
return args
|
||||||
},
|
},
|
||||||
show: (record) => { return ['Running', 'Stopped'].includes(record.state) && 'isoid' in record && record.isoid },
|
show: (record) => { return ['Running', 'Stopped'].includes(record.state) && 'isoid' in record && record.isoid },
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' || record.hostcontrolstate === 'Maintenance' },
|
||||||
mapping: {
|
mapping: {
|
||||||
virtualmachineid: {
|
virtualmachineid: {
|
||||||
value: (record, params) => { return record.id }
|
value: (record, params) => { return record.id }
|
||||||
@ -334,6 +340,7 @@ export default {
|
|||||||
docHelp: 'adminguide/virtual_machines.html#moving-vms-between-hosts-manual-live-migration',
|
docHelp: 'adminguide/virtual_machines.html#moving-vms-between-hosts-manual-live-migration',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
show: (record, store) => { return ['Running'].includes(record.state) && ['Admin'].includes(store.userInfo.roletype) },
|
show: (record, store) => { return ['Running'].includes(record.state) && ['Admin'].includes(store.userInfo.roletype) },
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' },
|
||||||
popup: true,
|
popup: true,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateWizard.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateWizard.vue')))
|
||||||
},
|
},
|
||||||
@ -345,6 +352,7 @@ export default {
|
|||||||
docHelp: 'adminguide/virtual_machines.html#moving-vms-between-hosts-manual-live-migration',
|
docHelp: 'adminguide/virtual_machines.html#moving-vms-between-hosts-manual-live-migration',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
show: (record, store) => { return ['Stopped'].includes(record.state) && ['Admin'].includes(store.userInfo.roletype) },
|
show: (record, store) => { return ['Stopped'].includes(record.state) && ['Admin'].includes(store.userInfo.roletype) },
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' },
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateVMStorage'))),
|
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateVMStorage'))),
|
||||||
popup: true
|
popup: true
|
||||||
},
|
},
|
||||||
|
|||||||
@ -23,7 +23,7 @@ export default {
|
|||||||
permission: ['listInternalLoadBalancerVMs'],
|
permission: ['listInternalLoadBalancerVMs'],
|
||||||
params: { projectid: '-1' },
|
params: { projectid: '-1' },
|
||||||
columns: ['name', 'state', 'publicip', 'guestnetworkname', 'vpcname', 'version', 'softwareversion', 'hostname', 'account', 'zonename', 'requiresupgrade'],
|
columns: ['name', 'state', 'publicip', 'guestnetworkname', 'vpcname', 'version', 'softwareversion', 'hostname', 'account', 'zonename', 'requiresupgrade'],
|
||||||
details: ['name', 'id', 'version', 'softwareversion', 'requiresupgrade', 'guestnetworkname', 'vpcname', 'publicip', 'guestipaddress', 'linklocalip', 'serviceofferingname', 'networkdomain', 'isredundantrouter', 'redundantstate', 'hostname', 'account', 'zonename', 'created'],
|
details: ['name', 'id', 'version', 'softwareversion', 'requiresupgrade', 'guestnetworkname', 'vpcname', 'publicip', 'guestipaddress', 'linklocalip', 'serviceofferingname', 'networkdomain', 'isredundantrouter', 'redundantstate', 'hostname', 'account', 'zonename', 'created', 'hostcontrolstate'],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
api: 'startInternalLoadBalancerVM',
|
api: 'startInternalLoadBalancerVM',
|
||||||
@ -53,6 +53,7 @@ export default {
|
|||||||
label: 'label.action.migrate.router',
|
label: 'label.action.migrate.router',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
show: (record, store) => { return record.state === 'Running' && ['Admin'].includes(store.userInfo.roletype) },
|
show: (record, store) => { return record.state === 'Running' && ['Admin'].includes(store.userInfo.roletype) },
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' },
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateWizard'))),
|
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateWizard'))),
|
||||||
popup: true
|
popup: true
|
||||||
},
|
},
|
||||||
@ -62,6 +63,7 @@ export default {
|
|||||||
label: 'label.action.migrate.systemvm.to.ps',
|
label: 'label.action.migrate.systemvm.to.ps',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
show: (record, store) => { return ['Stopped'].includes(record.state) && ['VMware'].includes(record.hypervisor) },
|
show: (record, store) => { return ['Stopped'].includes(record.state) && ['VMware'].includes(record.hypervisor) },
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' },
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateVMStorage'))),
|
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateVMStorage'))),
|
||||||
popup: true
|
popup: true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@ export default {
|
|||||||
return columns
|
return columns
|
||||||
},
|
},
|
||||||
searchFilters: ['name', 'zoneid', 'podid', 'clusterid'],
|
searchFilters: ['name', 'zoneid', 'podid', 'clusterid'],
|
||||||
details: ['name', 'id', 'version', 'softwareversion', 'requiresupgrade', 'guestnetworkname', 'vpcname', 'publicip', 'guestipaddress', 'linklocalip', 'serviceofferingname', 'networkdomain', 'isredundantrouter', 'redundantstate', 'hostname', 'account', 'zonename', 'created'],
|
details: ['name', 'id', 'version', 'softwareversion', 'requiresupgrade', 'guestnetworkname', 'vpcname', 'publicip', 'guestipaddress', 'linklocalip', 'serviceofferingname', 'networkdomain', 'isredundantrouter', 'redundantstate', 'hostname', 'account', 'zonename', 'created', 'hostcontrolstate'],
|
||||||
resourceType: 'VirtualRouter',
|
resourceType: 'VirtualRouter',
|
||||||
tabs: [{
|
tabs: [{
|
||||||
name: 'details',
|
name: 'details',
|
||||||
@ -188,6 +188,7 @@ export default {
|
|||||||
message: 'message.migrate.router.confirm',
|
message: 'message.migrate.router.confirm',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
show: (record, store) => { return record.state === 'Running' && ['Admin'].includes(store.userInfo.roletype) },
|
show: (record, store) => { return record.state === 'Running' && ['Admin'].includes(store.userInfo.roletype) },
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' },
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateWizard'))),
|
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateWizard'))),
|
||||||
popup: true
|
popup: true
|
||||||
},
|
},
|
||||||
@ -197,6 +198,7 @@ export default {
|
|||||||
label: 'label.action.migrate.systemvm.to.ps',
|
label: 'label.action.migrate.systemvm.to.ps',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
show: (record, store) => { return ['Stopped'].includes(record.state) && ['VMware', 'KVM'].includes(record.hypervisor) },
|
show: (record, store) => { return ['Stopped'].includes(record.state) && ['VMware', 'KVM'].includes(record.hypervisor) },
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' },
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateVMStorage'))),
|
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateVMStorage'))),
|
||||||
popup: true
|
popup: true
|
||||||
},
|
},
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export default {
|
|||||||
docHelp: 'adminguide/systemvm.html',
|
docHelp: 'adminguide/systemvm.html',
|
||||||
permission: ['listSystemVms'],
|
permission: ['listSystemVms'],
|
||||||
columns: ['name', 'state', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'hostname', 'zonename'],
|
columns: ['name', 'state', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'hostname', 'zonename'],
|
||||||
details: ['name', 'id', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'gateway', 'hostname', 'zonename', 'created', 'activeviewersessions', 'isdynamicallyscalable'],
|
details: ['name', 'id', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'gateway', 'hostname', 'zonename', 'created', 'activeviewersessions', 'isdynamicallyscalable', 'hostcontrolstate'],
|
||||||
resourceType: 'SystemVm',
|
resourceType: 'SystemVm',
|
||||||
tabs: [
|
tabs: [
|
||||||
{
|
{
|
||||||
@ -105,6 +105,7 @@ export default {
|
|||||||
message: 'message.migrate.systemvm.confirm',
|
message: 'message.migrate.systemvm.confirm',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
show: (record, store) => { return record.state === 'Running' && ['Admin'].includes(store.userInfo.roletype) },
|
show: (record, store) => { return record.state === 'Running' && ['Admin'].includes(store.userInfo.roletype) },
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' },
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateWizard'))),
|
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateWizard'))),
|
||||||
popup: true
|
popup: true
|
||||||
},
|
},
|
||||||
@ -114,6 +115,7 @@ export default {
|
|||||||
label: 'label.action.migrate.systemvm.to.ps',
|
label: 'label.action.migrate.systemvm.to.ps',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
show: (record, store) => { return ['Stopped'].includes(record.state) && ['VMware', 'KVM'].includes(record.hypervisor) },
|
show: (record, store) => { return ['Stopped'].includes(record.state) && ['VMware', 'KVM'].includes(record.hypervisor) },
|
||||||
|
disabled: (record) => { return record.hostcontrolstate === 'Offline' },
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateVMStorage'))),
|
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/MigrateVMStorage'))),
|
||||||
popup: true
|
popup: true
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user