mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
UI improvements (#9773)
* Show Usage Server configuration in a separate pane * UI: Option to attach volume to an instance during create volume * Show service ip in management server details tab * change Schedule Snapshots to Recurring Snapshots * Change the hypervisor order so that kvm, vmware, xenserver show up first * Remove extra space in hypervisor names in config.java * Fix `updateTemplatePermission` when the UI is set to a language other than English (#9766) * Fix updateTemplatePermission UI in non-english language * Improve fix --------- Co-authored-by: Lucas Martins <lucas.martins@scclouds.com.br> * Autofill vcenter details in add cluster form * UI: condition to display create vm-vol-snapshots to same as create vol-snapshots * Fix alignment on wrapping in global settings tabs * rename Autofill vCenter credentials to Autofill vCenter credentials from Zone * Rename Service Ip to Ip Address in management server response * Change description of kvm.snapshot.enabled to say that it applies to volume snapshots * Return error when kvm vm snapshot is taken withoutsnapshot memory * Minor naming changes and grammar * Fix tooltip for attach volume to instance button * Show Usage Server configuration in a separate pane * UI: Option to attach volume to an instance during create volume * Show service ip in management server details tab * change Schedule Snapshots to Recurring Snapshots * Change the hypervisor order so that kvm, vmware, xenserver show up first * Remove extra space in hypervisor names in config.java * Autofill vcenter details in add cluster form * UI: condition to display create vm-vol-snapshots to same as create vol-snapshots * Fix alignment on wrapping in global settings tabs * rename Autofill vCenter credentials to Autofill vCenter credentials from Zone * Rename Service Ip to Ip Address in management server response * Change description of kvm.snapshot.enabled to say that it applies to volume snapshots * Return error when kvm vm snapshot is taken withoutsnapshot memory * Minor naming changes and grammar * Fix tooltip for attach volume to instance button * Show Usage Server configuration in a separate pane * UI: Option to attach volume to an instance during create volume * Show service ip in management server details tab * change Schedule Snapshots to Recurring Snapshots * Change the hypervisor order so that kvm, vmware, xenserver show up first * Remove extra space in hypervisor names in config.java * Autofill vcenter details in add cluster form * UI: condition to display create vm-vol-snapshots to same as create vol-snapshots * Fix alignment on wrapping in global settings tabs * rename Autofill vCenter credentials to Autofill vCenter credentials from Zone * Rename Service Ip to Ip Address in management server response * Change description of kvm.snapshot.enabled to say that it applies to volume snapshots * Return error when kvm vm snapshot is taken withoutsnapshot memory * Minor naming changes and grammar * Fix tooltip for attach volume to instance button * UI: Option to attach volume to an instance during create volume * UI: condition to display create vm-vol-snapshots to same as create vol-snapshots * moved db changes from 41900to42000 to 42000to42010 * Update group_id in already present usage configuration settings * remove "schedule" from message in create Recurring Snapshots form * Update server/src/main/java/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java --------- Co-authored-by: Daan Hoogland <daan@onecht.net> Co-authored-by: Lucas Martins <56271185+lucas-a-martins@users.noreply.github.com> Co-authored-by: Lucas Martins <lucas.martins@scclouds.com.br> Co-authored-by: Boris Stoyanov - a.k.a Bobby <bss.stoyanov@gmail.com> Co-authored-by: Andrija Panic <45762285+andrijapanicsb@users.noreply.github.com>
This commit is contained in:
parent
986ec81b66
commit
c5afee2101
@ -447,7 +447,6 @@ public class ApiConstants {
|
|||||||
public static final String SENT = "sent";
|
public static final String SENT = "sent";
|
||||||
public static final String SENT_BYTES = "sentbytes";
|
public static final String SENT_BYTES = "sentbytes";
|
||||||
public static final String SERIAL = "serial";
|
public static final String SERIAL = "serial";
|
||||||
public static final String SERVICE_IP = "serviceip";
|
|
||||||
public static final String SERVICE_OFFERING_ID = "serviceofferingid";
|
public static final String SERVICE_OFFERING_ID = "serviceofferingid";
|
||||||
public static final String SESSIONKEY = "sessionkey";
|
public static final String SESSIONKEY = "sessionkey";
|
||||||
public static final String SHOW_CAPACITIES = "showcapacities";
|
public static final String SHOW_CAPACITIES = "showcapacities";
|
||||||
|
|||||||
@ -74,9 +74,9 @@ public class ManagementServerResponse extends BaseResponse {
|
|||||||
@Param(description = "the running OS kernel version for this Management Server")
|
@Param(description = "the running OS kernel version for this Management Server")
|
||||||
private String kernelVersion;
|
private String kernelVersion;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.SERVICE_IP)
|
@SerializedName(ApiConstants.IP_ADDRESS)
|
||||||
@Param(description = "the IP Address for this Management Server")
|
@Param(description = "the IP Address for this Management Server")
|
||||||
private String serviceIp;
|
private String ipAddress;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.PEERS)
|
@SerializedName(ApiConstants.PEERS)
|
||||||
@Param(description = "the Management Server Peers")
|
@Param(description = "the Management Server Peers")
|
||||||
@ -122,8 +122,8 @@ public class ManagementServerResponse extends BaseResponse {
|
|||||||
return lastBoot;
|
return lastBoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServiceIp() {
|
public String getIpAddress() {
|
||||||
return serviceIp;
|
return ipAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(String id) {
|
public void setId(String id) {
|
||||||
@ -170,8 +170,8 @@ public class ManagementServerResponse extends BaseResponse {
|
|||||||
this.kernelVersion = kernelVersion;
|
this.kernelVersion = kernelVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setServiceIp(String serviceIp) {
|
public void setIpAddress(String ipAddress) {
|
||||||
this.serviceIp = serviceIp;
|
this.ipAddress = ipAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getKernelVersion() {
|
public String getKernelVersion() {
|
||||||
|
|||||||
@ -24,6 +24,14 @@ CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.user', 'api_key_access', 'boolean DE
|
|||||||
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.account', 'api_key_access', 'boolean DEFAULT NULL COMMENT "is api key access allowed for the account" ');
|
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.account', 'api_key_access', 'boolean DEFAULT NULL COMMENT "is api key access allowed for the account" ');
|
||||||
CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.account', 'api_key_access', 'boolean DEFAULT NULL COMMENT "is api key access allowed for the account" ');
|
CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.account', 'api_key_access', 'boolean DEFAULT NULL COMMENT "is api key access allowed for the account" ');
|
||||||
|
|
||||||
|
-- Create a new group for Usage Server related configurations
|
||||||
|
INSERT INTO `cloud`.`configuration_group` (`name`, `description`, `precedence`) VALUES ('Usage Server', 'Usage Server related configuration', 9);
|
||||||
|
UPDATE `cloud`.`configuration_subgroup` set `group_id` = (SELECT `id` FROM `cloud`.`configuration_group` WHERE `name` = 'Usage Server'), `precedence` = 1 WHERE `name`='Usage';
|
||||||
|
UPDATE `cloud`.`configuration` SET `group_id` = (SELECT `id` FROM `cloud`.`configuration_group` WHERE `name` = 'Usage Server') where `subgroup_id` = (SELECT `id` FROM `cloud`.`configuration_subgroup` WHERE `name` = 'Usage');
|
||||||
|
|
||||||
|
-- Update the description to indicate this setting applies only to volume snapshots on running instances
|
||||||
|
UPDATE `cloud`.`configuration` SET `description`='whether volume snapshot is enabled on running instances on KVM hosts' WHERE `name`='kvm.snapshot.enabled';
|
||||||
|
|
||||||
-- Modify index for mshost_peer
|
-- Modify index for mshost_peer
|
||||||
DELETE FROM `cloud`.`mshost_peer`;
|
DELETE FROM `cloud`.`mshost_peer`;
|
||||||
CALL `cloud`.`IDEMPOTENT_DROP_FOREIGN_KEY`('cloud.mshost_peer','fk_mshost_peer__owner_mshost');
|
CALL `cloud`.`IDEMPOTENT_DROP_FOREIGN_KEY`('cloud.mshost_peer','fk_mshost_peer__owner_mshost');
|
||||||
|
|||||||
@ -5413,13 +5413,13 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
mgmtResponse.setLastServerStart(mgmt.getLastJvmStart());
|
mgmtResponse.setLastServerStart(mgmt.getLastJvmStart());
|
||||||
mgmtResponse.setLastServerStop(mgmt.getLastJvmStop());
|
mgmtResponse.setLastServerStop(mgmt.getLastJvmStop());
|
||||||
mgmtResponse.setLastBoot(mgmt.getLastSystemBoot());
|
mgmtResponse.setLastBoot(mgmt.getLastSystemBoot());
|
||||||
mgmtResponse.setServiceIp(mgmt.getServiceIP());
|
|
||||||
if (listPeers) {
|
if (listPeers) {
|
||||||
List<ManagementServerHostPeerJoinVO> peers = mshostPeerJoinDao.listByOwnerMshostId(mgmt.getId());
|
List<ManagementServerHostPeerJoinVO> peers = mshostPeerJoinDao.listByOwnerMshostId(mgmt.getId());
|
||||||
for (ManagementServerHostPeerJoinVO peer: peers) {
|
for (ManagementServerHostPeerJoinVO peer: peers) {
|
||||||
mgmtResponse.addPeer(createPeerManagementServerNodeResponse(peer));
|
mgmtResponse.addPeer(createPeerManagementServerNodeResponse(peer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mgmtResponse.setIpAddress(mgmt.getServiceIP());
|
||||||
mgmtResponse.setObjectName("managementserver");
|
mgmtResponse.setObjectName("managementserver");
|
||||||
return mgmtResponse;
|
return mgmtResponse;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -506,7 +506,7 @@ public enum Config {
|
|||||||
"The time interval in seconds when the management server polls for snapshots to be scheduled.",
|
"The time interval in seconds when the management server polls for snapshots to be scheduled.",
|
||||||
null),
|
null),
|
||||||
SnapshotDeltaMax("Snapshots", SnapshotManager.class, Integer.class, "snapshot.delta.max", "16", "max delta snapshots between two full snapshots.", null),
|
SnapshotDeltaMax("Snapshots", SnapshotManager.class, Integer.class, "snapshot.delta.max", "16", "max delta snapshots between two full snapshots.", null),
|
||||||
KVMSnapshotEnabled("Hidden", SnapshotManager.class, Boolean.class, "kvm.snapshot.enabled", "false", "whether snapshot is enabled for KVM hosts", null),
|
KVMSnapshotEnabled("Hidden", SnapshotManager.class, Boolean.class, "kvm.snapshot.enabled", "false", "Whether volume snapshot is enabled on running instances on a KVM host", null),
|
||||||
|
|
||||||
// Advanced
|
// Advanced
|
||||||
EventPurgeInterval(
|
EventPurgeInterval(
|
||||||
@ -665,8 +665,8 @@ public enum Config {
|
|||||||
ManagementServer.class,
|
ManagementServer.class,
|
||||||
String.class,
|
String.class,
|
||||||
"hypervisor.list",
|
"hypervisor.list",
|
||||||
HypervisorType.Hyperv + "," + HypervisorType.KVM + "," + HypervisorType.XenServer + "," + HypervisorType.VMware + "," + HypervisorType.BareMetal + "," +
|
HypervisorType.KVM + "," + HypervisorType.VMware + "," + HypervisorType.XenServer + "," + HypervisorType.Hyperv + "," +
|
||||||
HypervisorType.Ovm + "," + HypervisorType.LXC + "," + HypervisorType.Ovm3,
|
HypervisorType.BareMetal + "," + HypervisorType.Ovm + "," + HypervisorType.LXC + "," + HypervisorType.Ovm3,
|
||||||
"The list of hypervisors that this deployment will use.",
|
"The list of hypervisors that this deployment will use.",
|
||||||
"hypervisorList",
|
"hypervisorList",
|
||||||
ConfigKey.Kind.CSV,
|
ConfigKey.Kind.CSV,
|
||||||
|
|||||||
@ -343,7 +343,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
|||||||
private void validatePrerequisiteVpnGateway(Site2SiteVpnGateway vpnGateway) {
|
private void validatePrerequisiteVpnGateway(Site2SiteVpnGateway vpnGateway) {
|
||||||
// check if gateway has been defined on the VPC
|
// check if gateway has been defined on the VPC
|
||||||
if (_vpnGatewayDao.findByVpcId(vpnGateway.getVpcId()) == null) {
|
if (_vpnGatewayDao.findByVpcId(vpnGateway.getVpcId()) == null) {
|
||||||
throw new InvalidParameterValueException("we can not create a VPN connection for a VPC that does not have a VPN gateway defined");
|
throw new InvalidParameterValueException("We can not create a VPN connection for a VPC that does not have a VPN gateway defined");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,7 +590,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
|||||||
private void stopVpnConnection(Long id) throws ResourceUnavailableException {
|
private void stopVpnConnection(Long id) throws ResourceUnavailableException {
|
||||||
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id);
|
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id);
|
||||||
if (conn == null) {
|
if (conn == null) {
|
||||||
throw new CloudRuntimeException("Unable to acquire lock for stopping of VPN connection with ID " + id);
|
throw new CloudRuntimeException("Unable to acquire lock for stopping VPN connection with ID " + id);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (conn.getState() == State.Pending) {
|
if (conn.getState() == State.Pending) {
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import java.util.Map;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import com.cloud.storage.snapshot.SnapshotManager;
|
||||||
import org.apache.cloudstack.annotation.AnnotationService;
|
import org.apache.cloudstack.annotation.AnnotationService;
|
||||||
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
@ -377,9 +378,14 @@ public class VMSnapshotManagerImpl extends MutualExclusiveIdsManagerBase impleme
|
|||||||
//StorageVMSnapshotStrategy - allows volume snapshots without memory; VM has to be in Running state; No limitation of the image format if the storage plugin supports volume snapshots; "kvm.vmstoragesnapshot.enabled" has to be enabled
|
//StorageVMSnapshotStrategy - allows volume snapshots without memory; VM has to be in Running state; No limitation of the image format if the storage plugin supports volume snapshots; "kvm.vmstoragesnapshot.enabled" has to be enabled
|
||||||
//Other Storage volume plugins could integrate this with their own functionality for group snapshots
|
//Other Storage volume plugins could integrate this with their own functionality for group snapshots
|
||||||
VMSnapshotStrategy snapshotStrategy = storageStrategyFactory.getVmSnapshotStrategy(userVmVo.getId(), rootVolumePool.getId(), snapshotMemory);
|
VMSnapshotStrategy snapshotStrategy = storageStrategyFactory.getVmSnapshotStrategy(userVmVo.getId(), rootVolumePool.getId(), snapshotMemory);
|
||||||
|
|
||||||
if (snapshotStrategy == null) {
|
if (snapshotStrategy == null) {
|
||||||
String message = "KVM does not support the type of snapshot requested";
|
String message;
|
||||||
|
if (!SnapshotManager.VmStorageSnapshotKvm.value() && !snapshotMemory) {
|
||||||
|
message = "Creating a snapshot of a running KVM instance without memory is not supported";
|
||||||
|
} else {
|
||||||
|
message = "KVM does not support the type of snapshot requested";
|
||||||
|
}
|
||||||
|
|
||||||
logger.debug(message);
|
logger.debug(message);
|
||||||
throw new CloudRuntimeException(message);
|
throw new CloudRuntimeException(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1265,7 +1265,6 @@
|
|||||||
"label.save.new.rule": "Neue Regel Speichern",
|
"label.save.new.rule": "Neue Regel Speichern",
|
||||||
"label.schedule": "Zeitplan",
|
"label.schedule": "Zeitplan",
|
||||||
"label.scheduled.backups": "geplante Backups",
|
"label.scheduled.backups": "geplante Backups",
|
||||||
"label.scheduled.snapshots": "geplante Schnappschüsse",
|
|
||||||
"label.scope": "Geltungsbereich",
|
"label.scope": "Geltungsbereich",
|
||||||
"label.search": "Suche",
|
"label.search": "Suche",
|
||||||
"label.secondary.isolated.vlan.type.isolated": "Isoliert",
|
"label.secondary.isolated.vlan.type.isolated": "Isoliert",
|
||||||
|
|||||||
@ -1517,7 +1517,6 @@
|
|||||||
"label.scale.vm": "Κλίμακα εικονικής μηχανής",
|
"label.scale.vm": "Κλίμακα εικονικής μηχανής",
|
||||||
"label.schedule": "Πρόγραμμα",
|
"label.schedule": "Πρόγραμμα",
|
||||||
"label.scheduled.backups": "Προγραμματισμένα αντίγραφα ασφαλείας",
|
"label.scheduled.backups": "Προγραμματισμένα αντίγραφα ασφαλείας",
|
||||||
"label.scheduled.snapshots": "Προγραμματισμένα στιγμιότυπα",
|
|
||||||
"label.scope": "Πεδίο εφαρμογής",
|
"label.scope": "Πεδίο εφαρμογής",
|
||||||
"label.search": "Αναζήτηση",
|
"label.search": "Αναζήτηση",
|
||||||
"label.secondary.isolated.vlan.type.isolated": "Απομονωμένες",
|
"label.secondary.isolated.vlan.type.isolated": "Απομονωμένες",
|
||||||
|
|||||||
@ -54,6 +54,7 @@
|
|||||||
"label.action": "Action",
|
"label.action": "Action",
|
||||||
"label.action.attach.disk": "Attach disk",
|
"label.action.attach.disk": "Attach disk",
|
||||||
"label.action.attach.iso": "Attach ISO",
|
"label.action.attach.iso": "Attach ISO",
|
||||||
|
"label.action.attach.to.instance": "Attach to Instance",
|
||||||
"label.action.bulk.delete.egress.firewall.rules": "Bulk delete egress firewall rules",
|
"label.action.bulk.delete.egress.firewall.rules": "Bulk delete egress firewall rules",
|
||||||
"label.action.bulk.delete.firewall.rules": "Bulk delete firewall rules",
|
"label.action.bulk.delete.firewall.rules": "Bulk delete firewall rules",
|
||||||
"label.action.bulk.delete.ip.v6.firewall.rules": "Bulk remove IPv6 firewall rules",
|
"label.action.bulk.delete.ip.v6.firewall.rules": "Bulk remove IPv6 firewall rules",
|
||||||
@ -399,9 +400,11 @@
|
|||||||
"label.associatednetworkid": "Associated Network ID",
|
"label.associatednetworkid": "Associated Network ID",
|
||||||
"label.associatednetworkname": "Network name",
|
"label.associatednetworkname": "Network name",
|
||||||
"label.asyncbackup": "Async backup",
|
"label.asyncbackup": "Async backup",
|
||||||
|
"label.attach.vol.to.instance": "Attach the created Volume to an existing Instance",
|
||||||
"label.attaching": "Attaching",
|
"label.attaching": "Attaching",
|
||||||
"label.authentication.method": "Authentication Method",
|
"label.authentication.method": "Authentication Method",
|
||||||
"label.authentication.sshkey": "System SSH Key",
|
"label.authentication.sshkey": "System SSH Key",
|
||||||
|
"label.use.existing.vcenter.credentials.from.zone": "Use existing vCenter credentials from the Zone",
|
||||||
"label.autoscale": "AutoScale",
|
"label.autoscale": "AutoScale",
|
||||||
"label.autoscalevmgroupname": "AutoScaling Group",
|
"label.autoscalevmgroupname": "AutoScaling Group",
|
||||||
"label.author.email": "Author e-mail",
|
"label.author.email": "Author e-mail",
|
||||||
@ -1073,7 +1076,7 @@
|
|||||||
"label.hastate": "HA state",
|
"label.hastate": "HA state",
|
||||||
"label.headers": "Headers",
|
"label.headers": "Headers",
|
||||||
"label.header.backup.schedule": "You can set up recurring backup schedules by selecting from the available options below and applying your policy preference.",
|
"label.header.backup.schedule": "You can set up recurring backup schedules by selecting from the available options below and applying your policy preference.",
|
||||||
"label.header.volume.snapshot": "You can set up recurring Snapshot schedules by selecting from the available options below and applying your policy preference.",
|
"label.header.volume.snapshot": "You can set up recurring Snapshots by selecting from the available options below and applying your policy preference.",
|
||||||
"label.header.volume.take.snapshot": "Please confirm that you want to take a Snapshot of this volume.",
|
"label.header.volume.take.snapshot": "Please confirm that you want to take a Snapshot of this volume.",
|
||||||
"label.health.check": "Health check",
|
"label.health.check": "Health check",
|
||||||
"label.heapmemoryused": "Heap-memory used",
|
"label.heapmemoryused": "Heap-memory used",
|
||||||
@ -1999,7 +2002,6 @@
|
|||||||
"label.schedule": "Schedule",
|
"label.schedule": "Schedule",
|
||||||
"label.schedule.add": "Add schedule",
|
"label.schedule.add": "Add schedule",
|
||||||
"label.scheduled.backups": "Scheduled backups",
|
"label.scheduled.backups": "Scheduled backups",
|
||||||
"label.scheduled.snapshots": "Scheduled Snapshots",
|
|
||||||
"label.schedules": "Schedules",
|
"label.schedules": "Schedules",
|
||||||
"label.scope": "Scope",
|
"label.scope": "Scope",
|
||||||
"label.scope.tooltip": "Primary Storage Pool Scope",
|
"label.scope.tooltip": "Primary Storage Pool Scope",
|
||||||
|
|||||||
@ -1969,7 +1969,6 @@
|
|||||||
"label.scaleup.policy": "スケールアップポリシー",
|
"label.scaleup.policy": "スケールアップポリシー",
|
||||||
"label.schedule": "スケジュール",
|
"label.schedule": "スケジュール",
|
||||||
"label.scheduled.backups": "スケジュールされたバックアップ",
|
"label.scheduled.backups": "スケジュールされたバックアップ",
|
||||||
"label.scheduled.snapshots": "スケジュールされたスナップショット",
|
|
||||||
"label.scope": "スコープ",
|
"label.scope": "スコープ",
|
||||||
"label.search": "検索",
|
"label.search": "検索",
|
||||||
"label.secondary.isolated.vlan.type.isolated": "隔離",
|
"label.secondary.isolated.vlan.type.isolated": "隔離",
|
||||||
|
|||||||
@ -1322,7 +1322,6 @@
|
|||||||
"label.scale.vm": "VM \ud655\uc7a5",
|
"label.scale.vm": "VM \ud655\uc7a5",
|
||||||
"label.schedule": "\uc2a4\ucf00\uc904",
|
"label.schedule": "\uc2a4\ucf00\uc904",
|
||||||
"label.scheduled.backups": "\uc608\uc57d\ub41c \ubc31\uc5c5",
|
"label.scheduled.backups": "\uc608\uc57d\ub41c \ubc31\uc5c5",
|
||||||
"label.scheduled.snapshots": "\uc608\uc57d\ub41c \uc2a4\ub0c5\uc0f7",
|
|
||||||
"label.scope": "\ubc94\uc704",
|
"label.scope": "\ubc94\uc704",
|
||||||
"label.search": "\uac80\uc0c9",
|
"label.search": "\uac80\uc0c9",
|
||||||
"label.secondary.isolated.vlan.type.isolated": "isolated",
|
"label.secondary.isolated.vlan.type.isolated": "isolated",
|
||||||
|
|||||||
@ -1428,7 +1428,6 @@
|
|||||||
"label.scale.vm": "Escalar VM",
|
"label.scale.vm": "Escalar VM",
|
||||||
"label.schedule": "Programar",
|
"label.schedule": "Programar",
|
||||||
"label.scheduled.backups": "Backups programados",
|
"label.scheduled.backups": "Backups programados",
|
||||||
"label.scheduled.snapshots": "Snapshots programados",
|
|
||||||
"label.scope": "Escopo",
|
"label.scope": "Escopo",
|
||||||
"label.search": "Pesquisar",
|
"label.search": "Pesquisar",
|
||||||
"label.secondary.isolated.vlan.type.isolated": "Isolada",
|
"label.secondary.isolated.vlan.type.isolated": "Isolada",
|
||||||
|
|||||||
@ -2248,7 +2248,6 @@
|
|||||||
|
|
||||||
"label.schedule": "\u65E5\u7A0B",
|
"label.schedule": "\u65E5\u7A0B",
|
||||||
"label.scheduled.backups": "\u5B9A\u65F6\u5907\u4EFD",
|
"label.scheduled.backups": "\u5B9A\u65F6\u5907\u4EFD",
|
||||||
"label.scheduled.snapshots": "\u8BA1\u5212\u5FEB\u7167",
|
|
||||||
"label.scope": "\u8303\u56F4",
|
"label.scope": "\u8303\u56F4",
|
||||||
"label.search": "\u641C\u7D22",
|
"label.search": "\u641C\u7D22",
|
||||||
|
|
||||||
|
|||||||
@ -207,9 +207,10 @@ export default {
|
|||||||
docHelp: 'adminguide/virtual_machines.html#virtual-machine-snapshots',
|
docHelp: 'adminguide/virtual_machines.html#virtual-machine-snapshots',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
show: (record) => {
|
show: (record, store) => {
|
||||||
return ((['Running'].includes(record.state) && record.hypervisor !== 'LXC') ||
|
return (record.hypervisor !== 'KVM') ||
|
||||||
(['Stopped'].includes(record.state) && !['KVM', 'LXC'].includes(record.hypervisor)))
|
['Stopped', 'Destroyed'].includes(record.state) ||
|
||||||
|
store.features.kvmsnapshotenabled
|
||||||
},
|
},
|
||||||
disabled: (record) => { return record.hostcontrolstate === 'Offline' && record.hypervisor === 'KVM' },
|
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')))
|
||||||
|
|||||||
@ -26,14 +26,14 @@ export default {
|
|||||||
permission: ['listManagementServersMetrics'],
|
permission: ['listManagementServersMetrics'],
|
||||||
resourceType: 'ManagementServer',
|
resourceType: 'ManagementServer',
|
||||||
columns: () => {
|
columns: () => {
|
||||||
const fields = ['name', 'state', 'serviceip', 'version', 'osdistribution', 'agentcount']
|
const fields = ['name', 'state', 'ipaddress', 'version', 'osdistribution', 'agentcount']
|
||||||
const metricsFields = ['collectiontime', 'availableprocessors', 'cpuload', 'heapmemoryused']
|
const metricsFields = ['collectiontime', 'availableprocessors', 'cpuload', 'heapmemoryused']
|
||||||
if (store.getters.metrics) {
|
if (store.getters.metrics) {
|
||||||
fields.push(...metricsFields)
|
fields.push(...metricsFields)
|
||||||
}
|
}
|
||||||
return fields
|
return fields
|
||||||
},
|
},
|
||||||
details: ['collectiontime', 'usageislocal', 'dbislocal', 'lastserverstart', 'lastserverstop', 'lastboottime', 'version', 'loginfo', 'systemtotalcpucycles', 'systemloadaverages', 'systemcycleusage', 'systemmemorytotal', 'systemmemoryfree', 'systemmemoryvirtualsize', 'availableprocessors', 'javadistribution', 'javaversion', 'osdistribution', 'kernelversion', 'agentcount', 'sessions', 'heapmemoryused', 'heapmemorytotal', 'threadsblockedcount', 'threadsdeamoncount', 'threadsnewcount', 'threadsrunnablecount', 'threadsterminatedcount', 'threadstotalcount', 'threadswaitingcount'],
|
details: ['ipaddress', 'collectiontime', 'usageislocal', 'dbislocal', 'lastserverstart', 'lastserverstop', 'lastboottime', 'version', 'loginfo', 'systemtotalcpucycles', 'systemloadaverages', 'systemcycleusage', 'systemmemorytotal', 'systemmemoryfree', 'systemmemoryvirtualsize', 'availableprocessors', 'javadistribution', 'javaversion', 'osdistribution', 'kernelversion', 'agentcount', 'sessions', 'heapmemoryused', 'heapmemorytotal', 'threadsblockedcount', 'threadsdeamoncount', 'threadsnewcount', 'threadsrunnablecount', 'threadsterminatedcount', 'threadstotalcount', 'threadswaitingcount'],
|
||||||
tabs: [
|
tabs: [
|
||||||
{
|
{
|
||||||
name: 'details',
|
name: 'details',
|
||||||
|
|||||||
@ -165,9 +165,10 @@ export default {
|
|||||||
label: 'label.action.take.snapshot',
|
label: 'label.action.take.snapshot',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
show: (record, store) => {
|
show: (record, store) => {
|
||||||
return record.state === 'Ready' && (record.hypervisor !== 'KVM' ||
|
return record.state === 'Ready' &&
|
||||||
record.hypervisor === 'KVM' && record.vmstate === 'Running' && store.features.kvmsnapshotenabled ||
|
(record.hypervisor !== 'KVM' ||
|
||||||
record.hypervisor === 'KVM' && record.vmstate !== 'Running')
|
['Stopped', 'Destroyed'].includes(record.vmstate) ||
|
||||||
|
store.features.kvmsnapshotenabled)
|
||||||
},
|
},
|
||||||
popup: true,
|
popup: true,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/storage/TakeSnapshot.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/storage/TakeSnapshot.vue')))
|
||||||
@ -179,9 +180,10 @@ export default {
|
|||||||
label: 'label.action.recurring.snapshot',
|
label: 'label.action.recurring.snapshot',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
show: (record, store) => {
|
show: (record, store) => {
|
||||||
return record.state === 'Ready' && (record.hypervisor !== 'KVM' ||
|
return record.state === 'Ready' &&
|
||||||
record.hypervisor === 'KVM' && record.vmstate === 'Running' && store.features.kvmsnapshotenabled ||
|
(record.hypervisor !== 'KVM' ||
|
||||||
record.hypervisor === 'KVM' && record.vmstate !== 'Running')
|
(['Stopped', 'Destroyed'].includes(record.vmstate)) ||
|
||||||
|
(store.features.kvmsnapshotenabled))
|
||||||
},
|
},
|
||||||
popup: true,
|
popup: true,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/storage/RecurringSnapshotVolume.vue'))),
|
component: shallowRef(defineAsyncComponent(() => import('@/views/storage/RecurringSnapshotVolume.vue'))),
|
||||||
|
|||||||
@ -47,7 +47,7 @@
|
|||||||
<div class="form__label">{{ $t('label.hypervisor') }}</div>
|
<div class="form__label">{{ $t('label.hypervisor') }}</div>
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="hypervisor"
|
v-model:value="hypervisor"
|
||||||
@change="resetAllFields"
|
@change="hypervisor => onChangeHypervisor(hypervisor)"
|
||||||
showSearch
|
showSearch
|
||||||
optionFilterProp="value"
|
optionFilterProp="value"
|
||||||
:filterOption="(input, option) => {
|
:filterOption="(input, option) => {
|
||||||
@ -109,19 +109,28 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form__item">
|
<div class="form__item">
|
||||||
<div class="form__label">{{ $t('label.vcenterusername') }}</div>
|
<div class="form__label">{{ $t('label.vcenterdatacenter') }}</div>
|
||||||
|
<a-input v-model:value="dataCenter"></a-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form__item" name="useDefaultVMwareCred">
|
||||||
|
<div class="form__label">{{ $t('label.use.existing.vcenter.credentials.from.zone') }}</div>
|
||||||
|
<a-switch v-model="useDefaultVMwareCred" :checked="useDefaultVMwareCred" @change="onChangeUseDefaultVMwareCred()" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template v-if="useDefaultVMwareCred === false">
|
||||||
|
<div class="form__item">
|
||||||
|
<div class="form__label"><span class="required">* </span>{{ $t('label.vcenterusername') }}</div>
|
||||||
|
<span class="required required-label" ref="requiredUsername">{{ $t('label.required') }}</span>
|
||||||
<a-input v-model:value="username"></a-input>
|
<a-input v-model:value="username"></a-input>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form__item">
|
<div class="form__item">
|
||||||
<div class="form__label">{{ $t('label.vcenterpassword') }}</div>
|
<div class="form__label"><span class="required">* </span>{{ $t('label.vcenterpassword') }}</div>
|
||||||
|
<span class="required required-label" ref="requiredPassword">{{ $t('label.required') }}</span>
|
||||||
<a-input type="password" v-model:value="password"></a-input>
|
<a-input type="password" v-model:value="password"></a-input>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
<div class="form__item">
|
|
||||||
<div class="form__label">{{ $t('label.vcenterdatacenter') }}</div>
|
|
||||||
<a-input v-model:value="dataCenter"></a-input>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="form__item">
|
<div class="form__item">
|
||||||
@ -176,6 +185,7 @@ export default {
|
|||||||
username: null,
|
username: null,
|
||||||
password: null,
|
password: null,
|
||||||
url: null,
|
url: null,
|
||||||
|
useDefaultVMwareCred: true,
|
||||||
host: null,
|
host: null,
|
||||||
dataCenter: null,
|
dataCenter: null,
|
||||||
ovm3pool: null,
|
ovm3pool: null,
|
||||||
@ -257,6 +267,27 @@ export default {
|
|||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
fetchVMwareCred () {
|
||||||
|
this.loading = true
|
||||||
|
this.clustertype = 'ExternalManaged'
|
||||||
|
api('listVmwareDcs', {
|
||||||
|
zoneid: this.zoneId
|
||||||
|
}).then(response => {
|
||||||
|
var vmwaredcs = response.listvmwaredcsresponse.VMwareDC
|
||||||
|
if (vmwaredcs !== null) {
|
||||||
|
this.host = vmwaredcs[0].vcenter
|
||||||
|
this.dataCenter = vmwaredcs[0].name
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
this.$notification.error({
|
||||||
|
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||||
|
description: error.response.data.listvmwaredcsresponse.errortext,
|
||||||
|
duration: 0
|
||||||
|
})
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
toggleDedicated () {
|
toggleDedicated () {
|
||||||
this.dedicatedDomainId = null
|
this.dedicatedDomainId = null
|
||||||
this.dedicatedAccount = null
|
this.dedicatedAccount = null
|
||||||
@ -270,35 +301,24 @@ export default {
|
|||||||
}
|
}
|
||||||
this.$refs.requiredCluster.classList.remove('required-label--visible')
|
this.$refs.requiredCluster.classList.remove('required-label--visible')
|
||||||
|
|
||||||
|
if (this.hypervisor === 'VMware' && this.useDefaultVMwareCred === false) {
|
||||||
|
if (!this.username) {
|
||||||
|
this.$refs.requiredUsername.classList.add('required-label--visible')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.password) {
|
||||||
|
this.$refs.requiredPassword.classList.add('required-label--visible')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$refs.requiredUsername.classList.remove('required-label--visible')
|
||||||
|
this.$refs.requiredPassword.classList.remove('required-label--visible')
|
||||||
|
}
|
||||||
|
|
||||||
if (this.hypervisor === 'Ovm3') {
|
if (this.hypervisor === 'Ovm3') {
|
||||||
this.ovm3pool = 'on'
|
this.ovm3pool = 'on'
|
||||||
this.ovm3cluster = 'undefined'
|
this.ovm3cluster = 'undefined'
|
||||||
this.ovm3vip = ''
|
this.ovm3vip = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.hypervisor === 'VMware') {
|
|
||||||
this.clustertype = 'ExternalManaged'
|
|
||||||
if ((this.host === null || this.host.length === 0) &&
|
|
||||||
(this.dataCenter === null || this.dataCenter.length === 0)) {
|
|
||||||
api('listVmwareDcs', {
|
|
||||||
zoneid: this.zoneId
|
|
||||||
}).then(response => {
|
|
||||||
var vmwaredcs = response.listvmwaredcsresponse.VMwareDC
|
|
||||||
if (vmwaredcs !== null) {
|
|
||||||
this.host = vmwaredcs[0].vcenter
|
|
||||||
this.dataCenter = vmwaredcs[0].name
|
|
||||||
}
|
|
||||||
this.addCluster()
|
|
||||||
}).catch(error => {
|
|
||||||
this.$notification.error({
|
|
||||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
|
||||||
description: error.response.data.listvmwaredcsresponse.errortext,
|
|
||||||
duration: 0
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.addCluster()
|
this.addCluster()
|
||||||
},
|
},
|
||||||
addCluster () {
|
addCluster () {
|
||||||
@ -387,7 +407,7 @@ export default {
|
|||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
resetAllFields () {
|
onChangeHypervisor (hypervisor) {
|
||||||
this.clustertype = 'CloudManaged'
|
this.clustertype = 'CloudManaged'
|
||||||
this.username = null
|
this.username = null
|
||||||
this.password = null
|
this.password = null
|
||||||
@ -397,6 +417,16 @@ export default {
|
|||||||
this.ovm3pool = null
|
this.ovm3pool = null
|
||||||
this.ovm3cluster = null
|
this.ovm3cluster = null
|
||||||
this.ovm3vip = null
|
this.ovm3vip = null
|
||||||
|
if (hypervisor === 'VMware') {
|
||||||
|
this.fetchVMwareCred()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChangeUseDefaultVMwareCred () {
|
||||||
|
this.useDefaultVMwareCred = !this.useDefaultVMwareCred
|
||||||
|
if (this.useDefaultVMwareCred) {
|
||||||
|
this.username = null
|
||||||
|
this.password = null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
returnPlaceholder (field) {
|
returnPlaceholder (field) {
|
||||||
this.params.find(i => {
|
this.params.find(i => {
|
||||||
|
|||||||
@ -28,10 +28,9 @@
|
|||||||
|
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.key === 'name'">
|
<template v-if="column.key === 'name'">
|
||||||
<span :style="hierarchyExists ? 'padding-left: 0px;' : 'padding-left: 25px;'">
|
<a-row :style="hierarchyExists ? 'padding-left: 0px;' : 'padding-left: 25px;'">
|
||||||
<b><span v-if="record.parent">└─ </span>{{record.displaytext }} </b> {{ ' (' + record.name + ')' }}
|
<b><span v-if="record.parent">└─ </span>{{record.displaytext }} </b> {{ '(' + record.name + ')' }}
|
||||||
</span>
|
</a-row>
|
||||||
<br/>
|
|
||||||
<span :style="record.parent ? 'padding-left: 50px; display:block' : 'padding-left: 25px; display:block'">{{ record.description }}</span>
|
<span :style="record.parent ? 'padding-left: 50px; display:block' : 'padding-left: 25px; display:block'">{{ record.description }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.key === 'value'">
|
<template v-if="column.key === 'value'">
|
||||||
|
|||||||
@ -116,6 +116,48 @@
|
|||||||
:placeholder="apiParams.maxiops.description"/>
|
:placeholder="apiParams.maxiops.description"/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</span>
|
</span>
|
||||||
|
<a-form-item name="attachVolume" ref="attachVolume" v-if="!createVolumeFromVM">
|
||||||
|
<template #label>
|
||||||
|
<tooltip-label :title="$t('label.action.attach.to.instance')" :tooltip="$t('label.attach.vol.to.instance')" />
|
||||||
|
</template>
|
||||||
|
<a-switch v-model:checked="form.attachVolume" :checked="attachVolume" @change="zone => onChangeAttachToVM(zone.id)" />
|
||||||
|
</a-form-item>
|
||||||
|
<span v-if="attachVolume">
|
||||||
|
<a-form-item :label="$t('label.virtualmachineid')" name="virtualmachineid" ref="virtualmachineid">
|
||||||
|
<a-select
|
||||||
|
v-focus="true"
|
||||||
|
v-model:value="form.virtualmachineid"
|
||||||
|
:placeholder="attachVolumeApiParams.virtualmachineid.description"
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="label"
|
||||||
|
:filterOption="(input, option) => {
|
||||||
|
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}" >
|
||||||
|
<a-select-option v-for="vm in virtualmachines" :key="vm.id" :label="vm.name || vm.displayname">
|
||||||
|
{{ vm.name || vm.displayname }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item >
|
||||||
|
<a-form-item :label="$t('label.deviceid')">
|
||||||
|
<div style="margin-bottom: 10px">
|
||||||
|
<a-collapse>
|
||||||
|
<a-collapse-panel header="More information about deviceID">
|
||||||
|
<a-alert type="warning">
|
||||||
|
<template #message>
|
||||||
|
<span v-html="attachVolumeApiParams.deviceid.description" />
|
||||||
|
</template>
|
||||||
|
</a-alert>
|
||||||
|
</a-collapse-panel>
|
||||||
|
</a-collapse>
|
||||||
|
</div>
|
||||||
|
<a-input-number
|
||||||
|
v-model:value="form.deviceid"
|
||||||
|
style="width: 100%;"
|
||||||
|
:min="0"
|
||||||
|
:placeholder="$t('label.deviceid')"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</span>
|
||||||
<div :span="24" class="action-button">
|
<div :span="24" class="action-button">
|
||||||
<a-button @click="closeModal">{{ $t('label.cancel') }}</a-button>
|
<a-button @click="closeModal">{{ $t('label.cancel') }}</a-button>
|
||||||
<a-button type="primary" ref="submit" @click="handleSubmit">{{ $t('label.ok') }}</a-button>
|
<a-button type="primary" ref="submit" @click="handleSubmit">{{ $t('label.ok') }}</a-button>
|
||||||
@ -159,7 +201,10 @@ export default {
|
|||||||
offerings: [],
|
offerings: [],
|
||||||
customDiskOffering: false,
|
customDiskOffering: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
isCustomizedDiskIOps: false
|
isCustomizedDiskIOps: false,
|
||||||
|
virtualmachines: [],
|
||||||
|
attachVolume: false,
|
||||||
|
vmidtoattach: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -204,6 +249,10 @@ export default {
|
|||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
|
if (this.attachVolume) {
|
||||||
|
this.rules.virtualmachineid = [{ required: true, message: this.$t('message.error.select') }]
|
||||||
|
this.rules.deviceid = [{ required: true, message: this.$t('message.error.select') }]
|
||||||
|
}
|
||||||
if (!this.createVolumeFromSnapshot) {
|
if (!this.createVolumeFromSnapshot) {
|
||||||
this.rules.name = [{ required: true, message: this.$t('message.error.volume.name') }]
|
this.rules.name = [{ required: true, message: this.$t('message.error.volume.name') }]
|
||||||
this.rules.diskofferingid = [{ required: true, message: this.$t('message.error.select') }]
|
this.rules.diskofferingid = [{ required: true, message: this.$t('message.error.select') }]
|
||||||
@ -248,6 +297,9 @@ export default {
|
|||||||
this.zones = json.listzonesresponse.zone || []
|
this.zones = json.listzonesresponse.zone || []
|
||||||
this.form.zoneid = this.zones[0].id || ''
|
this.form.zoneid = this.zones[0].id || ''
|
||||||
this.fetchDiskOfferings(this.form.zoneid)
|
this.fetchDiskOfferings(this.form.zoneid)
|
||||||
|
if (this.attachVolume) {
|
||||||
|
this.fetchVirtualMachines(this.form.zoneid)
|
||||||
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
@ -301,6 +353,31 @@ export default {
|
|||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
fetchVirtualMachines (zoneId) {
|
||||||
|
var params = {
|
||||||
|
zoneid: zoneId,
|
||||||
|
details: 'min'
|
||||||
|
}
|
||||||
|
if (this.owner.projectid) {
|
||||||
|
params.projectid = this.owner.projectid
|
||||||
|
} else {
|
||||||
|
params.account = this.owner.account
|
||||||
|
params.domainid = this.owner.domainid
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = true
|
||||||
|
var vmStates = ['Running', 'Stopped']
|
||||||
|
vmStates.forEach((state) => {
|
||||||
|
params.state = state
|
||||||
|
api('listVirtualMachines', params).then(response => {
|
||||||
|
this.virtualmachines = this.virtualmachines.concat(response.listvirtualmachinesresponse.virtualmachine || [])
|
||||||
|
}).catch(error => {
|
||||||
|
this.$notifyError(error)
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
handleSubmit (e) {
|
handleSubmit (e) {
|
||||||
if (this.loading) return
|
if (this.loading) return
|
||||||
this.formRef.value.validate().then(() => {
|
this.formRef.value.validate().then(() => {
|
||||||
@ -315,6 +392,10 @@ export default {
|
|||||||
if (this.createVolumeFromSnapshot) {
|
if (this.createVolumeFromSnapshot) {
|
||||||
values.snapshotid = this.resource.id
|
values.snapshotid = this.resource.id
|
||||||
}
|
}
|
||||||
|
if (this.attachVolume) {
|
||||||
|
this.vmidtoattach = values.virtualmachineid
|
||||||
|
values.virtualmachineid = null
|
||||||
|
}
|
||||||
values.domainid = this.owner.domainid
|
values.domainid = this.owner.domainid
|
||||||
if (this.owner.projectid) {
|
if (this.owner.projectid) {
|
||||||
values.projectid = this.owner.projectid
|
values.projectid = this.owner.projectid
|
||||||
@ -330,10 +411,15 @@ export default {
|
|||||||
successMessage: this.$t('message.success.create.volume'),
|
successMessage: this.$t('message.success.create.volume'),
|
||||||
successMethod: (result) => {
|
successMethod: (result) => {
|
||||||
this.closeModal()
|
this.closeModal()
|
||||||
if (this.createVolumeFromVM) {
|
if (this.createVolumeFromVM || this.attachVolume) {
|
||||||
const params = {}
|
const params = {}
|
||||||
params.id = result.jobresult.volume.id
|
params.id = result.jobresult.volume.id
|
||||||
|
if (this.createVolumeFromVM) {
|
||||||
params.virtualmachineid = this.resource.id
|
params.virtualmachineid = this.resource.id
|
||||||
|
} else {
|
||||||
|
params.virtualmachineid = this.vmidtoattach
|
||||||
|
params.deviceid = values.deviceid
|
||||||
|
}
|
||||||
api('attachVolume', params).then(response => {
|
api('attachVolume', params).then(response => {
|
||||||
this.$pollJob({
|
this.$pollJob({
|
||||||
jobId: response.attachvolumeresponse.jobid,
|
jobId: response.attachvolumeresponse.jobid,
|
||||||
@ -368,6 +454,14 @@ export default {
|
|||||||
const offering = this.offerings.filter(x => x.id === id)
|
const offering = this.offerings.filter(x => x.id === id)
|
||||||
this.customDiskOffering = offering[0]?.iscustomized || false
|
this.customDiskOffering = offering[0]?.iscustomized || false
|
||||||
this.isCustomizedDiskIOps = offering[0]?.iscustomizediops || false
|
this.isCustomizedDiskIOps = offering[0]?.iscustomizediops || false
|
||||||
|
},
|
||||||
|
onChangeAttachToVM (zone) {
|
||||||
|
this.attachVolume = !this.attachVolume
|
||||||
|
this.virtualmachines = []
|
||||||
|
if (this.attachVolume) {
|
||||||
|
this.attachVolumeApiParams = this.$getApiParams('attachVolume')
|
||||||
|
this.fetchVirtualMachines(this.form.zoneid)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
@close-action="closeAction"
|
@close-action="closeAction"
|
||||||
@refresh="handleRefresh"/>
|
@refresh="handleRefresh"/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane :tab="$t('label.scheduled.snapshots')" key="2">
|
<a-tab-pane :tab="$t('label.action.recurring.snapshot')" key="2">
|
||||||
<ScheduledSnapshots
|
<ScheduledSnapshots
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:resource="resource"
|
:resource="resource"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user