Merge branch '4.20'

This commit is contained in:
Daan Hoogland 2025-07-29 16:50:55 +02:00
commit 0b3959221b
118 changed files with 1994 additions and 1553 deletions

View File

@ -87,6 +87,8 @@ public interface AccountService {
boolean isDomainAdmin(Long accountId); boolean isDomainAdmin(Long accountId);
boolean isResourceDomainAdmin(Long accountId);
boolean isNormalUser(long accountId); boolean isNormalUser(long accountId);
User getActiveUserByRegistrationToken(String registrationToken); User getActiveUserByRegistrationToken(String registrationToken);

View File

@ -190,7 +190,7 @@ public class ListClustersCmd extends BaseListCmd {
@Override @Override
public void execute() { public void execute() {
Pair<List<ClusterResponse>, Integer> clusterResponses = getClusterResponses(); Pair<List<ClusterResponse>, Integer> clusterResponses = getClusterResponses();
ListResponse<ClusterResponse> response = new ListResponse<ClusterResponse>(); ListResponse<ClusterResponse> response = new ListResponse<>();
response.setResponses(clusterResponses.first(), clusterResponses.second()); response.setResponses(clusterResponses.first(), clusterResponses.second());
response.setResponseName(getCommandName()); response.setResponseName(getCommandName());
this.setResponseObject(response); this.setResponseObject(response);

View File

@ -103,8 +103,8 @@ public class ListPodsByCmd extends BaseListCmd {
@Override @Override
public void execute() { public void execute() {
Pair<List<? extends Pod>, Integer> result = _mgr.searchForPods(this); Pair<List<? extends Pod>, Integer> result = _mgr.searchForPods(this);
ListResponse<PodResponse> response = new ListResponse<PodResponse>(); ListResponse<PodResponse> response = new ListResponse<>();
List<PodResponse> podResponses = new ArrayList<PodResponse>(); List<PodResponse> podResponses = new ArrayList<>();
for (Pod pod : result.first()) { for (Pod pod : result.first()) {
PodResponse podResponse = _responseGenerator.createPodResponse(pod, showCapacities); PodResponse podResponse = _responseGenerator.createPodResponse(pod, showCapacities);
podResponse.setObjectName("pod"); podResponse.setObjectName("pod");

View File

@ -74,6 +74,7 @@ public class ListCapabilitiesCmd extends BaseCmd {
response.setSharedFsVmMinRamSize((Integer)capabilities.get(ApiConstants.SHAREDFSVM_MIN_RAM_SIZE)); response.setSharedFsVmMinRamSize((Integer)capabilities.get(ApiConstants.SHAREDFSVM_MIN_RAM_SIZE));
response.setInstanceLeaseEnabled((Boolean) capabilities.get(ApiConstants.INSTANCE_LEASE_ENABLED)); response.setInstanceLeaseEnabled((Boolean) capabilities.get(ApiConstants.INSTANCE_LEASE_ENABLED));
response.setExtensionsPath((String)capabilities.get(ApiConstants.EXTENSIONS_PATH)); response.setExtensionsPath((String)capabilities.get(ApiConstants.EXTENSIONS_PATH));
response.setDynamicScalingEnabled((Boolean) capabilities.get(ApiConstants.DYNAMIC_SCALING_ENABLED));
response.setObjectName("capability"); response.setObjectName("capability");
response.setResponseName(getCommandName()); response.setResponseName(getCommandName());
this.setResponseObject(response); this.setResponseObject(response);

View File

@ -20,6 +20,7 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.cloud.cpu.CPU;
import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType; import org.apache.cloudstack.api.ApiCommandResourceType;
@ -148,6 +149,11 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
since = "4.19.0") since = "4.19.0")
private String accountName; private String accountName;
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
description = "the CPU arch of the template. Valid options are: x86_64, aarch64. Defaults to x86_64",
since = "4.20.2")
private String arch;
// /////////////////////////////////////////////////// // ///////////////////////////////////////////////////
// ///////////////// Accessors /////////////////////// // ///////////////// Accessors ///////////////////////
// /////////////////////////////////////////////////// // ///////////////////////////////////////////////////
@ -234,6 +240,10 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
return accountName; return accountName;
} }
public CPU.CPUArch getArch() {
return CPU.CPUArch.fromType(arch);
}
// /////////////////////////////////////////////////// // ///////////////////////////////////////////////////
// ///////////// API Implementation/////////////////// // ///////////// API Implementation///////////////////
// /////////////////////////////////////////////////// // ///////////////////////////////////////////////////

View File

@ -33,7 +33,7 @@ import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.UserData; import com.cloud.user.UserData;
@APICommand(name = "registerUserData", @APICommand(name = "registerUserData",
description = "Register a new userdata.", description = "Register a new User Data.",
since = "4.18", since = "4.18",
responseObject = SuccessResponse.class, responseObject = SuccessResponse.class,
requestHasSensitiveInfo = false, requestHasSensitiveInfo = false,
@ -46,9 +46,55 @@ public class RegisterUserDataCmd extends BaseRegisterUserDataCmd {
//////////////// API parameters ///////////////////// //////////////// API parameters /////////////////////
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
@Parameter(name = ApiConstants.USER_DATA, type = CommandType.STRING, required = true, description = "User data content", length = 1048576) @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of the User Data")
protected String userData; private String name;
//Owner information
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional account for the User Data. Must be used with domainId.")
private String accountName;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.UUID,
entityType = DomainResponse.class,
description = "an optional domainId for the User Data. If the account parameter is used, domainId must also be used.")
private Long domainId;
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "an optional project for the User Data")
private Long projectId;
@Parameter(name = ApiConstants.USER_DATA,
type = CommandType.STRING,
required = true,
description = "Base64 encoded User Data content. " +
"Using HTTP GET (via querystring), you can send up to 4KB of data after base64 encoding. " +
"Using HTTP POST (via POST body), you can send up to 32KB of data after base64 encoding, " +
"which can be increased upto 1MB using the vm.userdata.max.length setting",
length = 1048576)
private String userData;
@Parameter(name = ApiConstants.PARAMS, type = CommandType.STRING, description = "comma separated list of variables declared in the User Data content")
private String params;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getName() {
return name;
}
public String getAccountName() {
return accountName;
}
public Long getDomainId() {
return domainId;
}
public Long getProjectId() {
return projectId;
}
public String getUserData() { public String getUserData() {
return userData; return userData;

View File

@ -34,8 +34,6 @@ import org.apache.cloudstack.api.response.ZoneResponse;
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListZonesCmd extends BaseListCmd implements UserCmd { public class ListZonesCmd extends BaseListCmd implements UserCmd {
private static final String s_name = "listzonesresponse";
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
//////////////// API parameters ///////////////////// //////////////// API parameters /////////////////////
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
@ -130,11 +128,6 @@ public class ListZonesCmd extends BaseListCmd implements UserCmd {
/////////////// API Implementation/////////////////// /////////////// API Implementation///////////////////
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override @Override
public void execute() { public void execute() {
ListResponse<ZoneResponse> response = _queryService.listDataCenters(this); ListResponse<ZoneResponse> response = _queryService.listDataCenters(this);

View File

@ -145,6 +145,10 @@ public class CapabilitiesResponse extends BaseResponse {
@Param(description = "The path of the extensions directory", since = "4.21.0", authorized = {RoleType.Admin}) @Param(description = "The path of the extensions directory", since = "4.21.0", authorized = {RoleType.Admin})
private String extensionsPath; private String extensionsPath;
@SerializedName(ApiConstants.DYNAMIC_SCALING_ENABLED)
@Param(description = "true if dynamically scaling for instances is enabled", since = "4.21.0")
private Boolean dynamicScalingEnabled;
public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) { public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
this.securityGroupsEnabled = securityGroupsEnabled; this.securityGroupsEnabled = securityGroupsEnabled;
} }
@ -264,4 +268,8 @@ public class CapabilitiesResponse extends BaseResponse {
public void setExtensionsPath(String extensionsPath) { public void setExtensionsPath(String extensionsPath) {
this.extensionsPath = extensionsPath; this.extensionsPath = extensionsPath;
} }
public void setDynamicScalingEnabled(Boolean dynamicScalingEnabled) {
this.dynamicScalingEnabled = dynamicScalingEnabled;
}
} }

View File

@ -27,41 +27,41 @@ import org.apache.cloudstack.api.EntityReference;
public class UserDataResponse extends BaseResponseWithAnnotations implements ControlledEntityResponse { public class UserDataResponse extends BaseResponseWithAnnotations implements ControlledEntityResponse {
@SerializedName(ApiConstants.ID) @SerializedName(ApiConstants.ID)
@Param(description = "ID of the ssh keypair") @Param(description = "ID of the User Data")
private String id; private String id;
@SerializedName(ApiConstants.NAME) @SerializedName(ApiConstants.NAME)
@Param(description = "Name of the userdata") @Param(description = "Name of the User Data")
private String name; private String name;
@SerializedName(ApiConstants.ACCOUNT_ID) @Param(description="the owner id of the userdata") @SerializedName(ApiConstants.ACCOUNT_ID) @Param(description="the owner id of the User Data")
private String accountId; private String accountId;
@SerializedName(ApiConstants.ACCOUNT) @Param(description="the owner of the userdata") @SerializedName(ApiConstants.ACCOUNT) @Param(description="the owner of the User Data")
private String accountName; private String accountName;
@SerializedName(ApiConstants.PROJECT_ID) @SerializedName(ApiConstants.PROJECT_ID)
@Param(description = "the project id of the userdata", since = "4.19.1") @Param(description = "the project id of the User Data", since = "4.19.1")
private String projectId; private String projectId;
@SerializedName(ApiConstants.PROJECT) @SerializedName(ApiConstants.PROJECT)
@Param(description = "the project name of the userdata", since = "4.19.1") @Param(description = "the project name of the User Data", since = "4.19.1")
private String projectName; private String projectName;
@SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain id of the userdata owner") @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain id of the User Data owner")
private String domainId; private String domainId;
@SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the userdata owner") @SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the User Data owner")
private String domain; private String domain;
@SerializedName(ApiConstants.DOMAIN_PATH) @SerializedName(ApiConstants.DOMAIN_PATH)
@Param(description = "path of the domain to which the userdata owner belongs", since = "4.19.2.0") @Param(description = "path of the domain to which the User Data owner belongs", since = "4.19.2.0")
private String domainPath; private String domainPath;
@SerializedName(ApiConstants.USER_DATA) @Param(description="base64 encoded userdata content") @SerializedName(ApiConstants.USER_DATA) @Param(description="base64 encoded User Data content")
private String userData; private String userData;
@SerializedName(ApiConstants.PARAMS) @Param(description="list of parameters which contains the list of keys or string parameters that are needed to be passed for any variables declared in userdata") @SerializedName(ApiConstants.PARAMS) @Param(description="list of parameters which contains the list of keys or string parameters that are needed to be passed for any variables declared in the User Data")
private String params; private String params;
public UserDataResponse() { public UserDataResponse() {

View File

@ -114,11 +114,11 @@ public interface QueryService {
ConfigKey<Boolean> AllowUserViewDestroyedVM = new ConfigKey<>("Advanced", Boolean.class, "allow.user.view.destroyed.vm", "false", ConfigKey<Boolean> AllowUserViewDestroyedVM = new ConfigKey<>("Advanced", Boolean.class, "allow.user.view.destroyed.vm", "false",
"Determines whether users can view their destroyed or expunging vm ", true, ConfigKey.Scope.Account); "Determines whether users can view their destroyed or expunging vm ", true, ConfigKey.Scope.Account);
static final ConfigKey<String> UserVMDeniedDetails = new ConfigKey<>(String.class, ConfigKey<String> UserVMDeniedDetails = new ConfigKey<>(String.class,
"user.vm.denied.details", "Advanced", "rootdisksize, cpuOvercommitRatio, memoryOvercommitRatio, Message.ReservedCapacityFreed.Flag", "user.vm.denied.details", "Advanced", "rootdisksize, cpuOvercommitRatio, memoryOvercommitRatio, Message.ReservedCapacityFreed.Flag",
"Determines whether users can view certain VM settings. When set to empty, default value used is: rootdisksize, cpuOvercommitRatio, memoryOvercommitRatio, Message.ReservedCapacityFreed.Flag.", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null); "Determines whether users can view certain VM settings. When set to empty, default value used is: rootdisksize, cpuOvercommitRatio, memoryOvercommitRatio, Message.ReservedCapacityFreed.Flag.", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null);
static final ConfigKey<String> UserVMReadOnlyDetails = new ConfigKey<>(String.class, ConfigKey<String> UserVMReadOnlyDetails = new ConfigKey<>(String.class,
"user.vm.readonly.details", "Advanced", "dataDiskController, rootDiskController", "user.vm.readonly.details", "Advanced", "dataDiskController, rootDiskController",
"List of read-only VM settings/details as comma separated string", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null); "List of read-only VM settings/details as comma separated string", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null);
@ -127,16 +127,20 @@ public interface QueryService {
"network offering, zones), we use the flag to determine if the entities should be sorted ascending (when flag is true) " + "network offering, zones), we use the flag to determine if the entities should be sorted ascending (when flag is true) " +
"or descending (when flag is false). Within the scope of the config all users see the same result.", true, ConfigKey.Scope.Global); "or descending (when flag is false). Within the scope of the config all users see the same result.", true, ConfigKey.Scope.Global);
public static final ConfigKey<Boolean> AllowUserViewAllDomainAccounts = new ConfigKey<>("Advanced", Boolean.class, ConfigKey<Boolean> AllowUserViewAllDomainAccounts = new ConfigKey<>("Advanced", Boolean.class,
"allow.user.view.all.domain.accounts", "false", "allow.user.view.all.domain.accounts", "false",
"Determines whether users can view all user accounts within the same domain", true, ConfigKey.Scope.Domain); "Determines whether users can view all user accounts within the same domain", true, ConfigKey.Scope.Domain);
static final ConfigKey<Boolean> SharePublicTemplatesWithOtherDomains = new ConfigKey<>("Advanced", Boolean.class, "share.public.templates.with.other.domains", "true", ConfigKey<Boolean> AllowUserViewAllDataCenters = new ConfigKey<>("Advanced", Boolean.class, "allow.user.view.all.zones", "true",
"Determines whether for instance a Resource Admin can view zones that are not dedicated to them.", true, ConfigKey.Scope.Domain);
ConfigKey<Boolean> SharePublicTemplatesWithOtherDomains = new ConfigKey<>("Advanced", Boolean.class, "share.public.templates.with.other.domains", "true",
"If false, templates of this domain will not show up in the list templates of other domains.", true, ConfigKey.Scope.Domain); "If false, templates of this domain will not show up in the list templates of other domains.", true, ConfigKey.Scope.Domain);
ConfigKey<Boolean> ReturnVmStatsOnVmList = new ConfigKey<>("Advanced", Boolean.class, "list.vm.default.details.stats", "true", ConfigKey<Boolean> ReturnVmStatsOnVmList = new ConfigKey<>("Advanced", Boolean.class, "list.vm.default.details.stats", "true",
"Determines whether VM stats should be returned when details are not explicitly specified in listVirtualMachines API request. When false, details default to [group, nics, secgrp, tmpl, servoff, diskoff, backoff, iso, volume, min, affgrp]. When true, all details are returned including 'stats'.", true, ConfigKey.Scope.Global); "Determines whether VM stats should be returned when details are not explicitly specified in listVirtualMachines API request. When false, details default to [group, nics, secgrp, tmpl, servoff, diskoff, backoff, iso, volume, min, affgrp]. When true, all details are returned including 'stats'.", true, ConfigKey.Scope.Global);
ListResponse<UserResponse> searchForUsers(ResponseObject.ResponseView responseView, ListUsersCmd cmd) throws PermissionDeniedException; ListResponse<UserResponse> searchForUsers(ResponseObject.ResponseView responseView, ListUsersCmd cmd) throws PermissionDeniedException;
ListResponse<UserResponse> searchForUsers(Long domainId, boolean recursive) throws PermissionDeniedException; ListResponse<UserResponse> searchForUsers(Long domainId, boolean recursive) throws PermissionDeniedException;

View File

@ -17,22 +17,33 @@
package com.cloud.agent.api; package com.cloud.agent.api;
import org.apache.cloudstack.storage.volume.VolumeOnStorageTO;
import java.util.Map;
public class CheckVolumeAnswer extends Answer { public class CheckVolumeAnswer extends Answer {
private long size; private long size;
private Map<VolumeOnStorageTO.Detail, String> volumeDetails;
CheckVolumeAnswer() { CheckVolumeAnswer() {
} }
public CheckVolumeAnswer(CheckVolumeCommand cmd, String details, long size) { public CheckVolumeAnswer(CheckVolumeCommand cmd, final boolean success, String details, long size,
super(cmd, true, details); Map<VolumeOnStorageTO.Detail, String> volumeDetails) {
super(cmd, success, details);
this.size = size; this.size = size;
this.volumeDetails = volumeDetails;
} }
public long getSize() { public long getSize() {
return size; return size;
} }
public Map<VolumeOnStorageTO.Detail, String> getVolumeDetails() {
return volumeDetails;
}
public String getString() { public String getString() {
return "CheckVolumeAnswer [size=" + size + "]"; return "CheckVolumeAnswer [size=" + size + "]";
} }

View File

@ -17,21 +17,28 @@
package com.cloud.agent.api; package com.cloud.agent.api;
import org.apache.cloudstack.storage.volume.VolumeOnStorageTO;
import java.util.Map;
public class CopyRemoteVolumeAnswer extends Answer { public class CopyRemoteVolumeAnswer extends Answer {
private String remoteIp; private String remoteIp;
private String filename; private String filename;
private long size; private long size;
private Map<VolumeOnStorageTO.Detail, String> volumeDetails;
CopyRemoteVolumeAnswer() { CopyRemoteVolumeAnswer() {
} }
public CopyRemoteVolumeAnswer(CopyRemoteVolumeCommand cmd, String details, String filename, long size) { public CopyRemoteVolumeAnswer(CopyRemoteVolumeCommand cmd, final boolean success, String details, String filename, long size,
super(cmd, true, details); Map<VolumeOnStorageTO.Detail, String> volumeDetails) {
super(cmd, success, details);
this.remoteIp = cmd.getRemoteIp(); this.remoteIp = cmd.getRemoteIp();
this.filename = filename; this.filename = filename;
this.size = size; this.size = size;
this.volumeDetails = volumeDetails;
} }
public String getRemoteIp() { public String getRemoteIp() {
@ -54,6 +61,10 @@ public class CopyRemoteVolumeAnswer extends Answer {
return size; return size;
} }
public Map<VolumeOnStorageTO.Detail, String> getVolumeDetails() {
return volumeDetails;
}
public String getString() { public String getString() {
return "CopyRemoteVolumeAnswer [remoteIp=" + remoteIp + "]"; return "CopyRemoteVolumeAnswer [remoteIp=" + remoteIp + "]";
} }

View File

@ -24,6 +24,7 @@ import com.cloud.utils.PasswordGenerator;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.ca.CAManager; import org.apache.cloudstack.ca.CAManager;
import org.apache.cloudstack.framework.ca.Certificate; import org.apache.cloudstack.framework.ca.Certificate;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.utils.security.CertUtils; import org.apache.cloudstack.utils.security.CertUtils;
import org.apache.cloudstack.utils.security.KeyStoreUtils; import org.apache.cloudstack.utils.security.KeyStoreUtils;
@ -37,6 +38,9 @@ import java.util.Base64;
*/ */
public interface VirtualMachineGuru { public interface VirtualMachineGuru {
static final ConfigKey<String> NTPServerConfig = new ConfigKey<String>(String.class, "ntp.server.list", "Advanced", null,
"Comma separated list of NTP servers to configure in System VMs", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null);
boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context); boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context);
/** /**

View File

@ -37,4 +37,6 @@ public interface AutoScaleVmGroupVmMapDao extends GenericDao<AutoScaleVmGroupVmM
public boolean removeByGroup(long vmGroupId); public boolean removeByGroup(long vmGroupId);
int expungeByVmList(List<Long> vmIds, Long batchSize); int expungeByVmList(List<Long> vmIds, Long batchSize);
int getErroredInstanceCount(long vmGroupId);
} }

View File

@ -127,4 +127,13 @@ public class AutoScaleVmGroupVmMapDaoImpl extends GenericDaoBase<AutoScaleVmGrou
sc.setParameters("vmIds", vmIds.toArray()); sc.setParameters("vmIds", vmIds.toArray());
return batchExpunge(sc, batchSize); return batchExpunge(sc, batchSize);
} }
@Override
public int getErroredInstanceCount(long vmGroupId) {
SearchCriteria<Integer> sc = CountBy.create();
sc.setParameters("vmGroupId", vmGroupId);
sc.setJoinParameters("vmSearch", "states", State.Error);
final List<Integer> results = customSearch(sc, null);
return results.get(0);
}
} }

View File

@ -58,6 +58,7 @@ import javax.inject.Inject;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -169,6 +170,7 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
if (VirtualMachine.State.Stopped.equals(vm.getState())) { if (VirtualMachine.State.Stopped.equals(vm.getState())) {
List<VolumeVO> vmVolumes = volumeDao.findByInstance(vm.getId()); List<VolumeVO> vmVolumes = volumeDao.findByInstance(vm.getId());
vmVolumes.sort(Comparator.comparing(Volume::getDeviceId));
List<String> volumePaths = getVolumePaths(vmVolumes); List<String> volumePaths = getVolumePaths(vmVolumes);
command.setVolumePaths(volumePaths); command.setVolumePaths(volumePaths);
} }
@ -223,7 +225,10 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
@Override @Override
public boolean restoreVMFromBackup(VirtualMachine vm, Backup backup) { public boolean restoreVMFromBackup(VirtualMachine vm, Backup backup) {
List<Backup.VolumeInfo> backedVolumes = backup.getBackedUpVolumes(); List<Backup.VolumeInfo> backedVolumes = backup.getBackedUpVolumes();
List<VolumeVO> volumes = backedVolumes.stream().map(volume -> volumeDao.findByUuid(volume.getUuid())).collect(Collectors.toList()); List<VolumeVO> volumes = backedVolumes.stream()
.map(volume -> volumeDao.findByUuid(volume.getUuid()))
.sorted((v1, v2) -> Long.compare(v1.getDeviceId(), v2.getDeviceId()))
.collect(Collectors.toList());
LOG.debug("Restoring vm {} from backup {} on the NAS Backup Provider", vm, backup); LOG.debug("Restoring vm {} from backup {} on the NAS Backup Provider", vm, backup);
BackupRepository backupRepository = getBackupRepository(vm, backup); BackupRepository backupRepository = getBackupRepository(vm, backup);
@ -257,9 +262,13 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
if (Objects.isNull(storagePool)) { if (Objects.isNull(storagePool)) {
throw new CloudRuntimeException("Unable to find storage pool associated to the volume"); throw new CloudRuntimeException("Unable to find storage pool associated to the volume");
} }
String volumePathPrefix = String.format("/mnt/%s", storagePool.getUuid()); String volumePathPrefix;
if (ScopeType.HOST.equals(storagePool.getScope())) { if (ScopeType.HOST.equals(storagePool.getScope())) {
volumePathPrefix = storagePool.getPath(); volumePathPrefix = storagePool.getPath();
} else if (Storage.StoragePoolType.SharedMountPoint.equals(storagePool.getPoolType())) {
volumePathPrefix = storagePool.getPath();
} else {
volumePathPrefix = String.format("/mnt/%s", storagePool.getUuid());
} }
volumePaths.add(String.format("%s/%s", volumePathPrefix, volume.getPath())); volumePaths.add(String.format("%s/%s", volumePathPrefix, volume.getPath()));
} }

View File

@ -3731,7 +3731,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
if (!meetRequirements) { if (!meetRequirements) {
return false; return false;
} }
return isUbuntuHost() || isIoUringSupportedByQemu(); return isUbuntuOrDebianHost() || isIoUringSupportedByQemu();
} }
/** /**
@ -3744,13 +3744,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return diskBus != DiskDef.DiskBus.IDE || getHypervisorQemuVersion() >= HYPERVISOR_QEMU_VERSION_IDE_DISCARD_FIXED; return diskBus != DiskDef.DiskBus.IDE || getHypervisorQemuVersion() >= HYPERVISOR_QEMU_VERSION_IDE_DISCARD_FIXED;
} }
public boolean isUbuntuHost() { public boolean isUbuntuOrDebianHost() {
Map<String, String> versionString = getVersionStrings(); Map<String, String> versionString = getVersionStrings();
String hostKey = "Host.OS"; String hostKey = "Host.OS";
if (MapUtils.isEmpty(versionString) || !versionString.containsKey(hostKey) || versionString.get(hostKey) == null) { if (MapUtils.isEmpty(versionString) || !versionString.containsKey(hostKey) || versionString.get(hostKey) == null) {
return false; return false;
} }
return versionString.get(hostKey).equalsIgnoreCase("ubuntu"); return versionString.get(hostKey).equalsIgnoreCase("ubuntu")
|| versionString.get(hostKey).toLowerCase().startsWith("debian");
} }
private KVMPhysicalDisk getPhysicalDiskFromNfsStore(String dataStoreUrl, DataTO data) { private KVMPhysicalDisk getPhysicalDiskFromNfsStore(String dataStoreUrl, DataTO data) {
@ -5838,14 +5839,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
public boolean hostSupportsInstanceConversion() { public boolean hostSupportsInstanceConversion() {
int exitValue = Script.runSimpleBashScriptForExitValue(INSTANCE_CONVERSION_SUPPORTED_CHECK_CMD); int exitValue = Script.runSimpleBashScriptForExitValue(INSTANCE_CONVERSION_SUPPORTED_CHECK_CMD);
if (isUbuntuHost() && exitValue == 0) { if (isUbuntuOrDebianHost() && exitValue == 0) {
exitValue = Script.runSimpleBashScriptForExitValue(UBUNTU_NBDKIT_PKG_CHECK_CMD); exitValue = Script.runSimpleBashScriptForExitValue(UBUNTU_NBDKIT_PKG_CHECK_CMD);
} }
return exitValue == 0; return exitValue == 0;
} }
public boolean hostSupportsWindowsGuestConversion() { public boolean hostSupportsWindowsGuestConversion() {
if (isUbuntuHost()) { if (isUbuntuOrDebianHost()) {
int exitValue = Script.runSimpleBashScriptForExitValue(UBUNTU_WINDOWS_GUEST_CONVERSION_SUPPORTED_CHECK_CMD); int exitValue = Script.runSimpleBashScriptForExitValue(UBUNTU_WINDOWS_GUEST_CONVERSION_SUPPORTED_CHECK_CMD);
return exitValue == 0; return exitValue == 0;
} }

View File

@ -32,7 +32,7 @@ public class LibvirtCheckConvertInstanceCommandWrapper extends CommandWrapper<Ch
public Answer execute(CheckConvertInstanceCommand cmd, LibvirtComputingResource serverResource) { public Answer execute(CheckConvertInstanceCommand cmd, LibvirtComputingResource serverResource) {
if (!serverResource.hostSupportsInstanceConversion()) { if (!serverResource.hostSupportsInstanceConversion()) {
String msg = String.format("Cannot convert the instance from VMware as the virt-v2v binary is not found on host %s. " + String msg = String.format("Cannot convert the instance from VMware as the virt-v2v binary is not found on host %s. " +
"Please install virt-v2v%s on the host before attempting the instance conversion.", serverResource.getPrivateIp(), serverResource.isUbuntuHost()? ", nbdkit" : ""); "Please install virt-v2v%s on the host before attempting the instance conversion.", serverResource.getPrivateIp(), serverResource.isUbuntuOrDebianHost()? ", nbdkit" : "");
logger.info(msg); logger.info(msg);
return new CheckConvertInstanceAnswer(cmd, false, msg); return new CheckConvertInstanceAnswer(cmd, false, msg);
} }

View File

@ -31,16 +31,24 @@ import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ResourceWrapper; import com.cloud.resource.ResourceWrapper;
import com.cloud.storage.Storage; import com.cloud.storage.Storage;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.storage.volume.VolumeOnStorageTO;
import org.apache.cloudstack.utils.qemu.QemuImg; import org.apache.cloudstack.utils.qemu.QemuImg;
import org.apache.cloudstack.utils.qemu.QemuImgException; import org.apache.cloudstack.utils.qemu.QemuImgException;
import org.apache.cloudstack.utils.qemu.QemuImgFile; import org.apache.cloudstack.utils.qemu.QemuImgFile;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.libvirt.LibvirtException; import org.libvirt.LibvirtException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
@ResourceWrapper(handles = CheckVolumeCommand.class) @ResourceWrapper(handles = CheckVolumeCommand.class)
public final class LibvirtCheckVolumeCommandWrapper extends CommandWrapper<CheckVolumeCommand, Answer, LibvirtComputingResource> { public final class LibvirtCheckVolumeCommandWrapper extends CommandWrapper<CheckVolumeCommand, Answer, LibvirtComputingResource> {
private static final List<Storage.StoragePoolType> STORAGE_POOL_TYPES_SUPPORTED = Arrays.asList(Storage.StoragePoolType.Filesystem, Storage.StoragePoolType.NetworkFilesystem);
@Override @Override
public Answer execute(final CheckVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) { public Answer execute(final CheckVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
String result = null; String result = null;
@ -50,34 +58,76 @@ public final class LibvirtCheckVolumeCommandWrapper extends CommandWrapper<Check
KVMStoragePool pool = poolMgr.getStoragePool(storageFilerTO.getType(), storageFilerTO.getUuid()); KVMStoragePool pool = poolMgr.getStoragePool(storageFilerTO.getType(), storageFilerTO.getUuid());
try { try {
if (storageFilerTO.getType() == Storage.StoragePoolType.Filesystem || if (STORAGE_POOL_TYPES_SUPPORTED.contains(storageFilerTO.getType())) {
storageFilerTO.getType() == Storage.StoragePoolType.NetworkFilesystem) {
final KVMPhysicalDisk vol = pool.getPhysicalDisk(srcFile); final KVMPhysicalDisk vol = pool.getPhysicalDisk(srcFile);
final String path = vol.getPath(); final String path = vol.getPath();
long size = getVirtualSizeFromFile(path); try {
return new CheckVolumeAnswer(command, "", size); KVMPhysicalDisk.checkQcow2File(path);
} catch (final CloudRuntimeException e) {
return new CheckVolumeAnswer(command, false, "", 0, getVolumeDetails(pool, vol));
}
long size = KVMPhysicalDisk.getVirtualSizeFromFile(path);
return new CheckVolumeAnswer(command, true, "", size, getVolumeDetails(pool, vol));
} else { } else {
return new Answer(command, false, "Unsupported Storage Pool"); return new Answer(command, false, "Unsupported Storage Pool");
} }
} catch (final Exception e) { } catch (final Exception e) {
logger.error("Error while locating disk: "+ e.getMessage()); logger.error("Error while checking the disk: {}", e.getMessage());
return new Answer(command, false, result); return new Answer(command, false, result);
} }
} }
private long getVirtualSizeFromFile(String path) { private Map<VolumeOnStorageTO.Detail, String> getVolumeDetails(KVMStoragePool pool, KVMPhysicalDisk disk) {
Map<String, String> info = getDiskFileInfo(pool, disk, true);
if (MapUtils.isEmpty(info)) {
return null;
}
Map<VolumeOnStorageTO.Detail, String> volumeDetails = new HashMap<>();
String backingFilePath = info.get(QemuImg.BACKING_FILE);
if (StringUtils.isNotBlank(backingFilePath)) {
volumeDetails.put(VolumeOnStorageTO.Detail.BACKING_FILE, backingFilePath);
}
String backingFileFormat = info.get(QemuImg.BACKING_FILE_FORMAT);
if (StringUtils.isNotBlank(backingFileFormat)) {
volumeDetails.put(VolumeOnStorageTO.Detail.BACKING_FILE_FORMAT, backingFileFormat);
}
String clusterSize = info.get(QemuImg.CLUSTER_SIZE);
if (StringUtils.isNotBlank(clusterSize)) {
volumeDetails.put(VolumeOnStorageTO.Detail.CLUSTER_SIZE, clusterSize);
}
String fileFormat = info.get(QemuImg.FILE_FORMAT);
if (StringUtils.isNotBlank(fileFormat)) {
volumeDetails.put(VolumeOnStorageTO.Detail.FILE_FORMAT, fileFormat);
}
String encrypted = info.get(QemuImg.ENCRYPTED);
if (StringUtils.isNotBlank(encrypted) && encrypted.equalsIgnoreCase("yes")) {
volumeDetails.put(VolumeOnStorageTO.Detail.IS_ENCRYPTED, String.valueOf(Boolean.TRUE));
}
Boolean isLocked = isDiskFileLocked(pool, disk);
volumeDetails.put(VolumeOnStorageTO.Detail.IS_LOCKED, String.valueOf(isLocked));
return volumeDetails;
}
private Map<String, String> getDiskFileInfo(KVMStoragePool pool, KVMPhysicalDisk disk, boolean secure) {
if (!STORAGE_POOL_TYPES_SUPPORTED.contains(pool.getType())) {
return new HashMap<>(); // unknown
}
try { try {
QemuImg qemu = new QemuImg(0); QemuImg qemu = new QemuImg(0);
QemuImgFile qemuFile = new QemuImgFile(path); QemuImgFile qemuFile = new QemuImgFile(disk.getPath(), disk.getFormat());
Map<String, String> info = qemu.info(qemuFile); return qemu.info(qemuFile, secure);
if (info.containsKey(QemuImg.VIRTUAL_SIZE)) {
return Long.parseLong(info.get(QemuImg.VIRTUAL_SIZE));
} else {
throw new CloudRuntimeException("Unable to determine virtual size of volume at path " + path);
}
} catch (QemuImgException | LibvirtException ex) { } catch (QemuImgException | LibvirtException ex) {
throw new CloudRuntimeException("Error when inspecting volume at path " + path, ex); logger.error("Failed to get info of disk file: " + ex.getMessage());
return null;
} }
} }
private boolean isDiskFileLocked(KVMStoragePool pool, KVMPhysicalDisk disk) {
Map<String, String> info = getDiskFileInfo(pool, disk, false);
return info == null;
}
} }

View File

@ -60,7 +60,7 @@ public class LibvirtConvertInstanceCommandWrapper extends CommandWrapper<Convert
if (cmd.getCheckConversionSupport() && !serverResource.hostSupportsInstanceConversion()) { if (cmd.getCheckConversionSupport() && !serverResource.hostSupportsInstanceConversion()) {
String msg = String.format("Cannot convert the instance %s from VMware as the virt-v2v binary is not found. " + String msg = String.format("Cannot convert the instance %s from VMware as the virt-v2v binary is not found. " +
"Please install virt-v2v%s on the host before attempting the instance conversion.", sourceInstanceName, serverResource.isUbuntuHost()? ", nbdkit" : ""); "Please install virt-v2v%s on the host before attempting the instance conversion.", sourceInstanceName, serverResource.isUbuntuOrDebianHost()? ", nbdkit" : "");
logger.info(msg); logger.info(msg);
return new Answer(cmd, false, msg); return new Answer(cmd, false, msg);
} }

View File

@ -31,15 +31,22 @@ import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ResourceWrapper; import com.cloud.resource.ResourceWrapper;
import com.cloud.storage.Storage; import com.cloud.storage.Storage;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.storage.volume.VolumeOnStorageTO;
import org.apache.cloudstack.utils.qemu.QemuImg; import org.apache.cloudstack.utils.qemu.QemuImg;
import org.apache.cloudstack.utils.qemu.QemuImgException; import org.apache.cloudstack.utils.qemu.QemuImgException;
import org.apache.cloudstack.utils.qemu.QemuImgFile; import org.apache.cloudstack.utils.qemu.QemuImgFile;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.libvirt.LibvirtException; import org.libvirt.LibvirtException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
@ResourceWrapper(handles = CopyRemoteVolumeCommand.class) @ResourceWrapper(handles = CopyRemoteVolumeCommand.class)
public final class LibvirtCopyRemoteVolumeCommandWrapper extends CommandWrapper<CopyRemoteVolumeCommand, Answer, LibvirtComputingResource> { public final class LibvirtCopyRemoteVolumeCommandWrapper extends CommandWrapper<CopyRemoteVolumeCommand, Answer, LibvirtComputingResource> {
private static final List<Storage.StoragePoolType> STORAGE_POOL_TYPES_SUPPORTED = Arrays.asList(Storage.StoragePoolType.Filesystem, Storage.StoragePoolType.NetworkFilesystem);
@Override @Override
public Answer execute(final CopyRemoteVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) { public Answer execute(final CopyRemoteVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
@ -55,14 +62,19 @@ public final class LibvirtCopyRemoteVolumeCommandWrapper extends CommandWrapper<
int timeoutInSecs = command.getWait(); int timeoutInSecs = command.getWait();
try { try {
if (storageFilerTO.getType() == Storage.StoragePoolType.Filesystem || if (STORAGE_POOL_TYPES_SUPPORTED.contains(storageFilerTO.getType())) {
storageFilerTO.getType() == Storage.StoragePoolType.NetworkFilesystem) {
String filename = libvirtComputingResource.copyVolume(srcIp, username, password, dstPath, srcFile, tmpPath, timeoutInSecs); String filename = libvirtComputingResource.copyVolume(srcIp, username, password, dstPath, srcFile, tmpPath, timeoutInSecs);
logger.debug("Volume " + srcFile + " copy successful, copied to file: " + filename); logger.debug("Volume " + srcFile + " copy successful, copied to file: " + filename);
final KVMPhysicalDisk vol = pool.getPhysicalDisk(filename); final KVMPhysicalDisk vol = pool.getPhysicalDisk(filename);
final String path = vol.getPath(); final String path = vol.getPath();
long size = getVirtualSizeFromFile(path); try {
return new CopyRemoteVolumeAnswer(command, "", filename, size); KVMPhysicalDisk.checkQcow2File(path);
} catch (final CloudRuntimeException e) {
return new CopyRemoteVolumeAnswer(command, false, "", filename, 0, getVolumeDetails(pool, vol));
}
long size = KVMPhysicalDisk.getVirtualSizeFromFile(path);
return new CopyRemoteVolumeAnswer(command, true, "", filename, size, getVolumeDetails(pool, vol));
} else { } else {
String msg = "Unsupported storage pool type: " + storageFilerTO.getType().toString() + ", only local and NFS pools are supported"; String msg = "Unsupported storage pool type: " + storageFilerTO.getType().toString() + ", only local and NFS pools are supported";
return new Answer(command, false, msg); return new Answer(command, false, msg);
@ -74,18 +86,56 @@ public final class LibvirtCopyRemoteVolumeCommandWrapper extends CommandWrapper<
} }
} }
private long getVirtualSizeFromFile(String path) { private Map<VolumeOnStorageTO.Detail, String> getVolumeDetails(KVMStoragePool pool, KVMPhysicalDisk disk) {
Map<String, String> info = getDiskFileInfo(pool, disk, true);
if (MapUtils.isEmpty(info)) {
return null;
}
Map<VolumeOnStorageTO.Detail, String> volumeDetails = new HashMap<>();
String backingFilePath = info.get(QemuImg.BACKING_FILE);
if (StringUtils.isNotBlank(backingFilePath)) {
volumeDetails.put(VolumeOnStorageTO.Detail.BACKING_FILE, backingFilePath);
}
String backingFileFormat = info.get(QemuImg.BACKING_FILE_FORMAT);
if (StringUtils.isNotBlank(backingFileFormat)) {
volumeDetails.put(VolumeOnStorageTO.Detail.BACKING_FILE_FORMAT, backingFileFormat);
}
String clusterSize = info.get(QemuImg.CLUSTER_SIZE);
if (StringUtils.isNotBlank(clusterSize)) {
volumeDetails.put(VolumeOnStorageTO.Detail.CLUSTER_SIZE, clusterSize);
}
String fileFormat = info.get(QemuImg.FILE_FORMAT);
if (StringUtils.isNotBlank(fileFormat)) {
volumeDetails.put(VolumeOnStorageTO.Detail.FILE_FORMAT, fileFormat);
}
String encrypted = info.get(QemuImg.ENCRYPTED);
if (StringUtils.isNotBlank(encrypted) && encrypted.equalsIgnoreCase("yes")) {
volumeDetails.put(VolumeOnStorageTO.Detail.IS_ENCRYPTED, String.valueOf(Boolean.TRUE));
}
Boolean isLocked = isDiskFileLocked(pool, disk);
volumeDetails.put(VolumeOnStorageTO.Detail.IS_LOCKED, String.valueOf(isLocked));
return volumeDetails;
}
private Map<String, String> getDiskFileInfo(KVMStoragePool pool, KVMPhysicalDisk disk, boolean secure) {
if (!STORAGE_POOL_TYPES_SUPPORTED.contains(pool.getType())) {
return new HashMap<>(); // unknown
}
try { try {
QemuImg qemu = new QemuImg(0); QemuImg qemu = new QemuImg(0);
QemuImgFile qemuFile = new QemuImgFile(path); QemuImgFile qemuFile = new QemuImgFile(disk.getPath(), disk.getFormat());
Map<String, String> info = qemu.info(qemuFile); return qemu.info(qemuFile, secure);
if (info.containsKey(QemuImg.VIRTUAL_SIZE)) {
return Long.parseLong(info.get(QemuImg.VIRTUAL_SIZE));
} else {
throw new CloudRuntimeException("Unable to determine virtual size of volume at path " + path);
}
} catch (QemuImgException | LibvirtException ex) { } catch (QemuImgException | LibvirtException ex) {
throw new CloudRuntimeException("Error when inspecting volume at path " + path, ex); logger.error("Failed to get info of disk file: " + ex.getMessage());
return null;
} }
} }
private boolean isDiskFileLocked(KVMStoragePool pool, KVMPhysicalDisk disk) {
Map<String, String> info = getDiskFileInfo(pool, disk, false);
return info == null;
}
} }

View File

@ -36,6 +36,7 @@ import org.apache.cloudstack.utils.qemu.QemuImg;
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import org.apache.cloudstack.utils.qemu.QemuImgException; import org.apache.cloudstack.utils.qemu.QemuImgException;
import org.apache.cloudstack.utils.qemu.QemuImgFile; import org.apache.cloudstack.utils.qemu.QemuImgFile;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.libvirt.LibvirtException; import org.libvirt.LibvirtException;
@ -91,6 +92,22 @@ public final class LibvirtGetVolumesOnStorageCommandWrapper extends CommandWrapp
if (disk.getQemuEncryptFormat() != null) { if (disk.getQemuEncryptFormat() != null) {
volumeOnStorageTO.setQemuEncryptFormat(disk.getQemuEncryptFormat().toString()); volumeOnStorageTO.setQemuEncryptFormat(disk.getQemuEncryptFormat().toString());
} }
String fileFormat = info.get(QemuImg.FILE_FORMAT);
if (StringUtils.isNotBlank(fileFormat) && !fileFormat.equalsIgnoreCase(disk.getFormat().toString())) {
return new GetVolumesOnStorageAnswer(command, false, String.format("The file format is %s, but expected to be %s", fileFormat, disk.getFormat()));
}
addDetailsToVolumeOnStorageTO(volumeOnStorageTO, info, storagePool, disk);
volumes.add(volumeOnStorageTO);
}
return new GetVolumesOnStorageAnswer(command, volumes);
}
private void addDetailsToVolumeOnStorageTO(VolumeOnStorageTO volumeOnStorageTO, final Map<String, String> info, final KVMStoragePool storagePool, final KVMPhysicalDisk disk) {
if (MapUtils.isEmpty(info)) {
return;
}
String backingFilePath = info.get(QemuImg.BACKING_FILE); String backingFilePath = info.get(QemuImg.BACKING_FILE);
if (StringUtils.isNotBlank(backingFilePath)) { if (StringUtils.isNotBlank(backingFilePath)) {
volumeOnStorageTO.addDetail(VolumeOnStorageTO.Detail.BACKING_FILE, backingFilePath); volumeOnStorageTO.addDetail(VolumeOnStorageTO.Detail.BACKING_FILE, backingFilePath);
@ -105,9 +122,6 @@ public final class LibvirtGetVolumesOnStorageCommandWrapper extends CommandWrapp
} }
String fileFormat = info.get(QemuImg.FILE_FORMAT); String fileFormat = info.get(QemuImg.FILE_FORMAT);
if (StringUtils.isNotBlank(fileFormat)) { if (StringUtils.isNotBlank(fileFormat)) {
if (!fileFormat.equalsIgnoreCase(disk.getFormat().toString())) {
return new GetVolumesOnStorageAnswer(command, false, String.format("The file format is %s, but expected to be %s", fileFormat, disk.getFormat()));
}
volumeOnStorageTO.addDetail(VolumeOnStorageTO.Detail.FILE_FORMAT, fileFormat); volumeOnStorageTO.addDetail(VolumeOnStorageTO.Detail.FILE_FORMAT, fileFormat);
} }
String encrypted = info.get(QemuImg.ENCRYPTED); String encrypted = info.get(QemuImg.ENCRYPTED);
@ -116,10 +130,6 @@ public final class LibvirtGetVolumesOnStorageCommandWrapper extends CommandWrapp
} }
Boolean isLocked = isDiskFileLocked(storagePool, disk); Boolean isLocked = isDiskFileLocked(storagePool, disk);
volumeOnStorageTO.addDetail(VolumeOnStorageTO.Detail.IS_LOCKED, String.valueOf(isLocked)); volumeOnStorageTO.addDetail(VolumeOnStorageTO.Detail.IS_LOCKED, String.valueOf(isLocked));
volumes.add(volumeOnStorageTO);
}
return new GetVolumesOnStorageAnswer(command, volumes);
} }
private GetVolumesOnStorageAnswer addAllVolumes(final GetVolumesOnStorageCommand command, final KVMStoragePool storagePool, String keyword) { private GetVolumesOnStorageAnswer addAllVolumes(final GetVolumesOnStorageCommand command, final KVMStoragePool storagePool, String keyword) {
@ -134,11 +144,21 @@ public final class LibvirtGetVolumesOnStorageCommandWrapper extends CommandWrapp
if (!isDiskFormatSupported(disk)) { if (!isDiskFormatSupported(disk)) {
continue; continue;
} }
Map<String, String> info = getDiskFileInfo(storagePool, disk, true);
if (info == null) {
continue;
}
VolumeOnStorageTO volumeOnStorageTO = new VolumeOnStorageTO(Hypervisor.HypervisorType.KVM, disk.getName(), disk.getName(), disk.getPath(), VolumeOnStorageTO volumeOnStorageTO = new VolumeOnStorageTO(Hypervisor.HypervisorType.KVM, disk.getName(), disk.getName(), disk.getPath(),
disk.getFormat().toString(), disk.getSize(), disk.getVirtualSize()); disk.getFormat().toString(), disk.getSize(), disk.getVirtualSize());
if (disk.getQemuEncryptFormat() != null) { if (disk.getQemuEncryptFormat() != null) {
volumeOnStorageTO.setQemuEncryptFormat(disk.getQemuEncryptFormat().toString()); volumeOnStorageTO.setQemuEncryptFormat(disk.getQemuEncryptFormat().toString());
} }
String fileFormat = info.get(QemuImg.FILE_FORMAT);
if (StringUtils.isNotBlank(fileFormat) && !fileFormat.equalsIgnoreCase(disk.getFormat().toString())) {
continue;
}
addDetailsToVolumeOnStorageTO(volumeOnStorageTO, info, storagePool, disk);
volumes.add(volumeOnStorageTO); volumes.add(volumeOnStorageTO);
} }
return new GetVolumesOnStorageAnswer(command, volumes); return new GetVolumesOnStorageAnswer(command, volumes);

View File

@ -43,7 +43,7 @@ public final class LibvirtReadyCommandWrapper extends CommandWrapper<ReadyComman
public Answer execute(final ReadyCommand command, final LibvirtComputingResource libvirtComputingResource) { public Answer execute(final ReadyCommand command, final LibvirtComputingResource libvirtComputingResource) {
Map<String, String> hostDetails = new HashMap<String, String>(); Map<String, String> hostDetails = new HashMap<String, String>();
if (hostSupportsUefi(libvirtComputingResource.isUbuntuHost()) && libvirtComputingResource.isUefiPropertiesFileLoaded()) { if (hostSupportsUefi(libvirtComputingResource.isUbuntuOrDebianHost()) && libvirtComputingResource.isUefiPropertiesFileLoaded()) {
hostDetails.put(Host.HOST_UEFI_ENABLE, Boolean.TRUE.toString()); hostDetails.put(Host.HOST_UEFI_ENABLE, Boolean.TRUE.toString());
} }
@ -58,10 +58,10 @@ public final class LibvirtReadyCommandWrapper extends CommandWrapper<ReadyComman
return new ReadyAnswer(command, hostDetails); return new ReadyAnswer(command, hostDetails);
} }
private boolean hostSupportsUefi(boolean isUbuntuHost) { private boolean hostSupportsUefi(boolean isUbuntuOrDebianHost) {
int timeout = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.AGENT_SCRIPT_TIMEOUT) * 1000; // Get property value & convert to milliseconds int timeout = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.AGENT_SCRIPT_TIMEOUT) * 1000; // Get property value & convert to milliseconds
int result; int result;
if (isUbuntuHost) { if (isUbuntuOrDebianHost) {
logger.debug("Running command : [dpkg -l ovmf] with timeout : " + timeout + " ms"); logger.debug("Running command : [dpkg -l ovmf] with timeout : " + timeout + " ms");
result = Script.executeCommandForExitValue(timeout, Script.getExecutableAbsolutePath("dpkg"), "-l", "ovmf"); result = Script.executeCommandForExitValue(timeout, Script.getExecutableAbsolutePath("dpkg"), "-l", "ovmf");
} else { } else {

View File

@ -25,7 +25,6 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
import com.cloud.hypervisor.kvm.storage.ScaleIOStorageAdaptor; import com.cloud.hypervisor.kvm.storage.ScaleIOStorageAdaptor;
import org.apache.cloudstack.utils.cryptsetup.KeyFile; import org.apache.cloudstack.utils.cryptsetup.KeyFile;
@ -33,7 +32,6 @@ import org.apache.cloudstack.utils.qemu.QemuImageOptions;
import org.apache.cloudstack.utils.qemu.QemuImg; import org.apache.cloudstack.utils.qemu.QemuImg;
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import org.apache.cloudstack.utils.qemu.QemuImgException; import org.apache.cloudstack.utils.qemu.QemuImgException;
import org.apache.cloudstack.utils.qemu.QemuImgFile;
import org.apache.cloudstack.utils.qemu.QemuObject; import org.apache.cloudstack.utils.qemu.QemuObject;
import org.libvirt.Connect; import org.libvirt.Connect;
import org.libvirt.Domain; import org.libvirt.Domain;
@ -100,7 +98,7 @@ public final class LibvirtResizeVolumeCommandWrapper extends CommandWrapper<Resi
newSize = ScaleIOStorageAdaptor.getUsableBytesFromRawBytes(newSize); newSize = ScaleIOStorageAdaptor.getUsableBytesFromRawBytes(newSize);
} else if (spool.getType().equals(StoragePoolType.PowerFlex)) { } else if (spool.getType().equals(StoragePoolType.PowerFlex)) {
// PowerFlex RAW/LUKS is already resized, we just notify the domain based on new size (considering LUKS overhead) // PowerFlex RAW/LUKS is already resized, we just notify the domain based on new size (considering LUKS overhead)
newSize = getVirtualSizeFromFile(path); newSize = KVMPhysicalDisk.getVirtualSizeFromFile(path);
} }
if (pool.getType() != StoragePoolType.RBD && pool.getType() != StoragePoolType.Linstor && pool.getType() != StoragePoolType.PowerFlex) { if (pool.getType() != StoragePoolType.RBD && pool.getType() != StoragePoolType.Linstor && pool.getType() != StoragePoolType.PowerFlex) {
@ -214,21 +212,6 @@ public final class LibvirtResizeVolumeCommandWrapper extends CommandWrapper<Resi
} }
} }
private long getVirtualSizeFromFile(String path) {
try {
QemuImg qemu = new QemuImg(0);
QemuImgFile qemuFile = new QemuImgFile(path);
Map<String, String> info = qemu.info(qemuFile);
if (info.containsKey(QemuImg.VIRTUAL_SIZE)) {
return Long.parseLong(info.get(QemuImg.VIRTUAL_SIZE));
} else {
throw new CloudRuntimeException("Unable to determine virtual size of volume at path " + path);
}
} catch (QemuImgException | LibvirtException ex) {
throw new CloudRuntimeException("Error when inspecting volume at path " + path, ex);
}
}
private Answer handleMultipathSCSIResize(ResizeVolumeCommand command, KVMStoragePool pool) { private Answer handleMultipathSCSIResize(ResizeVolumeCommand command, KVMStoragePool pool) {
((MultipathSCSIPool)pool).resize(command.getPath(), command.getInstanceName(), command.getNewSize()); ((MultipathSCSIPool)pool).resize(command.getPath(), command.getInstanceName(), command.getNewSize());
return new ResizeVolumeAnswer(command, true, ""); return new ResizeVolumeAnswer(command, true, "");

View File

@ -62,6 +62,7 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
String restoreVolumeUuid = command.getRestoreVolumeUUID(); String restoreVolumeUuid = command.getRestoreVolumeUUID();
String newVolumeId = null; String newVolumeId = null;
try {
if (Objects.isNull(vmExists)) { if (Objects.isNull(vmExists)) {
String volumePath = volumePaths.get(0); String volumePath = volumePaths.get(0);
int lastIndex = volumePath.lastIndexOf("/"); int lastIndex = volumePath.lastIndexOf("/");
@ -73,6 +74,14 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
} else { } else {
restoreVolumesOfDestroyedVMs(volumePaths, vmName, backupPath, backupRepoType, backupRepoAddress, mountOptions); restoreVolumesOfDestroyedVMs(volumePaths, vmName, backupPath, backupRepoType, backupRepoAddress, mountOptions);
} }
} catch (CloudRuntimeException e) {
String errorMessage = "Failed to restore backup for VM: " + vmName + ".";
if (e.getMessage() != null && !e.getMessage().isEmpty()) {
errorMessage += " Details: " + e.getMessage();
}
logger.error(errorMessage);
return new BackupAnswer(command, false, errorMessage);
}
return new BackupAnswer(command, true, newVolumeId); return new BackupAnswer(command, true, newVolumeId);
} }
@ -86,10 +95,8 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
String volumePath = volumePaths.get(idx); String volumePath = volumePaths.get(idx);
Pair<String, String> bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, null); Pair<String, String> bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, null);
diskType = "datadisk"; diskType = "datadisk";
try { if (!replaceVolumeWithBackup(volumePath, bkpPathAndVolUuid.first())) {
replaceVolumeWithBackup(volumePath, bkpPathAndVolUuid.first()); throw new CloudRuntimeException(String.format("Unable to restore backup for volume [%s].", bkpPathAndVolUuid.second()));
} catch (IOException e) {
throw new CloudRuntimeException(String.format("Unable to revert backup for volume [%s] due to [%s].", bkpPathAndVolUuid.second(), e.getMessage()), e);
} }
} }
} finally { } finally {
@ -108,10 +115,8 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
String volumePath = volumePaths.get(i); String volumePath = volumePaths.get(i);
Pair<String, String> bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, null); Pair<String, String> bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, null);
diskType = "datadisk"; diskType = "datadisk";
try { if (!replaceVolumeWithBackup(volumePath, bkpPathAndVolUuid.first())) {
replaceVolumeWithBackup(volumePath, bkpPathAndVolUuid.first()); throw new CloudRuntimeException(String.format("Unable to restore backup for volume [%s].", bkpPathAndVolUuid.second()));
} catch (IOException e) {
throw new CloudRuntimeException(String.format("Unable to revert backup for volume [%s] due to [%s].", bkpPathAndVolUuid.second(), e.getMessage()), e);
} }
} }
} finally { } finally {
@ -126,16 +131,14 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
Pair<String, String> bkpPathAndVolUuid; Pair<String, String> bkpPathAndVolUuid;
try { try {
bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, volumeUUID); bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, volumeUUID);
try { if (!replaceVolumeWithBackup(volumePath, bkpPathAndVolUuid.first())) {
replaceVolumeWithBackup(volumePath, bkpPathAndVolUuid.first()); throw new CloudRuntimeException(String.format("Unable to restore backup for volume [%s].", bkpPathAndVolUuid.second()));
}
if (VirtualMachine.State.Running.equals(vmNameAndState.second())) { if (VirtualMachine.State.Running.equals(vmNameAndState.second())) {
if (!attachVolumeToVm(vmNameAndState.first(), volumePath)) { if (!attachVolumeToVm(vmNameAndState.first(), volumePath)) {
throw new CloudRuntimeException(String.format("Failed to attach volume to VM: %s", vmNameAndState.first())); throw new CloudRuntimeException(String.format("Failed to attach volume to VM: %s", vmNameAndState.first()));
} }
} }
} catch (IOException e) {
throw new CloudRuntimeException(String.format("Unable to revert backup for volume [%s] due to [%s].", bkpPathAndVolUuid.second(), e.getMessage()), e);
}
} catch (Exception e) { } catch (Exception e) {
throw new CloudRuntimeException("Failed to restore volume", e); throw new CloudRuntimeException("Failed to restore volume", e);
} finally { } finally {
@ -194,8 +197,9 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
return new Pair<>(bkpPath, volUuid); return new Pair<>(bkpPath, volUuid);
} }
private void replaceVolumeWithBackup(String volumePath, String backupPath) throws IOException { private boolean replaceVolumeWithBackup(String volumePath, String backupPath) {
Script.runSimpleBashScript(String.format(RSYNC_COMMAND, backupPath, volumePath)); int exitValue = Script.runSimpleBashScriptForExitValue(String.format(RSYNC_COMMAND, backupPath, volumePath));
return exitValue == 0;
} }
private boolean attachVolumeToVm(String vmName, String volumePath) { private boolean attachVolumeToVm(String vmName, String volumePath) {

View File

@ -16,10 +16,17 @@
// under the License. // under the License.
package com.cloud.hypervisor.kvm.storage; package com.cloud.hypervisor.kvm.storage;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.storage.formatinspector.Qcow2Inspector;
import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
import org.apache.cloudstack.utils.qemu.QemuImg;
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import org.apache.cloudstack.utils.qemu.QemuImgException;
import org.apache.cloudstack.utils.qemu.QemuImgFile;
import org.apache.cloudstack.utils.qemu.QemuObject; import org.apache.cloudstack.utils.qemu.QemuObject;
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils; import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.libvirt.LibvirtException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -83,6 +90,31 @@ public class KVMPhysicalDisk {
return hostIp; return hostIp;
} }
public static long getVirtualSizeFromFile(String path) {
try {
QemuImg qemu = new QemuImg(0);
QemuImgFile qemuFile = new QemuImgFile(path);
Map<String, String> info = qemu.info(qemuFile);
if (info.containsKey(QemuImg.VIRTUAL_SIZE)) {
return Long.parseLong(info.get(QemuImg.VIRTUAL_SIZE));
} else {
throw new CloudRuntimeException("Unable to determine virtual size of volume at path " + path);
}
} catch (QemuImgException | LibvirtException ex) {
throw new CloudRuntimeException("Error when inspecting volume at path " + path, ex);
}
}
public static void checkQcow2File(String path) {
if (ImageStoreUtil.isCorrectExtension(path, "qcow2")) {
try {
Qcow2Inspector.validateQcow2File(path);
} catch (RuntimeException e) {
throw new CloudRuntimeException("The volume file at path " + path + " is not a valid QCOW2. Error: " + e.getMessage());
}
}
}
private PhysicalDiskFormat format; private PhysicalDiskFormat format;
private long size; private long size;
private long virtualSize; private long virtualSize;

View File

@ -236,6 +236,12 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
return false; return false;
} }
@Override
public boolean isResourceDomainAdmin(Long accountId) {
// TODO Auto-generated method stub
return false;
}
@Override @Override
public boolean isNormalUser(long accountId) { public boolean isNormalUser(long accountId) {
// TODO Auto-generated method stub // TODO Auto-generated method stub

View File

@ -136,13 +136,18 @@ public class StorageVmSharedFSLifeCycle implements SharedFSLifeCycle {
return fsVmConfig; return fsVmConfig;
} }
private String getStorageVmName(String fileShareName) { private String getStorageVmPrefix(String fileShareName) {
String prefix = String.format("%s-%s", SharedFSVmNamePrefix, fileShareName); String prefix = String.format("%s-%s", SharedFSVmNamePrefix, fileShareName);
String suffix = Long.toHexString(System.currentTimeMillis());
if (!NetUtils.verifyDomainNameLabel(prefix, true)) { if (!NetUtils.verifyDomainNameLabel(prefix, true)) {
prefix = prefix.replaceAll("[^a-zA-Z0-9-]", ""); prefix = prefix.replaceAll("[^a-zA-Z0-9-]", "");
} }
return prefix;
}
private String getStorageVmName(String fileShareName) {
String prefix = getStorageVmPrefix(fileShareName);
String suffix = Long.toHexString(System.currentTimeMillis());
int nameLength = prefix.length() + suffix.length() + SharedFSVmNamePrefix.length(); int nameLength = prefix.length() + suffix.length() + SharedFSVmNamePrefix.length();
if (nameLength > 63) { if (nameLength > 63) {
int prefixLength = prefix.length() - (nameLength - 63); int prefixLength = prefix.length() - (nameLength - 63);
@ -232,8 +237,18 @@ public class StorageVmSharedFSLifeCycle implements SharedFSLifeCycle {
Account owner = accountMgr.getActiveAccountById(sharedFS.getAccountId()); Account owner = accountMgr.getActiveAccountById(sharedFS.getAccountId());
UserVm vm = deploySharedFSVM(sharedFS.getDataCenterId(), owner, List.of(networkId), sharedFS.getName(), sharedFS.getServiceOfferingId(), diskOfferingId, sharedFS.getFsType(), size, minIops, maxIops); UserVm vm = deploySharedFSVM(sharedFS.getDataCenterId(), owner, List.of(networkId), sharedFS.getName(), sharedFS.getServiceOfferingId(), diskOfferingId, sharedFS.getFsType(), size, minIops, maxIops);
List<VolumeVO> volumes = volumeDao.findByInstanceAndType(vm.getId(), Volume.Type.DATADISK); List<VolumeVO> volumes = volumeDao.findByInstance(vm.getId());
return new Pair<>(volumes.get(0).getId(), vm.getId()); VolumeVO dataVol = null;
for (VolumeVO vol : volumes) {
String volumeName = vol.getName();
String updatedVolumeName = SharedFSVmNamePrefix + "-" + volumeName;
vol.setName(updatedVolumeName);
volumeDao.update(vol.getId(), vol);
if (vol.getVolumeType() == Volume.Type.DATADISK) {
dataVol = vol;
}
}
return new Pair<>(dataVol.getId(), vm.getId());
} }
@Override @Override

View File

@ -259,9 +259,14 @@ public class StorageVmSharedFSLifeCycleTest {
anyMap(), isNull(), isNull(), isNull(), isNull(), anyMap(), isNull(), isNull(), isNull(), isNull(),
anyBoolean(), anyString(), isNull(), isNull(), isNull())).thenReturn(vm); anyBoolean(), anyString(), isNull(), isNull(), isNull())).thenReturn(vm);
VolumeVO volume = mock(VolumeVO.class); VolumeVO rootVol = mock(VolumeVO.class);
when(volume.getId()).thenReturn(s_volumeId); when(rootVol.getVolumeType()).thenReturn(Volume.Type.ROOT);
when(volumeDao.findByInstanceAndType(s_vmId, Volume.Type.DATADISK)).thenReturn(List.of(volume)); when(rootVol.getName()).thenReturn("ROOT-1");
VolumeVO dataVol = mock(VolumeVO.class);
when(dataVol.getId()).thenReturn(s_volumeId);
when(dataVol.getName()).thenReturn("DATA-1");
when(dataVol.getVolumeType()).thenReturn(Volume.Type.DATADISK);
when(volumeDao.findByInstance(s_vmId)).thenReturn(List.of(rootVol, dataVol));
Pair<Long, Long> result = lifeCycle.deploySharedFS(sharedFS, s_networkId, s_diskOfferingId, s_size, s_minIops, s_maxIops); Pair<Long, Long> result = lifeCycle.deploySharedFS(sharedFS, s_networkId, s_diskOfferingId, s_size, s_minIops, s_maxIops);
Assert.assertEquals(Optional.ofNullable(result.first()), Optional.ofNullable(s_volumeId)); Assert.assertEquals(Optional.ofNullable(result.first()), Optional.ofNullable(s_volumeId));

View File

@ -5,6 +5,12 @@ All notable changes to Linstor CloudStack plugin will be documented in this file
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2025-07-01]
### Fixed
- Regression in 4.19.3 and 4.21.0 with templates from snapshots
## [2025-05-07] ## [2025-05-07]
### Added ### Added

View File

@ -622,7 +622,7 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
try { try {
templateProps.load(new FileInputStream(propFile.toFile())); templateProps.load(new FileInputStream(propFile.toFile()));
String desc = templateProps.getProperty("description"); String desc = templateProps.getProperty("description");
if (desc.startsWith("SystemVM Template")) { if (desc != null && desc.startsWith("SystemVM Template")) {
return true; return true;
} }
} catch (IOException e) { } catch (IOException e) {

View File

@ -74,12 +74,14 @@ import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePool;
import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Volume; import com.cloud.storage.Volume;
import com.cloud.storage.VolumeDetailVO; import com.cloud.storage.VolumeDetailVO;
import com.cloud.storage.VolumeVO; import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.SnapshotDetailsDao; import com.cloud.storage.dao.SnapshotDetailsDao;
import com.cloud.storage.dao.SnapshotDetailsVO; import com.cloud.storage.dao.SnapshotDetailsVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.dao.VolumeDetailsDao; import com.cloud.storage.dao.VolumeDetailsDao;
@ -133,6 +135,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
ConfigurationDao _configDao; ConfigurationDao _configDao;
@Inject @Inject
private HostDao _hostDao; private HostDao _hostDao;
@Inject private VMTemplateDao _vmTemplateDao;
private long volumeStatsLastUpdate = 0L; private long volumeStatsLastUpdate = 0L;
private final Map<String, Pair<Long, Long>> volumeStats = new HashMap<>(); private final Map<String, Pair<Long, Long>> volumeStats = new HashMap<>();
@ -670,8 +673,15 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
storagePoolVO.getId(), csCloneId, null); storagePoolVO.getId(), csCloneId, null);
if (tmplPoolRef != null) { if (tmplPoolRef != null) {
final String templateRscName = LinstorUtil.RSC_PREFIX + tmplPoolRef.getLocalDownloadPath(); final String templateRscName;
if (tmplPoolRef.getLocalDownloadPath() == null) {
VMTemplateVO vmTemplateVO = _vmTemplateDao.findById(tmplPoolRef.getTemplateId());
templateRscName = LinstorUtil.RSC_PREFIX + vmTemplateVO.getUuid();
} else {
templateRscName = LinstorUtil.RSC_PREFIX + tmplPoolRef.getLocalDownloadPath();
}
final String rscName = LinstorUtil.RSC_PREFIX + volumeInfo.getUuid(); final String rscName = LinstorUtil.RSC_PREFIX + volumeInfo.getUuid();
final DevelopersApi linstorApi = LinstorUtil.getLinstorAPI(storagePoolVO.getHostAddress()); final DevelopersApi linstorApi = LinstorUtil.getLinstorAPI(storagePoolVO.getHostAddress());
try { try {

View File

@ -1279,13 +1279,13 @@ public class ScaleIOPrimaryDataStoreDriver implements PrimaryDataStoreDriver {
} }
org.apache.cloudstack.storage.datastore.api.Volume scaleIOVolume = client.getVolume(scaleIOVolumeId); org.apache.cloudstack.storage.datastore.api.Volume scaleIOVolume = client.getVolume(scaleIOVolumeId);
long newSizeInGB = newSizeInBytes / (1024 * 1024 * 1024); double newSizeInGB = newSizeInBytes / (1024.0 * 1024 * 1024);
long newSizeIn8gbBoundary = (long) (Math.ceil(newSizeInGB / 8.0) * 8.0); long newSizeIn8GBBoundary = (long) (Math.ceil(newSizeInGB / 8.0) * 8.0);
if (scaleIOVolume.getSizeInKb() == newSizeIn8gbBoundary << 20) { if (scaleIOVolume.getSizeInKb() == newSizeIn8GBBoundary << 20) {
logger.debug("No resize necessary at API"); logger.debug("No resize necessary at API");
} else { } else {
scaleIOVolume = client.resizeVolume(scaleIOVolumeId, (int) newSizeIn8gbBoundary); scaleIOVolume = client.resizeVolume(scaleIOVolumeId, (int) newSizeIn8GBBoundary);
if (scaleIOVolume == null) { if (scaleIOVolume == null) {
throw new CloudRuntimeException("Failed to resize volume: " + volumeInfo.getName()); throw new CloudRuntimeException("Failed to resize volume: " + volumeInfo.getName());
} }
@ -1411,12 +1411,12 @@ public class ScaleIOPrimaryDataStoreDriver implements PrimaryDataStoreDriver {
@Override @Override
public long getVolumeSizeRequiredOnPool(long volumeSize, Long templateSize, boolean isEncryptionRequired) { public long getVolumeSizeRequiredOnPool(long volumeSize, Long templateSize, boolean isEncryptionRequired) {
long newSizeInGB = volumeSize / (1024 * 1024 * 1024); double newSizeInGB = volumeSize / (1024.0 * 1024 * 1024);
if (templateSize != null && isEncryptionRequired && needsExpansionForEncryptionHeader(templateSize, volumeSize)) { if (templateSize != null && isEncryptionRequired && needsExpansionForEncryptionHeader(templateSize, volumeSize)) {
newSizeInGB = (volumeSize + (1<<30)) / (1024 * 1024 * 1024); newSizeInGB = (volumeSize + (1<<30)) / (1024.0 * 1024 * 1024);
} }
long newSizeIn8gbBoundary = (long) (Math.ceil(newSizeInGB / 8.0) * 8.0); long newSizeIn8GBBoundary = (long) (Math.ceil(newSizeInGB / 8.0) * 8.0);
return newSizeIn8gbBoundary * (1024 * 1024 * 1024); return newSizeIn8GBBoundary * (1024 * 1024 * 1024);
} }
@Override @Override

View File

@ -555,6 +555,18 @@ public class ScaleIOPrimaryDataStoreDriverTest {
@Test @Test
public void testGetVolumeSizeRequiredOnPool() { public void testGetVolumeSizeRequiredOnPool() {
Assert.assertEquals(8L * (1024 * 1024 * 1024),
scaleIOPrimaryDataStoreDriver.getVolumeSizeRequiredOnPool(
52428800,
null,
false));
Assert.assertEquals(8L * (1024 * 1024 * 1024),
scaleIOPrimaryDataStoreDriver.getVolumeSizeRequiredOnPool(
52428800,
52428800L,
true));
Assert.assertEquals(16L * (1024 * 1024 * 1024), Assert.assertEquals(16L * (1024 * 1024 * 1024),
scaleIOPrimaryDataStoreDriver.getVolumeSizeRequiredOnPool( scaleIOPrimaryDataStoreDriver.getVolumeSizeRequiredOnPool(
10L * (1024 * 1024 * 1024), 10L * (1024 * 1024 * 1024),

View File

@ -150,6 +150,9 @@ public class StorPoolStorageAdaptor implements StorageAdaptor {
} }
public static String getVolumeNameFromPath(final String volumeUuid, boolean tildeNeeded) { public static String getVolumeNameFromPath(final String volumeUuid, boolean tildeNeeded) {
if (volumeUuid == null) {
return null;
}
if (volumeUuid.startsWith("/dev/storpool/")) { if (volumeUuid.startsWith("/dev/storpool/")) {
return volumeUuid.split("/")[3]; return volumeUuid.split("/")[3];
} else if (volumeUuid.startsWith("/dev/storpool-byid/")) { } else if (volumeUuid.startsWith("/dev/storpool-byid/")) {

View File

@ -143,7 +143,8 @@ public class LdapListUsersCmd extends BaseListCmd {
// now filter and annotate // now filter and annotate
ldapResponses = applyUserFilter(ldapResponses); ldapResponses = applyUserFilter(ldapResponses);
} catch (final NoLdapUserMatchingQueryException ex) { } catch (final NoLdapUserMatchingQueryException ex) {
// ok, we'll make do with the empty list ldapResponses = new ArrayList<LdapUserResponse>(); logger.debug(ex.getMessage());
// ok, we'll make do with the empty list
} finally { } finally {
response.setResponses(ldapResponses); response.setResponses(ldapResponses);
response.setResponseName(getCommandName()); response.setResponseName(getCommandName());

View File

@ -45,6 +45,8 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
@Inject @Inject
private AccountManager _accountManager; private AccountManager _accountManager;
private static final String LDAP_READ_TIMED_OUT_MESSAGE = "LDAP response read timed out";
public LdapAuthenticator() { public LdapAuthenticator() {
super(); super();
} }
@ -174,12 +176,21 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
} }
} catch (NoLdapUserMatchingQueryException e) { } catch (NoLdapUserMatchingQueryException e) {
logger.debug(e.getMessage()); logger.debug(e.getMessage());
disableUserInCloudStack(userAccount); processLdapUserErrorMessage(userAccount, e.getMessage(), rc);
} }
return rc; return rc;
} }
private void processLdapUserErrorMessage(UserAccount user, String errorMessage, Pair<Boolean, ActionOnFailedAuthentication> rc) {
if (StringUtils.isNotEmpty(errorMessage) && errorMessage.contains(LDAP_READ_TIMED_OUT_MESSAGE) && !rc.first()) {
rc.second(ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
} else {
// no user in ldap ==>> disable user in cloudstack
disableUserInCloudStack(user);
}
}
private void tracelist(String msg, List<String> listToTrace) { private void tracelist(String msg, List<String> listToTrace) {
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {
StringBuilder logMsg = new StringBuilder(); StringBuilder logMsg = new StringBuilder();
@ -229,8 +240,7 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
processLdapUser(password, domainId, user, rc, ldapUser, accountType); processLdapUser(password, domainId, user, rc, ldapUser, accountType);
} catch (NoLdapUserMatchingQueryException e) { } catch (NoLdapUserMatchingQueryException e) {
logger.debug(e.getMessage()); logger.debug(e.getMessage());
// no user in ldap ==>> disable user in cloudstack processLdapUserErrorMessage(user, e.getMessage(), rc);
disableUserInCloudStack(user);
} }
return rc; return rc;
} }
@ -264,6 +274,7 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
*/ */
Pair<Boolean, ActionOnFailedAuthentication> authenticate(String username, String password, Long domainId, UserAccount user) { Pair<Boolean, ActionOnFailedAuthentication> authenticate(String username, String password, Long domainId, UserAccount user) {
boolean result = false; boolean result = false;
boolean timedOut = false;
if (user != null ) { if (user != null ) {
try { try {
@ -275,13 +286,16 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
} }
} catch (NoLdapUserMatchingQueryException e) { } catch (NoLdapUserMatchingQueryException e) {
logger.debug(e.getMessage()); logger.debug(e.getMessage());
if (e.getMessage().contains(LDAP_READ_TIMED_OUT_MESSAGE)) {
timedOut = true;
} }
} }
return processResultAndAction(user, result); }
return processResultAndAction(user, result, timedOut);
} }
private Pair<Boolean, ActionOnFailedAuthentication> processResultAndAction(UserAccount user, boolean result) { private Pair<Boolean, ActionOnFailedAuthentication> processResultAndAction(UserAccount user, boolean result, boolean timedOut) {
return (!result && user != null) ? return (!result && (user != null || timedOut)) ?
new Pair<Boolean, ActionOnFailedAuthentication>(result, ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT): new Pair<Boolean, ActionOnFailedAuthentication>(result, ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT):
new Pair<Boolean, ActionOnFailedAuthentication>(result, null); new Pair<Boolean, ActionOnFailedAuthentication>(result, null);
} }

View File

@ -303,8 +303,8 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(null)).getUser(escapedUsername, context, domainId); return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(null)).getUser(escapedUsername, context, domainId);
} catch (NamingException | IOException e) { } catch (NamingException | IOException e) {
logger.debug("ldap Exception: ",e); logger.debug("LDAP Exception: ", e);
throw new NoLdapUserMatchingQueryException("No Ldap User found for username: "+username); throw new NoLdapUserMatchingQueryException("Unable to find LDAP User for username: " + username + ", due to " + e.getMessage());
} finally { } finally {
closeContext(context); closeContext(context);
} }
@ -324,8 +324,8 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
LdapUserManager userManagerFactory = _ldapUserManagerFactory.getInstance(ldapProvider); LdapUserManager userManagerFactory = _ldapUserManagerFactory.getInstance(ldapProvider);
return userManagerFactory.getUser(escapedUsername, type, name, context, domainId); return userManagerFactory.getUser(escapedUsername, type, name, context, domainId);
} catch (NamingException | IOException e) { } catch (NamingException | IOException e) {
logger.debug("ldap Exception: ",e); logger.debug("LDAP Exception: ", e);
throw new NoLdapUserMatchingQueryException("No Ldap User found for username: "+username + " in group: " + name + " of type: " + type); throw new NoLdapUserMatchingQueryException("Unable to find LDAP User for username: " + username + " in group: " + name + " of type: " + type + ", due to " + e.getMessage());
} finally { } finally {
closeContext(context); closeContext(context);
} }
@ -338,7 +338,7 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
context = _ldapContextFactory.createBindContext(domainId); context = _ldapContextFactory.createBindContext(domainId);
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(domainId)).getUsers(context, domainId); return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(domainId)).getUsers(context, domainId);
} catch (NamingException | IOException e) { } catch (NamingException | IOException e) {
logger.debug("ldap Exception: ",e); logger.debug("LDAP Exception: ", e);
throw new NoLdapUserMatchingQueryException("*"); throw new NoLdapUserMatchingQueryException("*");
} finally { } finally {
closeContext(context); closeContext(context);
@ -352,7 +352,7 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
context = _ldapContextFactory.createBindContext(domainId); context = _ldapContextFactory.createBindContext(domainId);
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(domainId)).getUsersInGroup(groupName, context, domainId); return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(domainId)).getUsersInGroup(groupName, context, domainId);
} catch (NamingException | IOException e) { } catch (NamingException | IOException e) {
logger.debug("ldap NamingException: ",e); logger.debug("LDAP Exception: ", e);
throw new NoLdapUserMatchingQueryException("groupName=" + groupName); throw new NoLdapUserMatchingQueryException("groupName=" + groupName);
} finally { } finally {
closeContext(context); closeContext(context);
@ -390,7 +390,7 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username); final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username);
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(null)).getUsers("*" + escapedUsername + "*", context, null); return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(null)).getUsers("*" + escapedUsername + "*", context, null);
} catch (NamingException | IOException e) { } catch (NamingException | IOException e) {
logger.debug("ldap Exception: ",e); logger.debug("LDAP Exception: ",e);
throw new NoLdapUserMatchingQueryException(username); throw new NoLdapUserMatchingQueryException(username);
} finally { } finally {
closeContext(context); closeContext(context);

View File

@ -482,6 +482,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa
isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST)); isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST));
isoResponse.setCreated(iso.getCreatedOnStore()); isoResponse.setCreated(iso.getCreatedOnStore());
isoResponse.setDynamicallyScalable(iso.isDynamicallyScalable()); isoResponse.setDynamicallyScalable(iso.isDynamicallyScalable());
isoResponse.setFormat(iso.getFormat());
if (iso.getTemplateType() == TemplateType.PERHOST) { if (iso.getTemplateType() == TemplateType.PERHOST) {
// for TemplateManager.XS_TOOLS_ISO and TemplateManager.VMWARE_TOOLS_ISO, we didn't download, but is ready to use. // for TemplateManager.XS_TOOLS_ISO and TemplateManager.VMWARE_TOOLS_ISO, we didn't download, but is ready to use.
isoResponse.setReady(true); isoResponse.setReady(true);
@ -581,10 +582,14 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa
isoResponse.setZoneName(iso.getDataCenterName()); isoResponse.setZoneName(iso.getDataCenterName());
} }
Long isoSize = iso.getSize(); long isoSize = iso.getSize();
if (isoSize > 0) { if (isoSize > 0) {
isoResponse.setSize(isoSize); isoResponse.setSize(isoSize);
} }
long isoPhysicalSize = iso.getPhysicalSize();
if (isoPhysicalSize > 0) {
isoResponse.setPhysicalSize(isoPhysicalSize);
}
if (iso.getUserDataId() != null) { if (iso.getUserDataId() != null) {
isoResponse.setUserDataId(iso.getUserDataUUid()); isoResponse.setUserDataId(iso.getUserDataUUid());

View File

@ -50,12 +50,7 @@ import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import com.cloud.network.dao.NetrisProviderDao;
import com.cloud.network.element.NetrisProviderVO;
import com.cloud.network.netris.NetrisService;
import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.RoleType;
import com.cloud.gpu.VgpuProfileVO;
import com.cloud.gpu.dao.VgpuProfileDao;
import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupService; import org.apache.cloudstack.affinity.AffinityGroupService;
@ -207,6 +202,8 @@ import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.ResourceUnavailableException;
import com.cloud.gpu.GPU; import com.cloud.gpu.GPU;
import com.cloud.gpu.VgpuProfileVO;
import com.cloud.gpu.dao.VgpuProfileDao;
import com.cloud.host.HostTagVO; import com.cloud.host.HostTagVO;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
@ -230,10 +227,12 @@ import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.TrafficType; import com.cloud.network.Networks.TrafficType;
import com.cloud.network.PhysicalNetwork; import com.cloud.network.PhysicalNetwork;
import com.cloud.network.UserIpv6AddressVO; import com.cloud.network.UserIpv6AddressVO;
import com.cloud.network.as.AutoScaleManager;
import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao; import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao;
import com.cloud.network.dao.NetrisProviderDao;
import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.NsxProviderDao; import com.cloud.network.dao.NsxProviderDao;
@ -242,7 +241,9 @@ import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.dao.UserIpv6AddressDao; import com.cloud.network.dao.UserIpv6AddressDao;
import com.cloud.network.element.NetrisProviderVO;
import com.cloud.network.element.NsxProviderVO; import com.cloud.network.element.NsxProviderVO;
import com.cloud.network.netris.NetrisService;
import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.rules.LoadBalancerContainer.Scheme;
import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpc.VpcManager;
import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOffering;
@ -600,6 +601,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
configValuesForValidation.add(VMLeaseManager.InstanceLeaseSchedulerInterval.key()); configValuesForValidation.add(VMLeaseManager.InstanceLeaseSchedulerInterval.key());
configValuesForValidation.add(VMLeaseManager.InstanceLeaseExpiryEventSchedulerInterval.key()); configValuesForValidation.add(VMLeaseManager.InstanceLeaseExpiryEventSchedulerInterval.key());
configValuesForValidation.add(VMLeaseManager.InstanceLeaseExpiryEventDaysBefore.key()); configValuesForValidation.add(VMLeaseManager.InstanceLeaseExpiryEventDaysBefore.key());
configValuesForValidation.add(AutoScaleManager.AutoScaleErroredInstanceThreshold.key());
} }
protected void weightBasedParametersForValidation() { protected void weightBasedParametersForValidation() {

View File

@ -1276,6 +1276,10 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
buf.append(" vmpassword=").append(configurationDao.getValue("system.vm.password")); buf.append(" vmpassword=").append(configurationDao.getValue("system.vm.password"));
} }
if (StringUtils.isNotEmpty(NTPServerConfig.value())) {
buf.append(" ntpserverlist=").append(NTPServerConfig.value().replaceAll("\\s+",""));
}
for (NicProfile nic : profile.getNics()) { for (NicProfile nic : profile.getNics()) {
int deviceId = nic.getDeviceId(); int deviceId = nic.getDeviceId();
if (nic.getIPv4Address() == null) { if (nic.getIPv4Address() == null) {
@ -1506,7 +1510,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
public Long[] getScannablePools() { public Long[] getScannablePools() {
List<Long> zoneIds = dataCenterDao.listEnabledNonEdgeZoneIds(); List<Long> zoneIds = dataCenterDao.listEnabledNonEdgeZoneIds();
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(String.format("Enabled non-edge zones available for scan: %s", org.apache.commons.lang3.StringUtils.join(zoneIds, ","))); logger.debug(String.format("Enabled non-edge zones available for scan: %s", StringUtils.join(zoneIds, ",")));
} }
return zoneIds.toArray(Long[]::new); return zoneIds.toArray(Long[]::new);
} }

View File

@ -39,6 +39,12 @@ public interface AutoScaleManager extends AutoScaleService {
"The Number of worker threads to scan the autoscale vm groups.", "The Number of worker threads to scan the autoscale vm groups.",
false); false);
ConfigKey<Integer> AutoScaleErroredInstanceThreshold = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Integer.class,
"autoscale.errored.instance.threshold",
"10",
"The number of Error Instances allowed in autoscale vm groups for scale up.",
true);
void checkAutoScaleUser(Long autoscaleUserId, long accountId); void checkAutoScaleUser(Long autoscaleUserId, long accountId);
boolean deleteAutoScaleVmGroupsByAccount(Account account); boolean deleteAutoScaleVmGroupsByAccount(Account account);

View File

@ -1722,6 +1722,11 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
logger.warn("number of VM will greater than the maximum in this group if scaling up, so do nothing more"); logger.warn("number of VM will greater than the maximum in this group if scaling up, so do nothing more");
return false; return false;
} }
int erroredInstanceCount = autoScaleVmGroupVmMapDao.getErroredInstanceCount(asGroup.getId());
if (erroredInstanceCount > AutoScaleManager.AutoScaleErroredInstanceThreshold.value()) {
logger.warn("Number of Errored Instances are greater than the threshold in this group for scaling up, so do nothing more");
return false;
}
return true; return true;
} }
@ -2202,7 +2207,8 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
return new ConfigKey<?>[] { return new ConfigKey<?>[] {
AutoScaleStatsInterval, AutoScaleStatsInterval,
AutoScaleStatsCleanupDelay, AutoScaleStatsCleanupDelay,
AutoScaleStatsWorker AutoScaleStatsWorker,
AutoScaleErroredInstanceThreshold
}; };
} }

View File

@ -1365,7 +1365,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
for (int i = 0; i < retry; i++) { for (int i = 0; i < retry; i++) {
lsuccess = true; lsuccess = true;
try { try {
Thread.currentThread().wait(5 * 1000); Thread.sleep(5 * 1000);
} catch (final InterruptedException e) { } catch (final InterruptedException e) {
logger.debug("thread unexpectedly interrupted during wait, while updating cluster"); logger.debug("thread unexpectedly interrupted during wait, while updating cluster");
} }

View File

@ -146,6 +146,7 @@ import com.cloud.vm.dao.VMInstanceDao;
@Component @Component
public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLimitService, Configurable { public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLimitService, Configurable {
public static final String CHECKING_IF = "Checking if {}";
@Inject @Inject
private AccountManager _accountMgr; private AccountManager _accountMgr;
@Inject @Inject
@ -171,8 +172,6 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
@Inject @Inject
private ResourceLimitDao _resourceLimitDao; private ResourceLimitDao _resourceLimitDao;
@Inject @Inject
private ResourceLimitService resourceLimitService;
@Inject
private ReservationDao reservationDao; private ReservationDao reservationDao;
@Inject @Inject
protected SnapshotDao _snapshotDao; protected SnapshotDao _snapshotDao;
@ -356,7 +355,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
return; return;
} }
final long numToIncrement = (delta.length == 0) ? 1 : delta[0].longValue(); final long numToIncrement = (delta.length == 0) ? 1 : delta[0];
removeResourceReservationIfNeededAndIncrementResourceCount(accountId, type, tag, numToIncrement); removeResourceReservationIfNeededAndIncrementResourceCount(accountId, type, tag, numToIncrement);
} }
@ -372,7 +371,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
logger.trace("Not decrementing resource count for system accounts, returning"); logger.trace("Not decrementing resource count for system accounts, returning");
return; return;
} }
long numToDecrement = (delta.length == 0) ? 1 : delta[0].longValue(); long numToDecrement = (delta.length == 0) ? 1 : delta[0];
if (!updateResourceCountForAccount(accountId, type, tag, false, numToDecrement)) { if (!updateResourceCountForAccount(accountId, type, tag, false, numToDecrement)) {
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, "Failed to decrement resource count of type " + type + " for account id=" + accountId, _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, "Failed to decrement resource count of type " + type + " for account id=" + accountId,
@ -399,11 +398,11 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
// Check if limit is configured for account // Check if limit is configured for account
if (limit != null) { if (limit != null) {
max = limit.getMax().longValue(); max = limit.getMax();
} else { } else {
String resourceTypeName = type.name(); String resourceTypeName = type.name();
// If the account has an no limit set, then return global default account limits // If the account has an no limit set, then return global default account limits
Long value = null; Long value;
if (account.getType() == Account.Type.PROJECT) { if (account.getType() == Account.Type.PROJECT) {
value = projectResourceLimitMap.get(resourceTypeName); value = projectResourceLimitMap.get(resourceTypeName);
} else { } else {
@ -444,10 +443,10 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
// Check if limit is configured for account // Check if limit is configured for account
if (limit != null) { if (limit != null) {
max = limit.longValue(); max = limit;
} else { } else {
// If the account has an no limit set, then return global default account limits // If the account has an no limit set, then return global default account limits
Long value = null; Long value;
if (account.getType() == Account.Type.PROJECT) { if (account.getType() == Account.Type.PROJECT) {
value = projectResourceLimitMap.get(type.getName()); value = projectResourceLimitMap.get(type.getName());
} else { } else {
@ -479,7 +478,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndTypeAndTag(domain.getId(), ResourceOwnerType.Domain, type, tag); ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndTypeAndTag(domain.getId(), ResourceOwnerType.Domain, type, tag);
if (limit != null) { if (limit != null) {
max = limit.getMax().longValue(); max = limit.getMax();
} else { } else {
// check domain hierarchy // check domain hierarchy
Long domainId = domain.getParent(); Long domainId = domain.getParent();
@ -493,12 +492,12 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
} }
if (limit != null) { if (limit != null) {
max = limit.getMax().longValue(); max = limit.getMax();
} else { } else {
if (StringUtils.isNotEmpty(tag)) { if (StringUtils.isNotEmpty(tag)) {
return findCorrectResourceLimitForDomain(domain, type, null); return findCorrectResourceLimitForDomain(domain, type, null);
} }
Long value = null; Long value;
value = domainResourceLimitMap.get(type.name()); value = domainResourceLimitMap.get(type.name());
if (value != null) { if (value != null) {
if (value < 0) { // return unlimit if value is set to negative if (value < 0) { // return unlimit if value is set to negative
@ -517,7 +516,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
protected void checkDomainResourceLimit(final Account account, final Project project, final ResourceType type, String tag, long numResources) throws ResourceAllocationException { protected void checkDomainResourceLimit(final Account account, final Project project, final ResourceType type, String tag, long numResources) throws ResourceAllocationException {
// check all domains in the account's domain hierarchy // check all domains in the account's domain hierarchy
Long domainId = null; Long domainId;
if (project != null) { if (project != null) {
domainId = project.getDomainId(); domainId = project.getDomainId();
} else { } else {
@ -556,9 +555,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
convCurrentDomainResourceCount, convCurrentResourceReservation, convNumResources convCurrentDomainResourceCount, convCurrentResourceReservation, convNumResources
); );
if (logger.isDebugEnabled()) { logger.debug(CHECKING_IF, messageSuffix);
logger.debug("Checking if" + messageSuffix);
}
if (domainResourceLimit != Resource.RESOURCE_UNLIMITED && requestedDomainResourceCount > domainResourceLimit) { if (domainResourceLimit != Resource.RESOURCE_UNLIMITED && requestedDomainResourceCount > domainResourceLimit) {
String message = "Maximum" + messageSuffix; String message = "Maximum" + messageSuffix;
@ -597,9 +594,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
convertedAccountResourceLimit, convertedCurrentResourceCount, convertedCurrentResourceReservation, convertedNumResources convertedAccountResourceLimit, convertedCurrentResourceCount, convertedCurrentResourceReservation, convertedNumResources
); );
if (logger.isDebugEnabled()) { logger.debug(CHECKING_IF, messageSuffix);
logger.debug("Checking if" + messageSuffix);
}
if (accountResourceLimit != Resource.RESOURCE_UNLIMITED && requestedResourceCount > accountResourceLimit) { if (accountResourceLimit != Resource.RESOURCE_UNLIMITED && requestedResourceCount > accountResourceLimit) {
String message = "Maximum" + messageSuffix; String message = "Maximum" + messageSuffix;
@ -618,14 +613,14 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
@Override @Override
public long findDefaultResourceLimitForDomain(ResourceType resourceType) { public long findDefaultResourceLimitForDomain(ResourceType resourceType) {
Long resourceLimit = null; Long resourceLimit;
resourceLimit = domainResourceLimitMap.get(resourceType.getName()); resourceLimit = domainResourceLimitMap.get(resourceType.getName());
if (resourceLimit != null && ResourceType.isStorageType(resourceType)) { if (resourceLimit != null && ResourceType.isStorageType(resourceType)) {
if (! Long.valueOf(Resource.RESOURCE_UNLIMITED).equals(resourceLimit)) { if (! Long.valueOf(Resource.RESOURCE_UNLIMITED).equals(resourceLimit)) {
resourceLimit = resourceLimit * ResourceType.bytesToGiB; resourceLimit = resourceLimit * ResourceType.bytesToGiB;
} }
} else { } else {
resourceLimit = Long.valueOf(Resource.RESOURCE_UNLIMITED); resourceLimit = (long) Resource.RESOURCE_UNLIMITED;
} }
return resourceLimit; return resourceLimit;
} }
@ -703,8 +698,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
@Override @Override
public List<ResourceLimitVO> searchForLimits(Long id, Long accountId, Long domainId, ResourceType resourceType, String tag, Long startIndex, Long pageSizeVal) { public List<ResourceLimitVO> searchForLimits(Long id, Long accountId, Long domainId, ResourceType resourceType, String tag, Long startIndex, Long pageSizeVal) {
Account caller = CallContext.current().getCallingAccount(); Account caller = CallContext.current().getCallingAccount();
List<ResourceLimitVO> limits = new ArrayList<ResourceLimitVO>(); List<ResourceLimitVO> limits = new ArrayList<>();
boolean isAccount = true; boolean isAccount;
if (!_accountMgr.isAdmin(caller.getId())) { if (!_accountMgr.isAdmin(caller.getId())) {
accountId = caller.getId(); accountId = caller.getId();
@ -796,7 +791,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
if (foundLimits.isEmpty()) { if (foundLimits.isEmpty()) {
ResourceOwnerType ownerType = ResourceOwnerType.Domain; ResourceOwnerType ownerType = ResourceOwnerType.Domain;
Long ownerId = domainId; Long ownerId = domainId;
long max = 0; long max;
if (isAccount) { if (isAccount) {
ownerType = ResourceOwnerType.Account; ownerType = ResourceOwnerType.Account;
ownerId = accountId; ownerId = accountId;
@ -814,8 +809,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
// see if any limits are missing from the table, and if yes - get it from the config table and add // see if any limits are missing from the table, and if yes - get it from the config table and add
ResourceType[] resourceTypes = ResourceCount.ResourceType.values(); ResourceType[] resourceTypes = ResourceCount.ResourceType.values();
if (foundLimits.size() != resourceTypes.length) { if (foundLimits.size() != resourceTypes.length) {
List<String> accountLimitStr = new ArrayList<String>(); List<String> accountLimitStr = new ArrayList<>();
List<String> domainLimitStr = new ArrayList<String>(); List<String> domainLimitStr = new ArrayList<>();
for (ResourceLimitVO foundLimit : foundLimits) { for (ResourceLimitVO foundLimit : foundLimits) {
if (foundLimit.getAccountId() != null) { if (foundLimit.getAccountId() != null) {
accountLimitStr.add(foundLimit.getType().toString()); accountLimitStr.add(foundLimit.getType().toString());
@ -909,8 +904,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
Account caller = CallContext.current().getCallingAccount(); Account caller = CallContext.current().getCallingAccount();
if (max == null) { if (max == null) {
max = new Long(Resource.RESOURCE_UNLIMITED); max = (long)Resource.RESOURCE_UNLIMITED;
} else if (max.longValue() < Resource.RESOURCE_UNLIMITED) { } else if (max < Resource.RESOURCE_UNLIMITED) {
throw new InvalidParameterValueException("Please specify either '-1' for an infinite limit, or a limit that is at least '0'."); throw new InvalidParameterValueException("Please specify either '-1' for an infinite limit, or a limit that is at least '0'.");
} }
@ -918,7 +913,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
ResourceType resourceType = null; ResourceType resourceType = null;
if (typeId != null) { if (typeId != null) {
for (ResourceType type : Resource.ResourceType.values()) { for (ResourceType type : Resource.ResourceType.values()) {
if (type.getOrdinal() == typeId.intValue()) { if (type.getOrdinal() == typeId) {
resourceType = type; resourceType = type;
} }
} }
@ -957,7 +952,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
throw new InvalidParameterValueException("Only " + Resource.RESOURCE_UNLIMITED + " limit is supported for Root Admin accounts"); throw new InvalidParameterValueException("Only " + Resource.RESOURCE_UNLIMITED + " limit is supported for Root Admin accounts");
} }
if ((caller.getAccountId() == accountId.longValue()) && (_accountMgr.isDomainAdmin(caller.getId()) || caller.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN)) { if ((caller.getAccountId() == accountId) && (_accountMgr.isDomainAdmin(caller.getId()) || caller.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN)) {
// If the admin is trying to update their own account, disallow. // If the admin is trying to update their own account, disallow.
throw new PermissionDeniedException(String.format("Unable to update resource limit for their own account %s, permission denied", account)); throw new PermissionDeniedException(String.format("Unable to update resource limit for their own account %s, permission denied", account));
} }
@ -993,12 +988,12 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
_accountMgr.checkAccess(caller, domain); _accountMgr.checkAccess(caller, domain);
if (Domain.ROOT_DOMAIN == domainId.longValue()) { if (Domain.ROOT_DOMAIN == domainId) {
// no one can add limits on ROOT domain, disallow... // no one can add limits on ROOT domain, disallow...
throw new PermissionDeniedException("Cannot update resource limit for ROOT domain " + domainId + ", permission denied"); throw new PermissionDeniedException("Cannot update resource limit for ROOT domain " + domainId + ", permission denied");
} }
if ((caller.getDomainId() == domainId.longValue()) && caller.getType() == Account.Type.DOMAIN_ADMIN || caller.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN) { if ((caller.getDomainId() == domainId) && caller.getType() == Account.Type.DOMAIN_ADMIN || caller.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN) {
// if the admin is trying to update their own domain, disallow... // if the admin is trying to update their own domain, disallow...
throw new PermissionDeniedException("Unable to update resource limit for domain " + domainId + ", permission denied"); throw new PermissionDeniedException("Unable to update resource limit for domain " + domainId + ", permission denied");
} }
@ -1013,7 +1008,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
if (parentDomainId != null) { if (parentDomainId != null) {
DomainVO parentDomain = _domainDao.findById(parentDomainId); DomainVO parentDomain = _domainDao.findById(parentDomainId);
long parentMaximum = findCorrectResourceLimitForDomain(parentDomain, resourceType, tag); long parentMaximum = findCorrectResourceLimitForDomain(parentDomain, resourceType, tag);
if ((parentMaximum >= 0) && (max.longValue() > parentMaximum)) { if ((parentMaximum >= 0) && (max > parentMaximum)) {
throw new InvalidParameterValueException(String.format("Domain %s has maximum allowed resource limit %d for %s, please specify a value less than or equal to %d", parentDomain, parentMaximum, resourceType, parentMaximum)); throw new InvalidParameterValueException(String.format("Domain %s has maximum allowed resource limit %d for %s, please specify a value less than or equal to %d", parentDomain, parentMaximum, resourceType, parentMaximum));
} }
} }
@ -1031,7 +1026,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
ActionEventUtils.onActionEvent(caller.getId(), caller.getAccountId(), ActionEventUtils.onActionEvent(caller.getId(), caller.getAccountId(),
caller.getDomainId(), EventTypes.EVENT_RESOURCE_LIMIT_UPDATE, caller.getDomainId(), EventTypes.EVENT_RESOURCE_LIMIT_UPDATE,
"Resource limit updated. Resource Type: " + resourceType.toString() + ", New Value: " + max, "Resource limit updated. Resource Type: " + resourceType + ", New Value: " + max,
ownerResourceId, ownerResourceType.toString()); ownerResourceId, ownerResourceType.toString());
if (limit != null) { if (limit != null) {
@ -1110,15 +1105,15 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
@Override @Override
public List<? extends ResourceCount> recalculateResourceCount(Long accountId, Long domainId, Integer typeId, String tag) throws CloudRuntimeException { public List<? extends ResourceCount> recalculateResourceCount(Long accountId, Long domainId, Integer typeId, String tag) throws CloudRuntimeException {
Account callerAccount = CallContext.current().getCallingAccount(); Account callerAccount = CallContext.current().getCallingAccount();
long count = 0; long count;
List<ResourceCountVO> counts = new ArrayList<ResourceCountVO>(); List<ResourceCountVO> counts = new ArrayList<>();
List<ResourceType> resourceTypes = new ArrayList<ResourceType>(); List<ResourceType> resourceTypes = new ArrayList<>();
ResourceType resourceType = null; ResourceType resourceType = null;
if (typeId != null) { if (typeId != null) {
for (ResourceType type : Resource.ResourceType.values()) { for (ResourceType type : Resource.ResourceType.values()) {
if (type.getOrdinal() == typeId.intValue()) { if (type.getOrdinal() == typeId) {
resourceType = type; resourceType = type;
} }
} }
@ -1137,12 +1132,13 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
throw new InvalidParameterValueException("Please specify a valid domain ID."); throw new InvalidParameterValueException("Please specify a valid domain ID.");
} }
_accountMgr.checkAccess(callerAccount, domain); _accountMgr.checkAccess(callerAccount, domain);
if (accountId != null) {
Account account = _entityMgr.findById(Account.class, accountId); Account account = _entityMgr.findById(Account.class, accountId);
if (account == null) { if (account == null) {
throw new InvalidParameterValueException("Unable to find account " + accountId); throw new InvalidParameterValueException("Unable to find account " + accountId);
} }
_accountMgr.verifyCallerPrivilegeForUserOrAccountOperations(account); _accountMgr.verifyCallerPrivilegeForUserOrAccountOperations(account);
}
if (resourceType != null) { if (resourceType != null) {
resourceTypes.add(resourceType); resourceTypes.add(resourceType);
} else { } else {
@ -1191,7 +1187,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
convertedDelta = toHumanReadableSize(delta); convertedDelta = toHumanReadableSize(delta);
} }
String typeStr = StringUtils.isNotEmpty(tag) ? String.format("%s (tag: %s)", type, tag) : type.getName(); String typeStr = StringUtils.isNotEmpty(tag) ? String.format("%s (tag: %s)", type, tag) : type.getName();
logger.debug("Updating resource Type = " + typeStr + " count for Account = " + accountId + " Operation = " + (increment ? "increasing" : "decreasing") + " Amount = " + convertedDelta); logger.debug("Updating resource Type = {} count for Account with id = {} Operation = {} Amount = {}", typeStr, accountId, (increment ? "increasing" : "decreasing"), convertedDelta);
} }
Set<Long> rowIdsToUpdate = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type, tag); Set<Long> rowIdsToUpdate = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type, tag);
return _resourceCountDao.updateCountByDeltaForIds(new ArrayList<>(rowIdsToUpdate), increment, delta); return _resourceCountDao.updateCountByDeltaForIds(new ArrayList<>(rowIdsToUpdate), increment, delta);
@ -1246,6 +1242,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
newResourceCount += _projectDao.countProjectsForDomain(domainId); newResourceCount += _projectDao.countProjectsForDomain(domainId);
} }
// TODO make sure that the resource counts are not null
for (ResourceCountVO resourceCount : resourceCounts) { for (ResourceCountVO resourceCount : resourceCounts) {
if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Domain && resourceCount.getDomainId() == domainId) { if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Domain && resourceCount.getDomainId() == domainId) {
oldResourceCount = resourceCount.getCount(); oldResourceCount = resourceCount.getCount();
@ -1255,11 +1252,12 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
} }
} }
// TODO domainRC may be null if there are no resource counts for the domain found in the loop above
if (oldResourceCount != newResourceCount) { if (oldResourceCount != newResourceCount) {
domainRC.setCount(newResourceCount); domainRC.setCount(newResourceCount);
_resourceCountDao.update(domainRC.getId(), domainRC); _resourceCountDao.update(domainRC.getId(), domainRC);
logger.warn("Discrepency in the resource count has been detected " + "(original count = " + oldResourceCount + " correct count = " + newResourceCount + ") for Type = " + type logger.warn("Discrepency in the resource count has been detected (original count = {} correct count = {}) for Type = {} for Domain ID = {} is fixed during resource count recalculation.",
+ " for Domain ID = " + domainId + " is fixed during resource count recalculation."); oldResourceCount, newResourceCount, type, domainId);
} }
return newResourceCount; return newResourceCount;
}); });
@ -1335,8 +1333,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
// No need to log message for storage type resources because both are recalculating the // No need to log message for storage type resources because both are recalculating the
// resource count which will not lead to any discrepancy. // resource count which will not lead to any discrepancy.
if (newCount != null && !newCount.equals(oldCount) && !ResourceType.isStorageType(type)) { if (newCount != null && !newCount.equals(oldCount) && !ResourceType.isStorageType(type)) {
logger.warn("Discrepancy in the resource count " + "(original count=" + oldCount + " correct count = " + newCount + ") for type " + type + logger.warn("Discrepancy in the resource count (original count={} correct count = {}) for type {} for account ID {} is fixed during resource count recalculation.",
" for account ID " + accountId + " is fixed during resource count recalculation."); oldCount, newCount, type, accountId);
} }
return (newCount == null) ? 0 : newCount; return (newCount == null) ? 0 : newCount;
@ -1508,20 +1506,16 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
} }
private long calculatePublicIpForAccount(long accountId) { private long calculatePublicIpForAccount(long accountId) {
Long dedicatedCount = 0L; long dedicatedCount = 0L;
Long allocatedCount = 0L; long allocatedCount;
List<VlanVO> dedicatedVlans = _vlanDao.listDedicatedVlans(accountId); List<VlanVO> dedicatedVlans = _vlanDao.listDedicatedVlans(accountId);
for (VlanVO dedicatedVlan : dedicatedVlans) { for (VlanVO dedicatedVlan : dedicatedVlans) {
List<IPAddressVO> ips = _ipAddressDao.listByVlanId(dedicatedVlan.getId()); List<IPAddressVO> ips = _ipAddressDao.listByVlanId(dedicatedVlan.getId());
dedicatedCount += new Long(ips.size()); dedicatedCount += ips.size();
} }
allocatedCount = _ipAddressDao.countAllocatedIPsForAccount(accountId); allocatedCount = _ipAddressDao.countAllocatedIPsForAccount(accountId);
if (dedicatedCount > allocatedCount) { return Math.max(dedicatedCount, allocatedCount);
return dedicatedCount;
} else {
return allocatedCount;
}
} }
protected long calculatePrimaryStorageForAccount(long accountId, String tag) { protected long calculatePrimaryStorageForAccount(long accountId, String tag) {
@ -1609,10 +1603,10 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
protected TaggedResourceLimitAndCountResponse getTaggedResourceLimitAndCountResponse(Account account, protected TaggedResourceLimitAndCountResponse getTaggedResourceLimitAndCountResponse(Account account,
Domain domain, ResourceOwnerType ownerType, ResourceType type, String tag) { Domain domain, ResourceOwnerType ownerType, ResourceType type, String tag) {
Long limit = ResourceOwnerType.Account.equals(ownerType) ? long limit = ResourceOwnerType.Account.equals(ownerType) ?
findCorrectResourceLimitForAccount(account, type, tag) : findCorrectResourceLimitForAccount(account, type, tag) :
findCorrectResourceLimitForDomain(domain, type, tag); findCorrectResourceLimitForDomain(domain, type, tag);
Long count = 0L; long count = 0L;
ResourceCountVO countVO = _resourceCountDao.findByOwnerAndTypeAndTag( ResourceCountVO countVO = _resourceCountDao.findByOwnerAndTypeAndTag(
ResourceOwnerType.Account.equals(ownerType) ? account.getId() : domain.getId(), ownerType, type, tag); ResourceOwnerType.Account.equals(ownerType) ? account.getId() : domain.getId(), ownerType, type, tag);
if (countVO != null) { if (countVO != null) {
@ -1861,7 +1855,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
if (currentOfferingTags.isEmpty() && newOfferingTags.isEmpty()) { if (currentOfferingTags.isEmpty() && newOfferingTags.isEmpty()) {
return null; return null;
} }
Set<String> sameTags = currentOfferingTags.stream().filter(newOfferingTags::contains).collect(Collectors.toSet());; Set<String> sameTags = currentOfferingTags.stream().filter(newOfferingTags::contains).collect(Collectors.toSet());
Set<String> newTags = newOfferingTags.stream().filter(tag -> !currentOfferingTags.contains(tag)).collect(Collectors.toSet()); Set<String> newTags = newOfferingTags.stream().filter(tag -> !currentOfferingTags.contains(tag)).collect(Collectors.toSet());
Set<String> removedTags = currentOfferingTags.stream().filter(tag -> !newOfferingTags.contains(tag)).collect(Collectors.toSet()); Set<String> removedTags = currentOfferingTags.stream().filter(tag -> !newOfferingTags.contains(tag)).collect(Collectors.toSet());
return new Ternary<>(sameTags, newTags, removedTags); return new Ternary<>(sameTags, newTags, removedTags);
@ -1936,7 +1930,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
if (currentOfferingTags.isEmpty() && newOfferingTags.isEmpty()) { if (currentOfferingTags.isEmpty() && newOfferingTags.isEmpty()) {
return null; return null;
} }
Set<String> sameTags = currentOfferingTags.stream().filter(newOfferingTags::contains).collect(Collectors.toSet());; Set<String> sameTags = currentOfferingTags.stream().filter(newOfferingTags::contains).collect(Collectors.toSet());
Set<String> newTags = newOfferingTags.stream().filter(tag -> !currentOfferingTags.contains(tag)).collect(Collectors.toSet()); Set<String> newTags = newOfferingTags.stream().filter(tag -> !currentOfferingTags.contains(tag)).collect(Collectors.toSet());
Set<String> removedTags = currentOfferingTags.stream().filter(tag -> !newOfferingTags.contains(tag)).collect(Collectors.toSet()); Set<String> removedTags = currentOfferingTags.stream().filter(tag -> !newOfferingTags.contains(tag)).collect(Collectors.toSet());
return new Ternary<>(sameTags, newTags, removedTags); return new Ternary<>(sameTags, newTags, removedTags);

View File

@ -774,14 +774,12 @@ import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkDomainDao; import com.cloud.network.dao.NetworkDomainDao;
import com.cloud.network.dao.NetworkDomainVO; import com.cloud.network.dao.NetworkDomainVO;
import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PublicIpQuarantineDao;
import com.cloud.network.vpc.dao.VpcDao; import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.org.Cluster; import com.cloud.org.Cluster;
import com.cloud.org.Grouping.AllocationState; import com.cloud.org.Grouping.AllocationState;
import com.cloud.projects.Project; import com.cloud.projects.Project;
import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.projects.Project.ListProjectResourcesCriteria;
import com.cloud.projects.ProjectManager; import com.cloud.projects.ProjectManager;
import com.cloud.resource.ResourceManager;
import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.server.ResourceTag.ResourceObjectType;
import com.cloud.service.ServiceOfferingVO; import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.service.dao.ServiceOfferingDao;
@ -883,8 +881,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
static final ConfigKey<Integer> sshKeyLength = new ConfigKey<>("Advanced", Integer.class, "ssh.key.length", "2048", "Specifies custom SSH key length (bit)", true, ConfigKey.Scope.Global); static final ConfigKey<Integer> sshKeyLength = new ConfigKey<>("Advanced", Integer.class, "ssh.key.length", "2048", "Specifies custom SSH key length (bit)", true, ConfigKey.Scope.Global);
static final ConfigKey<Boolean> humanReadableSizes = new ConfigKey<>("Advanced", Boolean.class, "display.human.readable.sizes", "true", "Enables outputting human readable byte sizes to logs and usage records.", false, ConfigKey.Scope.Global); static final ConfigKey<Boolean> humanReadableSizes = new ConfigKey<>("Advanced", Boolean.class, "display.human.readable.sizes", "true", "Enables outputting human readable byte sizes to logs and usage records.", false, ConfigKey.Scope.Global);
public static final ConfigKey<String> customCsIdentifier = new ConfigKey<>("Advanced", String.class, "custom.cs.identifier", UUID.randomUUID().toString().split("-")[0].substring(4), "Custom identifier for the cloudstack installation", true, ConfigKey.Scope.Global); public static final ConfigKey<String> customCsIdentifier = new ConfigKey<>("Advanced", String.class, "custom.cs.identifier", UUID.randomUUID().toString().split("-")[0].substring(4), "Custom identifier for the cloudstack installation", true, ConfigKey.Scope.Global);
public static final ConfigKey<Boolean> exposeCloudStackVersionInApiXmlResponse = new ConfigKey<Boolean>("Advanced", Boolean.class, "expose.cloudstack.version.api.xml.response", "true", "Indicates whether ACS version should appear in the root element of an API XML response.", true, ConfigKey.Scope.Global); public static final ConfigKey<Boolean> exposeCloudStackVersionInApiXmlResponse = new ConfigKey<>("Advanced", Boolean.class, "expose.cloudstack.version.api.xml.response", "true", "Indicates whether ACS version should appear in the root element of an API XML response.", true, ConfigKey.Scope.Global);
public static final ConfigKey<Boolean> exposeCloudStackVersionInApiListCapabilities = new ConfigKey<Boolean>("Advanced", Boolean.class, "expose.cloudstack.version.api.list.capabilities", "true", "Indicates whether ACS version should show in the listCapabilities API.", true, ConfigKey.Scope.Global); public static final ConfigKey<Boolean> exposeCloudStackVersionInApiListCapabilities = new ConfigKey<>("Advanced", Boolean.class, "expose.cloudstack.version.api.list.capabilities", "true", "Indicates whether ACS version should show in the listCapabilities API.", true, ConfigKey.Scope.Global);
private static final VirtualMachine.Type []systemVmTypes = { VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.ConsoleProxy}; private static final VirtualMachine.Type []systemVmTypes = { VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.ConsoleProxy};
private static final List<HypervisorType> LIVE_MIGRATION_SUPPORTING_HYPERVISORS = List.of(HypervisorType.Hyperv, HypervisorType.KVM, private static final List<HypervisorType> LIVE_MIGRATION_SUPPORTING_HYPERVISORS = List.of(HypervisorType.Hyperv, HypervisorType.KVM,
@ -991,8 +989,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
@Inject @Inject
private ProjectManager _projectMgr; private ProjectManager _projectMgr;
@Inject @Inject
private ResourceManager _resourceMgr;
@Inject
private HighAvailabilityManager _haMgr; private HighAvailabilityManager _haMgr;
@Inject @Inject
private HostTagsDao _hostTagsDao; private HostTagsDao _hostTagsDao;
@ -1050,10 +1046,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
StoragePoolTagsDao storagePoolTagsDao; StoragePoolTagsDao storagePoolTagsDao;
@Inject @Inject
protected ManagementServerJoinDao managementServerJoinDao; protected ManagementServerJoinDao managementServerJoinDao;
@Inject
private PublicIpQuarantineDao publicIpQuarantineDao;
@Inject @Inject
ClusterManager _clusterMgr; ClusterManager _clusterMgr;
@ -1080,7 +1072,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
private List<UserAuthenticator> _userAuthenticators; private List<UserAuthenticator> _userAuthenticators;
private List<UserTwoFactorAuthenticator> _userTwoFactorAuthenticators; private List<UserTwoFactorAuthenticator> _userTwoFactorAuthenticators;
private List<UserAuthenticator> _userPasswordEncoders; private List<UserAuthenticator> _userPasswordEncoders;
protected boolean _executeInSequence;
protected List<DeploymentPlanner> _planners; protected List<DeploymentPlanner> _planners;
@ -4751,6 +4742,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
capabilities.put(ApiConstants.INSTANCES_DISKS_STATS_RETENTION_ENABLED, StatsCollector.vmDiskStatsRetentionEnabled.value()); capabilities.put(ApiConstants.INSTANCES_DISKS_STATS_RETENTION_ENABLED, StatsCollector.vmDiskStatsRetentionEnabled.value());
capabilities.put(ApiConstants.INSTANCES_DISKS_STATS_RETENTION_TIME, StatsCollector.vmDiskStatsMaxRetentionTime.value()); capabilities.put(ApiConstants.INSTANCES_DISKS_STATS_RETENTION_TIME, StatsCollector.vmDiskStatsMaxRetentionTime.value());
capabilities.put(ApiConstants.INSTANCE_LEASE_ENABLED, VMLeaseManager.InstanceLeaseEnabled.value()); capabilities.put(ApiConstants.INSTANCE_LEASE_ENABLED, VMLeaseManager.InstanceLeaseEnabled.value());
capabilities.put(ApiConstants.DYNAMIC_SCALING_ENABLED, UserVmManager.EnableDynamicallyScaleVm.value());
if (apiLimitEnabled) { if (apiLimitEnabled) {
capabilities.put("apiLimitInterval", apiLimitInterval); capabilities.put("apiLimitInterval", apiLimitInterval);
capabilities.put("apiLimitMax", apiLimitMax); capabilities.put("apiLimitMax", apiLimitMax);

View File

@ -2644,7 +2644,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
excludeLocalStorageIfNeeded(volumeToAttach); excludeLocalStorageIfNeeded(volumeToAttach);
checkForDevicesInCopies(vmId, vm); checkForVMSnapshots(vmId, vm);
checkForBackups(vm, true);
checkRightsToAttach(caller, volumeToAttach, vm); checkRightsToAttach(caller, volumeToAttach, vm);
@ -2743,18 +2745,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
} }
} }
private void checkForDevicesInCopies(Long vmId, UserVmVO vm) { private void checkForVMSnapshots(Long vmId, UserVmVO vm) {
// if target VM has associated VM snapshots // if target VM has associated VM snapshots
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId); List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
if (vmSnapshots.size() > 0) { if (vmSnapshots.size() > 0) {
throw new InvalidParameterValueException(String.format("Unable to attach volume to VM %s/%s, please specify a VM that does not have VM snapshots", vm.getName(), vm.getUuid())); throw new InvalidParameterValueException(String.format("Unable to attach volume to VM %s/%s, please specify a VM that does not have VM snapshots", vm.getName(), vm.getUuid()));
} }
// if target VM has backups
List<Backup> backups = backupDao.listByVmId(vm.getDataCenterId(), vm.getId());
if (vm.getBackupOfferingId() != null && !backups.isEmpty()) {
throw new InvalidParameterValueException(String.format("Unable to attach volume to VM %s/%s, please specify a VM that does not have any backups", vm.getName(), vm.getUuid()));
}
} }
/** /**
@ -2854,7 +2850,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
return volumeToAttach; return volumeToAttach;
} }
protected void validateIfVmHasBackups(UserVmVO vm, boolean attach) { protected void checkForBackups(UserVmVO vm, boolean attach) {
if ((vm.getBackupOfferingId() == null || CollectionUtils.isEmpty(vm.getBackupVolumeList())) || BooleanUtils.isTrue(BackupManager.BackupEnableAttachDetachVolumes.value())) { if ((vm.getBackupOfferingId() == null || CollectionUtils.isEmpty(vm.getBackupVolumeList())) || BooleanUtils.isTrue(BackupManager.BackupEnableAttachDetachVolumes.value())) {
return; return;
} }
@ -3074,7 +3070,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots"); throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots");
} }
validateIfVmHasBackups(vm, false); checkForBackups(vm, false);
AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext(); AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
if (asyncExecutionContext != null) { if (asyncExecutionContext != null) {

View File

@ -1854,6 +1854,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
throw new InvalidParameterValueException("Failed to create private template record, please specify only one of volume ID (" + volumeId + throw new InvalidParameterValueException("Failed to create private template record, please specify only one of volume ID (" + volumeId +
") and snapshot ID (" + snapshotId + ")"); ") and snapshot ID (" + snapshotId + ")");
} }
CPU.CPUArch arch = cmd.getArch();
HypervisorType hyperType; HypervisorType hyperType;
VolumeVO volume = null; VolumeVO volume = null;
@ -1946,7 +1947,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
String description = cmd.getDisplayText(); String description = cmd.getDisplayText();
boolean isExtractable = false; boolean isExtractable = false;
Long sourceTemplateId = null; Long sourceTemplateId = null;
CPU.CPUArch arch = CPU.CPUArch.amd64;
if (volume != null) { if (volume != null) {
VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId()); VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
isExtractable = template != null && template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM; isExtractable = template != null && template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM;

View File

@ -650,6 +650,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
return false; return false;
} }
@Override
public boolean isResourceDomainAdmin(Long accountId) { public boolean isResourceDomainAdmin(Long accountId) {
if (accountId != null) { if (accountId != null) {
AccountVO acct = _accountDao.findById(accountId); AccountVO acct = _accountDao.findById(accountId);

View File

@ -19,6 +19,7 @@ package org.apache.cloudstack.backup;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -292,6 +293,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
public static String createVolumeInfoFromVolumes(List<VolumeVO> vmVolumes) { public static String createVolumeInfoFromVolumes(List<VolumeVO> vmVolumes) {
List<Backup.VolumeInfo> list = new ArrayList<>(); List<Backup.VolumeInfo> list = new ArrayList<>();
vmVolumes.sort(Comparator.comparing(VolumeVO::getDeviceId));
for (VolumeVO vol : vmVolumes) { for (VolumeVO vol : vmVolumes) {
list.add(new Backup.VolumeInfo(vol.getUuid(), vol.getPath(), vol.getVolumeType(), vol.getSize())); list.add(new Backup.VolumeInfo(vol.getUuid(), vol.getPath(), vol.getVolumeType(), vol.getSize()));
} }

View File

@ -170,6 +170,7 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.volume.VolumeOnStorageTO;
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo; import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils; import org.apache.commons.collections.MapUtils;
@ -814,6 +815,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
throw new CloudRuntimeException("Error while copying volume of remote instance: " + answer.getDetails()); throw new CloudRuntimeException("Error while copying volume of remote instance: " + answer.getDetails());
} }
CopyRemoteVolumeAnswer copyRemoteVolumeAnswer = (CopyRemoteVolumeAnswer) answer; CopyRemoteVolumeAnswer copyRemoteVolumeAnswer = (CopyRemoteVolumeAnswer) answer;
checkVolume(copyRemoteVolumeAnswer.getVolumeDetails());
if (!copyRemoteVolumeAnswer.getResult()) { if (!copyRemoteVolumeAnswer.getResult()) {
throw new CloudRuntimeException("Unable to copy volume of remote instance"); throw new CloudRuntimeException("Unable to copy volume of remote instance");
} }
@ -1188,6 +1190,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
allDetails.put(VmDetailConstants.KVM_VNC_PASSWORD, unmanagedInstance.getVncPassword()); allDetails.put(VmDetailConstants.KVM_VNC_PASSWORD, unmanagedInstance.getVncPassword());
} }
addImportingVMBootTypeAndModeDetails(unmanagedInstance.getBootType(), unmanagedInstance.getBootMode(), allDetails);
VirtualMachine.PowerState powerState = VirtualMachine.PowerState.PowerOff; VirtualMachine.PowerState powerState = VirtualMachine.PowerState.PowerOff;
if (unmanagedInstance.getPowerState().equals(UnmanagedInstanceTO.PowerState.PowerOn)) { if (unmanagedInstance.getPowerState().equals(UnmanagedInstanceTO.PowerState.PowerOn)) {
powerState = VirtualMachine.PowerState.PowerOn; powerState = VirtualMachine.PowerState.PowerOn;
@ -1259,6 +1263,12 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
return userVm; return userVm;
} }
private void addImportingVMBootTypeAndModeDetails(String bootType, String bootMode, Map<String, String> allDetails) {
if (StringUtils.isNotBlank(bootType) && bootType.equalsIgnoreCase("uefi") && StringUtils.isNotBlank(bootMode)) {
allDetails.put("UEFI", bootMode);
}
}
private HashMap<String, UnmanagedInstanceTO> getUnmanagedInstancesForHost(HostVO host, String instanceName, List<String> managedVms) { private HashMap<String, UnmanagedInstanceTO> getUnmanagedInstancesForHost(HostVO host, String instanceName, List<String> managedVms) {
HashMap<String, UnmanagedInstanceTO> unmanagedInstances = new HashMap<>(); HashMap<String, UnmanagedInstanceTO> unmanagedInstances = new HashMap<>();
if (host.isInMaintenanceStates()) { if (host.isInMaintenanceStates()) {
@ -2692,6 +2702,12 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
throw new CloudRuntimeException("Disk not found or is invalid"); throw new CloudRuntimeException("Disk not found or is invalid");
} }
CheckVolumeAnswer checkVolumeAnswer = (CheckVolumeAnswer) answer; CheckVolumeAnswer checkVolumeAnswer = (CheckVolumeAnswer) answer;
try {
checkVolume(checkVolumeAnswer.getVolumeDetails());
} catch (CloudRuntimeException e) {
cleanupFailedImportVM(userVm);
throw e;
}
if (!checkVolumeAnswer.getResult()) { if (!checkVolumeAnswer.getResult()) {
cleanupFailedImportVM(userVm); cleanupFailedImportVM(userVm);
throw new CloudRuntimeException("Disk not found or is invalid"); throw new CloudRuntimeException("Disk not found or is invalid");
@ -2718,6 +2734,31 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
return userVm; return userVm;
} }
private void checkVolume(Map<VolumeOnStorageTO.Detail, String> volumeDetails) {
if (MapUtils.isEmpty(volumeDetails)) {
return;
}
if (volumeDetails.containsKey(VolumeOnStorageTO.Detail.IS_LOCKED)) {
String isLocked = volumeDetails.get(VolumeOnStorageTO.Detail.IS_LOCKED);
if (Boolean.parseBoolean(isLocked)) {
logFailureAndThrowException("Locked volume cannot be imported or unmanaged.");
}
}
if (volumeDetails.containsKey(VolumeOnStorageTO.Detail.IS_ENCRYPTED)) {
String isEncrypted = volumeDetails.get(VolumeOnStorageTO.Detail.IS_ENCRYPTED);
if (Boolean.parseBoolean(isEncrypted)) {
logFailureAndThrowException("Encrypted volume cannot be imported or unmanaged.");
}
}
if (volumeDetails.containsKey(VolumeOnStorageTO.Detail.BACKING_FILE)) {
String backingFile = volumeDetails.get(VolumeOnStorageTO.Detail.BACKING_FILE);
if (StringUtils.isNotBlank(backingFile)) {
logFailureAndThrowException("Volume with backing file cannot be imported or unmanaged.");
}
}
}
private NetworkVO getDefaultNetwork(DataCenter zone, Account owner, boolean selectAny) throws InsufficientCapacityException, ResourceAllocationException { private NetworkVO getDefaultNetwork(DataCenter zone, Account owner, boolean selectAny) throws InsufficientCapacityException, ResourceAllocationException {
NetworkVO defaultNetwork = null; NetworkVO defaultNetwork = null;

View File

@ -672,7 +672,6 @@ public class VolumeApiServiceImplTest {
when(vm.getState()).thenReturn(State.Running); when(vm.getState()).thenReturn(State.Running);
when(vm.getDataCenterId()).thenReturn(34L); when(vm.getDataCenterId()).thenReturn(34L);
when(vm.getBackupOfferingId()).thenReturn(null); when(vm.getBackupOfferingId()).thenReturn(null);
when(backupDaoMock.listByVmId(anyLong(), anyLong())).thenReturn(Collections.emptyList());
when(volumeDaoMock.findByInstanceAndType(anyLong(), any(Volume.Type.class))).thenReturn(new ArrayList<>(10)); when(volumeDaoMock.findByInstanceAndType(anyLong(), any(Volume.Type.class))).thenReturn(new ArrayList<>(10));
when(volumeDataFactoryMock.getVolume(9L)).thenReturn(volumeToAttach); when(volumeDataFactoryMock.getVolume(9L)).thenReturn(volumeToAttach);
when(volumeToAttach.getState()).thenReturn(Volume.State.Uploaded); when(volumeToAttach.getState()).thenReturn(Volume.State.Uploaded);
@ -1311,7 +1310,7 @@ public class VolumeApiServiceImplTest {
try { try {
UserVmVO vm = Mockito.mock(UserVmVO.class); UserVmVO vm = Mockito.mock(UserVmVO.class);
when(vm.getBackupOfferingId()).thenReturn(1l); when(vm.getBackupOfferingId()).thenReturn(1l);
volumeApiServiceImpl.validateIfVmHasBackups(vm, false); volumeApiServiceImpl.checkForBackups(vm, false);
} catch (Exception e) { } catch (Exception e) {
Assert.assertEquals("Unable to detach volume, cannot detach volume from a VM that has backups. First remove the VM from the backup offering or set the global configuration 'backup.enable.attach.detach.of.volumes' to true.", e.getMessage()); Assert.assertEquals("Unable to detach volume, cannot detach volume from a VM that has backups. First remove the VM from the backup offering or set the global configuration 'backup.enable.attach.detach.of.volumes' to true.", e.getMessage());
} }
@ -1322,7 +1321,7 @@ public class VolumeApiServiceImplTest {
try { try {
UserVmVO vm = Mockito.mock(UserVmVO.class); UserVmVO vm = Mockito.mock(UserVmVO.class);
when(vm.getBackupOfferingId()).thenReturn(1l); when(vm.getBackupOfferingId()).thenReturn(1l);
volumeApiServiceImpl.validateIfVmHasBackups(vm, true); volumeApiServiceImpl.checkForBackups(vm, true);
} catch (Exception e) { } catch (Exception e) {
Assert.assertEquals("Unable to attach volume, please specify a VM that does not have any backups or set the global configuration 'backup.enable.attach.detach.of.volumes' to true.", e.getMessage()); Assert.assertEquals("Unable to attach volume, please specify a VM that does not have any backups or set the global configuration 'backup.enable.attach.detach.of.volumes' to true.", e.getMessage());
} }
@ -1332,7 +1331,7 @@ public class VolumeApiServiceImplTest {
public void validateIfVmHaveBackupsTestSuccessWhenVMDontHaveBackupOffering() { public void validateIfVmHaveBackupsTestSuccessWhenVMDontHaveBackupOffering() {
UserVmVO vm = Mockito.mock(UserVmVO.class); UserVmVO vm = Mockito.mock(UserVmVO.class);
when(vm.getBackupOfferingId()).thenReturn(null); when(vm.getBackupOfferingId()).thenReturn(null);
volumeApiServiceImpl.validateIfVmHasBackups(vm, true); volumeApiServiceImpl.checkForBackups(vm, true);
} }
@Test @Test

View File

@ -422,6 +422,11 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
return false; return false;
} }
@Override
public boolean isResourceDomainAdmin(Long accountId) {
return false;
}
@Override @Override
public boolean isNormalUser(long accountId) { public boolean isNormalUser(long accountId) {
// TODO Auto-generated method stub // TODO Auto-generated method stub

View File

@ -76,6 +76,7 @@ public class ConsoleProxy {
static int httpCmdListenPort = 8001; static int httpCmdListenPort = 8001;
static int reconnectMaxRetry = 5; static int reconnectMaxRetry = 5;
static int readTimeoutSeconds = 90; static int readTimeoutSeconds = 90;
public static int defaultBufferSize = 64 * 1024;
static int keyboardType = KEYBOARD_RAW; static int keyboardType = KEYBOARD_RAW;
static String factoryClzName; static String factoryClzName;
static boolean standaloneStart = false; static boolean standaloneStart = false;
@ -160,6 +161,12 @@ public class ConsoleProxy {
readTimeoutSeconds = Integer.parseInt(s); readTimeoutSeconds = Integer.parseInt(s);
LOGGER.info("Setting readTimeoutSeconds=" + readTimeoutSeconds); LOGGER.info("Setting readTimeoutSeconds=" + readTimeoutSeconds);
} }
s = conf.getProperty("consoleproxy.defaultBufferSize");
if (s != null) {
defaultBufferSize = Integer.parseInt(s);
LOGGER.info("Setting defaultBufferSize=" + defaultBufferSize);
}
} }
public static ConsoleProxyServerFactory getHttpServerFactory() { public static ConsoleProxyServerFactory getHttpServerFactory() {

View File

@ -52,6 +52,9 @@ public class ConsoleProxyNoVncClient implements ConsoleProxyClient {
private ConsoleProxyClientParam clientParam; private ConsoleProxyClientParam clientParam;
private String sessionUuid; private String sessionUuid;
private ByteBuffer readBuffer = null;
private int flushThreshold = -1;
public ConsoleProxyNoVncClient(Session session) { public ConsoleProxyNoVncClient(Session session) {
this.session = session; this.session = session;
} }
@ -109,8 +112,9 @@ public class ConsoleProxyNoVncClient implements ConsoleProxyClient {
connectClientToVNCServer(tunnelUrl, tunnelSession, websocketUrl); connectClientToVNCServer(tunnelUrl, tunnelSession, websocketUrl);
authenticateToVNCServer(clientSourceIp); authenticateToVNCServer(clientSourceIp);
int readBytes; // Track consecutive iterations with no data and sleep accordingly. Only used for NIO socket connections.
byte[] b; int consecutiveZeroReads = 0;
int sleepTime = 1;
while (connectionAlive) { while (connectionAlive) {
logger.trace("Connection with client [{}] [IP: {}] is alive.", clientId, clientSourceIp); logger.trace("Connection with client [{}] [IP: {}] is alive.", clientId, clientSourceIp);
if (client.isVncOverWebSocketConnection()) { if (client.isVncOverWebSocketConnection()) {
@ -118,32 +122,55 @@ public class ConsoleProxyNoVncClient implements ConsoleProxyClient {
updateFrontEndActivityTime(); updateFrontEndActivityTime();
} }
connectionAlive = session.isOpen(); connectionAlive = session.isOpen();
sleepTime = 1;
} else if (client.isVncOverNioSocket()) { } else if (client.isVncOverNioSocket()) {
byte[] bytesArr; ByteBuffer buffer = getOrCreateReadBuffer();
int nextBytes = client.getNextBytes(); int bytesRead = client.readAvailableDataIntoBuffer(buffer, buffer.remaining());
bytesArr = new byte[nextBytes];
client.readBytes(bytesArr, nextBytes); if (bytesRead > 0) {
logger.trace("Read [{}] bytes from client [{}].", nextBytes, clientId);
if (nextBytes > 0) {
session.getRemote().sendBytes(ByteBuffer.wrap(bytesArr));
updateFrontEndActivityTime(); updateFrontEndActivityTime();
consecutiveZeroReads = 0; // Reset counter on successful read
sleepTime = 0; // Still no sleep to catch any remaining data quickly
} else { } else {
connectionAlive = session.isOpen(); connectionAlive = session.isOpen();
consecutiveZeroReads++;
// Use adaptive sleep time to prevent excessive busy waiting
sleepTime = Math.min(consecutiveZeroReads, 10); // Cap at 10ms max
}
final boolean bufferHasData = buffer.position() > 0;
if (bufferHasData && (bytesRead == 0 || buffer.remaining() <= flushThreshold)) {
buffer.flip();
logger.trace("Flushing buffer with [{}] bytes for client [{}]", buffer.remaining(), clientId);
session.getRemote().sendBytes(buffer);
buffer.compact();
} }
} else { } else {
b = new byte[100]; ByteBuffer buffer = getOrCreateReadBuffer();
readBytes = client.read(b); buffer.clear();
int readBytes = client.read(buffer.array());
logger.trace("Read [{}] bytes from client [{}].", readBytes, clientId); logger.trace("Read [{}] bytes from client [{}].", readBytes, clientId);
if (readBytes == -1 || (readBytes > 0 && !sendReadBytesToNoVNC(b, readBytes))) { if (readBytes > 0) {
// Update buffer position to reflect bytes read and flip for reading
buffer.position(readBytes);
buffer.flip();
if (!sendReadBytesToNoVNC(buffer)) {
connectionAlive = false; connectionAlive = false;
} }
} else if (readBytes == -1) {
connectionAlive = false;
} }
sleepTime = 1;
}
if (sleepTime > 0 && connectionAlive) {
try { try {
Thread.sleep(1); Thread.sleep(sleepTime);
} catch (InterruptedException e) { } catch (InterruptedException e) {
logger.error("Error on sleep for vnc sessions", e); logger.error("Error on sleep for vnc sessions", e);
} }
} }
}
logger.info("Connection with client [{}] [IP: {}] is dead.", clientId, clientSourceIp); logger.info("Connection with client [{}] [IP: {}] is dead.", clientId, clientSourceIp);
} catch (IOException e) { } catch (IOException e) {
logger.error("Error on VNC client", e); logger.error("Error on VNC client", e);
@ -154,9 +181,10 @@ public class ConsoleProxyNoVncClient implements ConsoleProxyClient {
worker.start(); worker.start();
} }
private boolean sendReadBytesToNoVNC(byte[] b, int readBytes) { private boolean sendReadBytesToNoVNC(ByteBuffer buffer) {
try { try {
session.getRemote().sendBytes(ByteBuffer.wrap(b, 0, readBytes)); // Buffer is already prepared for reading by flip()
session.getRemote().sendBytes(buffer);
updateFrontEndActivityTime(); updateFrontEndActivityTime();
} catch (WebSocketException | IOException e) { } catch (WebSocketException | IOException e) {
logger.error("VNC server connection exception.", e); logger.error("VNC server connection exception.", e);
@ -316,9 +344,29 @@ public class ConsoleProxyNoVncClient implements ConsoleProxyClient {
this.clientParam = param; this.clientParam = param;
} }
private ByteBuffer getOrCreateReadBuffer() {
if (readBuffer == null) {
readBuffer = ByteBuffer.allocate(ConsoleProxy.defaultBufferSize);
logger.debug("Allocated {} KB read buffer for client [{}]", ConsoleProxy.defaultBufferSize / 1024 , clientId);
// Only apply batching logic for NIO TLS connections to work around 16KB record limitation
// For non-TLS or non-NIO connections, use immediate flush for better responsiveness
if (client != null && client.isVncOverNioSocket() && client.isTLSConnectionEstablished()) {
flushThreshold = Math.min(ConsoleProxy.defaultBufferSize / 4, 2048);
logger.debug("NIO TLS connection detected - using batching with threshold {} for client [{}]", flushThreshold, clientId);
} else {
flushThreshold = ConsoleProxy.defaultBufferSize + 1; // Always flush immediately
logger.debug("Non-TLS or non-NIO connection - using immediate flush for client [{}]", clientId);
}
}
return readBuffer;
}
@Override @Override
public void closeClient() { public void closeClient() {
this.connectionAlive = false; this.connectionAlive = false;
// Clear buffer reference to allow GC when client disconnects
this.readBuffer = null;
ConsoleProxy.removeViewer(this); ConsoleProxy.removeViewer(this);
} }

View File

@ -502,18 +502,14 @@ public class NoVncClient {
return nioSocketConnection.readServerInit(); return nioSocketConnection.readServerInit();
} }
public int getNextBytes() { public int readAvailableDataIntoBuffer(ByteBuffer buffer, int maxSize) {
return nioSocketConnection.readNextBytes(); return nioSocketConnection.readAvailableDataIntoBuffer(buffer, maxSize);
} }
public boolean isTLSConnectionEstablished() { public boolean isTLSConnectionEstablished() {
return nioSocketConnection.isTLSConnection(); return nioSocketConnection.isTLSConnection();
} }
public void readBytes(byte[] arr, int len) {
nioSocketConnection.readNextByteArray(arr, len);
}
public void processHandshakeSecurityType(int secType, String vmPassword, String host, int port) { public void processHandshakeSecurityType(int secType, String vmPassword, String host, int port) {
waitForNoVNCReply(); waitForNoVNCReply();

View File

@ -41,6 +41,8 @@ public class NioSocket {
socketChannel = SocketChannel.open(); socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false); socketChannel.configureBlocking(false);
socketChannel.socket().setSoTimeout(5000); socketChannel.socket().setSoTimeout(5000);
socketChannel.socket().setKeepAlive(true);
socketChannel.socket().setTcpNoDelay(true);
writeSelector = Selector.open(); writeSelector = Selector.open();
readSelector = Selector.open(); readSelector = Selector.open();
socketChannel.register(writeSelector, SelectionKey.OP_WRITE); socketChannel.register(writeSelector, SelectionKey.OP_WRITE);
@ -77,7 +79,6 @@ public class NioSocket {
socketChannel.register(selector, SelectionKey.OP_CONNECT); socketChannel.register(selector, SelectionKey.OP_CONNECT);
waitForSocketSelectorConnected(selector); waitForSocketSelectorConnected(selector);
socketChannel.socket().setTcpNoDelay(false);
} catch (IOException e) { } catch (IOException e) {
logger.error(String.format("Error creating NioSocket to %s:%s: %s", host, port, e.getMessage()), e); logger.error(String.format("Error creating NioSocket to %s:%s: %s", host, port, e.getMessage()), e);
} }

View File

@ -29,8 +29,7 @@ public interface NioSocketHandler {
void readBytes(ByteBuffer data, int length); void readBytes(ByteBuffer data, int length);
String readString(); String readString();
byte[] readServerInit(); byte[] readServerInit();
int readNextBytes(); int readAvailableDataIntoBuffer(ByteBuffer buffer, int maxSize);
void readNextByteArray(byte[] arr, int len);
// Write operations // Write operations
void writeUnsignedInteger(int sizeInBits, int value); void writeUnsignedInteger(int sizeInBits, int value);

View File

@ -17,6 +17,7 @@
package com.cloud.consoleproxy.vnc.network; package com.cloud.consoleproxy.vnc.network;
import com.cloud.consoleproxy.ConsoleProxy;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -28,13 +29,11 @@ public class NioSocketHandlerImpl implements NioSocketHandler {
private NioSocketOutputStream outputStream; private NioSocketOutputStream outputStream;
private boolean isTLS = false; private boolean isTLS = false;
private static final int DEFAULT_BUF_SIZE = 16384;
protected Logger logger = LogManager.getLogger(getClass()); protected Logger logger = LogManager.getLogger(getClass());
public NioSocketHandlerImpl(NioSocket socket) { public NioSocketHandlerImpl(NioSocket socket) {
this.inputStream = new NioSocketInputStream(DEFAULT_BUF_SIZE, socket); this.inputStream = new NioSocketInputStream(ConsoleProxy.defaultBufferSize, socket);
this.outputStream = new NioSocketOutputStream(DEFAULT_BUF_SIZE, socket); this.outputStream = new NioSocketOutputStream(ConsoleProxy.defaultBufferSize, socket);
} }
@Override @Override
@ -97,13 +96,8 @@ public class NioSocketHandlerImpl implements NioSocketHandler {
} }
@Override @Override
public int readNextBytes() { public int readAvailableDataIntoBuffer(ByteBuffer buffer, int maxSize) {
return inputStream.getNextBytes(); return inputStream.readAvailableDataIntoBuffer(buffer, maxSize);
}
@Override
public void readNextByteArray(byte[] arr, int len) {
inputStream.readNextByteArrayFromReadBuffer(arr, len);
} }
@Override @Override

View File

@ -175,28 +175,38 @@ public class NioSocketInputStream extends NioSocketStream {
return ArrayUtils.addAll(ret, (byte) 0, (byte) 0, (byte) 0); return ArrayUtils.addAll(ret, (byte) 0, (byte) 0, (byte) 0);
} }
protected int getNextBytes() { /**
int size = 200; * This method checks what data is immediately available and returns a reasonable amount.
while (size > 0) { *
if (checkForSizeWithoutWait(size)) { * @param maxSize Maximum number of bytes to attempt to read
break; * @return Number of bytes available to read (0 if none available)
} */
size--; protected int getAvailableBytes(int maxSize) {
} // First check if we have data already in our buffer
return size; int bufferedData = endPosition - currentPosition;
if (bufferedData > 0) {
return Math.min(bufferedData, maxSize);
} }
protected void readNextByteArrayFromReadBuffer(byte[] arr, int len) { // Try to read more data with non-blocking call
copyBytesFromReadBuffer(len, arr); // This determines how much data is available
return getReadBytesAvailableToFitSize(1, maxSize, false);
} }
protected void copyBytesFromReadBuffer(int length, byte[] arr) { /**
int ptr = 0; * Read available data directly into a ByteBuffer.
while (length > 0) { *
int n = getReadBytesAvailableToFitSize(1, length, true); * @param buffer ByteBuffer to read data into
readBytes(ByteBuffer.wrap(arr, ptr, n), n); * @param maxSize Maximum number of bytes to read
ptr += n; * @return Number of bytes actually read (0 if none available)
length -= n; */
} protected int readAvailableDataIntoBuffer(ByteBuffer buffer, int maxSize) {
// Get the amount of data available to read
int available = getAvailableBytes(maxSize);
if (available > 0) {
// Read directly into the ByteBuffer
readBytes(buffer, available);
}
return available;
} }
} }

View File

@ -16,6 +16,8 @@
// under the License. // under the License.
package com.cloud.consoleproxy.vnc.network; package com.cloud.consoleproxy.vnc.network;
import com.cloud.consoleproxy.ConsoleProxy;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLException; import javax.net.ssl.SSLException;
@ -43,9 +45,9 @@ public class NioSocketSSLEngineManager {
executor = Executors.newSingleThreadExecutor(); executor = Executors.newSingleThreadExecutor();
int pktBufSize = engine.getSession().getPacketBufferSize(); int networkBufSize = Math.max(engine.getSession().getPacketBufferSize(), ConsoleProxy.defaultBufferSize);
myNetData = ByteBuffer.allocate(pktBufSize); myNetData = ByteBuffer.allocate(networkBufSize);
peerNetData = ByteBuffer.allocate(pktBufSize); peerNetData = ByteBuffer.allocate(networkBufSize);
} }
private void handshakeNeedUnwrap(ByteBuffer peerAppData) throws SSLException { private void handshakeNeedUnwrap(ByteBuffer peerAppData) throws SSLException {
@ -155,22 +157,25 @@ public class NioSocketSSLEngineManager {
} }
public int write(ByteBuffer data) throws IOException { public int write(ByteBuffer data) throws IOException {
int n = 0; int totalBytesConsumed = 0;
int sessionAppBufSize = engine.getSession().getApplicationBufferSize();
boolean shouldBatch = ConsoleProxy.defaultBufferSize > sessionAppBufSize;
while (data.hasRemaining()) { while (data.hasRemaining()) {
SSLEngineResult result = engine.wrap(data, myNetData); SSLEngineResult result = engine.wrap(data, myNetData);
n += result.bytesConsumed(); totalBytesConsumed += result.bytesConsumed();
switch (result.getStatus()) { switch (result.getStatus()) {
case OK: case OK:
myNetData.flip(); // Flush immediately if: batching is disabled, small data, or last chunk
outputStream.writeBytes(myNetData, myNetData.remaining()); if (!shouldBatch || result.bytesConsumed() < sessionAppBufSize || !data.hasRemaining()) {
outputStream.flushWriteBuffer(); flush();
myNetData.compact(); }
// Otherwise accumulate for batching (large chunk with more data coming)
break; break;
case BUFFER_OVERFLOW: case BUFFER_OVERFLOW:
myNetData.flip(); // Flush when buffer is full
outputStream.writeBytes(myNetData, myNetData.remaining()); flush();
myNetData.compact();
break; break;
case CLOSED: case CLOSED:
@ -181,7 +186,16 @@ public class NioSocketSSLEngineManager {
break; break;
} }
} }
return n; return totalBytesConsumed;
}
public void flush() {
if (myNetData.position() > 0) {
myNetData.flip();
outputStream.writeBytes(myNetData, myNetData.remaining());
outputStream.flushWriteBuffer();
myNetData.compact();
}
} }
public SSLSession getSession() { public SSLSession getSession() {

View File

@ -16,6 +16,7 @@
// under the License. // under the License.
package com.cloud.consoleproxy.vnc.network; package com.cloud.consoleproxy.vnc.network;
import com.cloud.consoleproxy.ConsoleProxy;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import java.io.IOException; import java.io.IOException;
@ -26,7 +27,7 @@ public class NioSocketTLSInputStream extends NioSocketInputStream {
private final NioSocketSSLEngineManager sslEngineManager; private final NioSocketSSLEngineManager sslEngineManager;
public NioSocketTLSInputStream(NioSocketSSLEngineManager sslEngineManager, NioSocket socket) { public NioSocketTLSInputStream(NioSocketSSLEngineManager sslEngineManager, NioSocket socket) {
super(sslEngineManager.getSession().getApplicationBufferSize(), socket); super(ConsoleProxy.defaultBufferSize, socket);
this.sslEngineManager = sslEngineManager; this.sslEngineManager = sslEngineManager;
} }

View File

@ -16,6 +16,8 @@
// under the License. // under the License.
package com.cloud.consoleproxy.vnc.network; package com.cloud.consoleproxy.vnc.network;
import com.cloud.consoleproxy.ConsoleProxy;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -24,7 +26,7 @@ public class NioSocketTLSOutputStream extends NioSocketOutputStream {
private final NioSocketSSLEngineManager sslEngineManager; private final NioSocketSSLEngineManager sslEngineManager;
public NioSocketTLSOutputStream(NioSocketSSLEngineManager sslEngineManager, NioSocket socket) { public NioSocketTLSOutputStream(NioSocketSSLEngineManager sslEngineManager, NioSocket socket) {
super(sslEngineManager.getSession().getApplicationBufferSize(), socket); super(ConsoleProxy.defaultBufferSize, socket);
this.sslEngineManager = sslEngineManager; this.sslEngineManager = sslEngineManager;
} }
@ -38,6 +40,7 @@ public class NioSocketTLSOutputStream extends NioSocketOutputStream {
} }
currentPosition = start; currentPosition = start;
sslEngineManager.flush();
} }
protected int writeThroughSSLEngineManager(byte[] data, int startPos, int length) { protected int writeThroughSSLEngineManager(byte[] data, int startPos, int length) {

View File

@ -268,9 +268,6 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName()); private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName());
static final ConfigKey<String> NTPServerConfig = new ConfigKey<String>(String.class, "ntp.server.list", "Advanced", null,
"Comma separated list of NTP servers to configure in Secondary storage VM", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null);
static final ConfigKey<Integer> MaxNumberOfSsvmsForMigration = new ConfigKey<Integer>("Advanced", Integer.class, "max.ssvm.count", "5", static final ConfigKey<Integer> MaxNumberOfSsvmsForMigration = new ConfigKey<Integer>("Advanced", Integer.class, "max.ssvm.count", "5",
"Number of additional SSVMs to handle migration of data objects concurrently", true, ConfigKey.Scope.Global); "Number of additional SSVMs to handle migration of data objects concurrently", true, ConfigKey.Scope.Global);
@ -1178,7 +1175,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password")); buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
} }
if (NTPServerConfig.value() != null) { if (StringUtils.isNotEmpty(NTPServerConfig.value())) {
buf.append(" ntpserverlist=").append(NTPServerConfig.value().replaceAll("\\s+","")); buf.append(" ntpserverlist=").append(NTPServerConfig.value().replaceAll("\\s+",""));
} }

View File

@ -27,6 +27,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import io.netty.util.IllegalReferenceCountException;
import org.apache.cloudstack.storage.template.UploadEntity; import org.apache.cloudstack.storage.template.UploadEntity;
import org.apache.cloudstack.utils.imagestore.ImageStoreUtil; import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -230,9 +231,16 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj
private void reset() { private void reset() {
request = null; request = null;
// destroy the decoder to release all resources // destroy the decoder to release all resources
if (decoder != null) {
try {
decoder.destroy(); decoder.destroy();
} catch (IllegalReferenceCountException e) {
logger.warn("Decoder already destroyed", e);
}
decoder = null; decoder = null;
} }
}
private HttpResponseStatus readFileUploadData() throws IOException { private HttpResponseStatus readFileUploadData() throws IOException {
while (decoder.hasNext()) { while (decoder.hasNext()) {

View File

@ -21,3 +21,4 @@ consoleproxy.httpCmdListenPort=8001
consoleproxy.jarDir=./applet/ consoleproxy.jarDir=./applet/
consoleproxy.viewerLinger=180 consoleproxy.viewerLinger=180
consoleproxy.reconnectMaxRetry=5 consoleproxy.reconnectMaxRetry=5
consoleproxy.defaultBufferSize=65536

View File

@ -683,7 +683,7 @@ getPublicIp() {
setup_ntp() { setup_ntp() {
log_it "Setting up NTP" log_it "Setting up NTP"
NTP_CONF_FILE="/etc/ntp.conf" NTP_CONF_FILE="/etc/ntpsec/ntp.conf"
if [ -f $NTP_CONF_FILE ] if [ -f $NTP_CONF_FILE ]
then then
IFS=',' read -a server_list <<< "$NTP_SERVER_LIST" IFS=',' read -a server_list <<< "$NTP_SERVER_LIST"
@ -694,7 +694,7 @@ setup_ntp() {
PATTERN="server $server" PATTERN="server $server"
sed -i "0,/^# server/s//$PATTERN\n# server/" $NTP_CONF_FILE sed -i "0,/^# server/s//$PATTERN\n# server/" $NTP_CONF_FILE
done done
systemctl enable ntp systemctl enable --now --no-block ntp
else else
log_it "NTP configuration file not found" log_it "NTP configuration file not found"
fi fi

View File

@ -40,6 +40,10 @@ setup_console_proxy() {
disable_rpfilter disable_rpfilter
enable_fwding 0 enable_fwding 0
enable_irqbalance 0 enable_irqbalance 0
if [[ -n "$NTP_SERVER_LIST" ]]; then
setup_ntp
systemctl restart ntp
fi
rm -f /etc/logrotate.d/cloud rm -f /etc/logrotate.d/cloud
} }

View File

@ -82,6 +82,7 @@ HTTP
enable_fwding 0 enable_fwding 0
enable_irqbalance 0 enable_irqbalance 0
setup_ntp setup_ntp
systemctl restart ntp
rm -f /etc/logrotate.d/cloud rm -f /etc/logrotate.d/cloud
} }

View File

@ -953,9 +953,72 @@ class TestLinstorVolumes(cloudstackTestCase):
snapshot.delete(self.apiClient) snapshot.delete(self.apiClient)
@attr(tags=['basic'], required_hardware=False)
def test_10_create_template_from_snapshot(self):
"""
Create a template from a snapshot and start an instance from it
"""
self.virtual_machine.stop(self.apiClient)
volume = list_volumes(
self.apiClient,
virtualmachineid = self.virtual_machine.id,
type = "ROOT",
listall = True,
)
snapshot = Snapshot.create(
self.apiClient,
volume_id=volume[0].id,
account=self.account.name,
domainid=self.domain.id,
)
self.cleanup.append(snapshot)
self.assertIsNotNone(snapshot, "Could not create snapshot")
services = {
"displaytext": "IntegrationTestTemplate",
"name": "int-test-template",
"ostypeid": self.template.ostypeid,
"ispublic": "true"
}
custom_template = Template.create_from_snapshot(
self.apiClient,
snapshot,
services,
)
self.cleanup.append(custom_template)
# create VM from custom template
test_virtual_machine = VirtualMachine.create(
self.apiClient,
self.testdata[TestData.virtualMachine2],
accountid=self.account.name,
zoneid=self.zone.id,
serviceofferingid=self.compute_offering.id,
templateid=custom_template.id,
domainid=self.domain.id,
startvm=False,
mode='basic',
)
self.cleanup.append(test_virtual_machine)
TestLinstorVolumes._start_vm(test_virtual_machine)
test_virtual_machine.stop(self.apiClient)
test_virtual_machine.delete(self.apiClient, True)
self.cleanup.remove(test_virtual_machine)
custom_template.delete(self.apiClient)
self.cleanup.remove(custom_template)
snapshot.delete(self.apiClient)
self.cleanup.remove(snapshot)
@attr(tags=['advanced', 'migration'], required_hardware=False) @attr(tags=['advanced', 'migration'], required_hardware=False)
def test_10_migrate_volume_to_same_instance_pool(self): def test_11_migrate_volume_to_same_instance_pool(self):
"""Migrate volume to the same instance pool""" """Migrate volume to the same instance pool"""
if not self.testdata[TestData.migrationTests]: if not self.testdata[TestData.migrationTests]:
@ -1088,7 +1151,7 @@ class TestLinstorVolumes(cloudstackTestCase):
test_virtual_machine.delete(self.apiClient, True) test_virtual_machine.delete(self.apiClient, True)
@attr(tags=['advanced', 'migration'], required_hardware=False) @attr(tags=['advanced', 'migration'], required_hardware=False)
def test_11_migrate_volume_to_distinct_instance_pool(self): def test_12_migrate_volume_to_distinct_instance_pool(self):
"""Migrate volume to distinct instance pool""" """Migrate volume to distinct instance pool"""
if not self.testdata[TestData.migrationTests]: if not self.testdata[TestData.migrationTests]:
@ -1221,7 +1284,7 @@ class TestLinstorVolumes(cloudstackTestCase):
test_virtual_machine.delete(self.apiClient, True) test_virtual_machine.delete(self.apiClient, True)
@attr(tags=["basic"], required_hardware=False) @attr(tags=["basic"], required_hardware=False)
def test_12_create_vm_snapshots(self): def test_13_create_vm_snapshots(self):
"""Test to create VM snapshots """Test to create VM snapshots
""" """
vm = TestLinstorVolumes._start_vm(self.virtual_machine) vm = TestLinstorVolumes._start_vm(self.virtual_machine)
@ -1251,7 +1314,7 @@ class TestLinstorVolumes(cloudstackTestCase):
) )
@attr(tags=["basic"], required_hardware=False) @attr(tags=["basic"], required_hardware=False)
def test_13_revert_vm_snapshots(self): def test_14_revert_vm_snapshots(self):
"""Test to revert VM snapshots """Test to revert VM snapshots
""" """
@ -1313,7 +1376,7 @@ class TestLinstorVolumes(cloudstackTestCase):
) )
@attr(tags=["basic"], required_hardware=False) @attr(tags=["basic"], required_hardware=False)
def test_14_delete_vm_snapshots(self): def test_15_delete_vm_snapshots(self):
"""Test to delete vm snapshots """Test to delete vm snapshots
""" """

View File

@ -14,12 +14,12 @@
"label.account.specific": "Account-Specific", "label.account.specific": "Account-Specific",
"label.accounts": "Accounts", "label.accounts": "Accounts",
"label.accounttype": "Account Type", "label.accounttype": "Account Type",
"label.acl.export": "Export ACLs", "label.acl.export": "Export ACL rules",
"label.acl.id": "ACL ID", "label.acl.id": "ACL ID",
"label.acl.list.rules": "ACL List Rules", "label.acl.rules": "ACL Rules",
"label.acl.reason.description": "Enter the reason behind an ACL rule.", "label.acl.reason.description": "Enter the reason behind an ACL rule.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "ACL Name", "label.acl.rule.name": "ACL Name",
"label.acquire.new.ip": "Acquire New IP", "label.acquire.new.ip": "Acquire New IP",
"label.acquire.new.secondary.ip": "Acquire new secondary IP", "label.acquire.new.secondary.ip": "Acquire new secondary IP",
"label.action": "Action", "label.action": "Action",
@ -119,8 +119,8 @@
"label.activeviewersessions": "Active Sessions", "label.activeviewersessions": "Active Sessions",
"label.add": "Add", "label.add": "Add",
"label.add.account": "Add Account", "label.add.account": "Add Account",
"label.add.acl": "\u0625\u0636\u0627\u0641\u0629 ACL", "label.add.acl.rule": "\u0625\u0636\u0627\u0641\u0629 ACL",
"label.add.acl.list": "Add ACL List", "label.add.acl": "Add ACL",
"label.add.affinity.group": "Add new affinity group", "label.add.affinity.group": "Add new affinity group",
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device", "label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
"label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller", "label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller",
@ -142,12 +142,12 @@
"label.add.ip.range": "Add IP Range", "label.add.ip.range": "Add IP Range",
"label.add.isolated.network": "Add Isolated Network", "label.add.isolated.network": "Add Isolated Network",
"label.add.ldap.account": "Add LDAP account", "label.add.ldap.account": "Add LDAP account",
"label.add.list.name": "ACL List Name", "label.add.acl.name": "ACL Name",
"label.add.more": "Add More", "label.add.more": "Add More",
"label.add.netscaler.device": "Add Netscaler device", "label.add.netscaler.device": "Add Netscaler device",
"label.add.network": "Add Network", "label.add.network": "Add Network",
"label.add.network.acl": "\u0625\u0636\u0627\u0641\u0629 \u0634\u0628\u0643\u0629 ACL", "label.add.network.acl": "\u0625\u0636\u0627\u0641\u0629 \u0634\u0628\u0643\u0629 ACL",
"label.add.network.acl.list": "Add Network ACL List", "label.add.network.acl": "Add Network ACL",
"label.add.network.offering": "Add network offering", "label.add.network.offering": "Add network offering",
"label.add.new.gateway": "\u0623\u0636\u0641 \u0628\u0648\u0627\u0628\u0629 \u062c\u062f\u064a\u062f\u0629", "label.add.new.gateway": "\u0623\u0636\u0641 \u0628\u0648\u0627\u0628\u0629 \u062c\u062f\u064a\u062f\u0629",
"label.add.new.tier": "\u0625\u0636\u0627\u0641\u0629 \u0637\u0628\u0642\u0629 \u062c\u062f\u064a\u062f\u0629", "label.add.new.tier": "\u0625\u0636\u0627\u0641\u0629 \u0637\u0628\u0642\u0629 \u062c\u062f\u064a\u062f\u0629",
@ -334,7 +334,7 @@
"label.default.use": "Default Use", "label.default.use": "Default Use",
"label.default.view": "\u0637\u0631\u064a\u0642\u0629 \u0627\u0644\u0639\u0631\u0636 \u0627\u0644\u0627\u0641\u062a\u0631\u0627\u0636\u064a\u0629", "label.default.view": "\u0637\u0631\u064a\u0642\u0629 \u0627\u0644\u0639\u0631\u0636 \u0627\u0644\u0627\u0641\u062a\u0631\u0627\u0636\u064a\u0629",
"label.delete": "Delete", "label.delete": "Delete",
"label.delete.acl.list": "Delete ACL List", "label.delete.acl": "Delete ACL",
"label.delete.affinity.group": "Delete Affinity Group", "label.delete.affinity.group": "Delete Affinity Group",
"label.delete.alerts": "Delete alerts", "label.delete.alerts": "Delete alerts",
"label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller", "label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller",
@ -419,7 +419,7 @@
"label.dpd": "\u0643\u0634\u0641 \u0627\u0644\u0642\u0631\u064a\u0646 \u0627\u0644\u0645\u0641\u0642\u0648\u062f", "label.dpd": "\u0643\u0634\u0641 \u0627\u0644\u0642\u0631\u064a\u0646 \u0627\u0644\u0645\u0641\u0642\u0648\u062f",
"label.driver": "Driver", "label.driver": "Driver",
"label.edit": "Edit", "label.edit": "Edit",
"label.edit.acl.list": "Edit ACL List", "label.edit.acl": "Edit ACL",
"label.edit.acl.rule": "Edit ACL rule", "label.edit.acl.rule": "Edit ACL rule",
"label.edit.project.details": "\u0627\u0636\u0627\u0641\u0629 \u062a\u0641\u0627\u0635\u064a\u0644 \u0627\u0644\u0645\u0634\u0631\u0648\u0639", "label.edit.project.details": "\u0627\u0636\u0627\u0641\u0629 \u062a\u0641\u0627\u0635\u064a\u0644 \u0627\u0644\u0645\u0634\u0631\u0648\u0639",
"label.edit.role": "Edit Role", "label.edit.role": "Edit Role",
@ -924,7 +924,6 @@
"label.remove.vpc.offering": "Remove VPC offering", "label.remove.vpc.offering": "Remove VPC offering",
"label.removing": "Removing", "label.removing": "Removing",
"label.replace.acl": "Replace ACL", "label.replace.acl": "Replace ACL",
"label.replace.acl.list": "Replace ACL List",
"label.required": "Required", "label.required": "Required",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
"label.requiresupgrade": "Requires Upgrade", "label.requiresupgrade": "Requires Upgrade",
@ -1150,8 +1149,7 @@
"label.usehttps": "\u0627\u0633\u062a\u062e\u062f\u0645 HTTPS", "label.usehttps": "\u0627\u0633\u062a\u062e\u062f\u0645 HTTPS",
"label.usenewdiskoffering": "Replace disk offering?", "label.usenewdiskoffering": "Replace disk offering?",
"label.user": "User", "label.user": "User",
"label.userdata": "Userdata", "label.user.data": "User Data",
"label.userdatal2": "User Data",
"label.username": "Username", "label.username": "Username",
"label.users": "Users", "label.users": "Users",
"label.utilization": "Utilisation", "label.utilization": "Utilisation",
@ -1329,7 +1327,7 @@
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts", "message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events", "message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
"message.confirm.attach.disk": "Are you sure you want to attach disk?", "message.confirm.attach.disk": "Are you sure you want to attach disk?",
"message.confirm.delete.acl.list": "Are you sure you want to delete this ACL list?", "message.confirm.delete.acl": "Are you sure you want to delete this ACL?",
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller", "message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch", "message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v", "message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",

View File

@ -14,12 +14,12 @@
"label.account.specific": "Account-Specific", "label.account.specific": "Account-Specific",
"label.accounts": "Accounts", "label.accounts": "Accounts",
"label.accounttype": "Account Type", "label.accounttype": "Account Type",
"label.acl.export": "Export ACLs", "label.acl.export": "Export ACL rules",
"label.acl.id": "ACL ID", "label.acl.id": "ACL ID",
"label.acl.list.rules": "ACL List Rules", "label.acl.rules": "ACL Rules",
"label.acl.reason.description": "Enter the reason behind an ACL rule.", "label.acl.reason.description": "Enter the reason behind an ACL rule.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "ACL Name", "label.acl.rule.name": "ACL Name",
"label.acquire.new.ip": "Acquire New IP", "label.acquire.new.ip": "Acquire New IP",
"label.acquire.new.secondary.ip": "Acquire new secondary IP", "label.acquire.new.secondary.ip": "Acquire new secondary IP",
"label.action": "Action", "label.action": "Action",
@ -119,8 +119,8 @@
"label.activeviewersessions": "Active Sessions", "label.activeviewersessions": "Active Sessions",
"label.add": "Add", "label.add": "Add",
"label.add.account": "Add Account", "label.add.account": "Add Account",
"label.add.acl.rule": "Add ACL rule",
"label.add.acl": "Add ACL", "label.add.acl": "Add ACL",
"label.add.acl.list": "Add ACL List",
"label.add.affinity.group": "Add new affinity group", "label.add.affinity.group": "Add new affinity group",
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device", "label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
"label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller", "label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller",
@ -142,12 +142,12 @@
"label.add.ip.range": "Add IP Range", "label.add.ip.range": "Add IP Range",
"label.add.isolated.network": "Add Isolated Network", "label.add.isolated.network": "Add Isolated Network",
"label.add.ldap.account": "Add LDAP account", "label.add.ldap.account": "Add LDAP account",
"label.add.list.name": "ACL List Name", "label.add.acl.name": "ACL Name",
"label.add.more": "Add More", "label.add.more": "Add More",
"label.add.netscaler.device": "Add Netscaler device", "label.add.netscaler.device": "Add Netscaler device",
"label.add.network": "Add Network", "label.add.network": "Add Network",
"label.add.network.acl": "Add network ACL", "label.add.network.acl": "Add network ACL",
"label.add.network.acl.list": "Add Network ACL List", "label.add.network.acl": "Add Network ACL",
"label.add.network.offering": "Add network offering", "label.add.network.offering": "Add network offering",
"label.add.new.gateway": "Add new gateway", "label.add.new.gateway": "Add new gateway",
"label.add.new.tier": "Add new tier", "label.add.new.tier": "Add new tier",
@ -334,7 +334,7 @@
"label.default.use": "Default Use", "label.default.use": "Default Use",
"label.default.view": "Default View", "label.default.view": "Default View",
"label.delete": "Delete", "label.delete": "Delete",
"label.delete.acl.list": "Delete ACL List", "label.delete.acl": "Delete ACL",
"label.delete.affinity.group": "Delete Affinity Group", "label.delete.affinity.group": "Delete Affinity Group",
"label.delete.alerts": "Delete alerts", "label.delete.alerts": "Delete alerts",
"label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller", "label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller",
@ -419,7 +419,7 @@
"label.dpd": "Dead Peer Detection", "label.dpd": "Dead Peer Detection",
"label.driver": "Driver", "label.driver": "Driver",
"label.edit": "Edit", "label.edit": "Edit",
"label.edit.acl.list": "Edit ACL List", "label.edit.acl": "Edit ACL",
"label.edit.acl.rule": "Edit ACL rule", "label.edit.acl.rule": "Edit ACL rule",
"label.edit.project.details": "Editar detalls del projecte", "label.edit.project.details": "Editar detalls del projecte",
"label.edit.role": "Edit Role", "label.edit.role": "Edit Role",
@ -924,7 +924,6 @@
"label.remove.vpc.offering": "Remove VPC offering", "label.remove.vpc.offering": "Remove VPC offering",
"label.removing": "Esborrant", "label.removing": "Esborrant",
"label.replace.acl": "Replace ACL", "label.replace.acl": "Replace ACL",
"label.replace.acl.list": "Replace ACL List",
"label.required": "Required", "label.required": "Required",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
"label.requiresupgrade": "Requires Upgrade", "label.requiresupgrade": "Requires Upgrade",
@ -1150,8 +1149,7 @@
"label.usehttps": "Use HTTPS", "label.usehttps": "Use HTTPS",
"label.usenewdiskoffering": "Replace disk offering?", "label.usenewdiskoffering": "Replace disk offering?",
"label.user": "User", "label.user": "User",
"label.userdata": "Userdata", "label.user.data": "User Data",
"label.userdatal2": "User Data",
"label.username": "Username", "label.username": "Username",
"label.users": "Users", "label.users": "Users",
"label.utilization": "Utilisation", "label.utilization": "Utilisation",
@ -1329,7 +1327,7 @@
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts", "message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events", "message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
"message.confirm.attach.disk": "Are you sure you want to attach disk?", "message.confirm.attach.disk": "Are you sure you want to attach disk?",
"message.confirm.delete.acl.list": "Are you sure you want to delete this ACL list?", "message.confirm.delete.acl": "Are you sure you want to delete this ACL?",
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller", "message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch", "message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v", "message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",

View File

@ -26,12 +26,12 @@
"label.account.specific": "Besonderheiten des Benutzerkontos", "label.account.specific": "Besonderheiten des Benutzerkontos",
"label.accounts": "Benutzerkonten", "label.accounts": "Benutzerkonten",
"label.accounttype": "Benutzerkontotyp", "label.accounttype": "Benutzerkontotyp",
"label.acl.export": "Export ACLs", "label.acl.export": "Export ACL rules",
"label.acl.id": "ACL-Kennung", "label.acl.id": "ACL-Kennung",
"label.acl.list.rules": "ACL-Listenregeln", "label.acl.rules": "ACL-Listenregeln",
"label.acl.reason.description": "Enter the reason behind an ACL rule.", "label.acl.reason.description": "Enter the reason behind an ACL rule.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "ACL-Name", "label.acl.rule.name": "ACL-Name",
"label.acquire.new.ip": "Neue IP erwerben", "label.acquire.new.ip": "Neue IP erwerben",
"label.acquire.new.secondary.ip": "Neue sekundäre IP anfordern", "label.acquire.new.secondary.ip": "Neue sekundäre IP anfordern",
"label.acquiring.ip": "IP anfordern", "label.acquiring.ip": "IP anfordern",
@ -144,8 +144,8 @@
"label.activeviewersessions": "Aktive Sitzungen", "label.activeviewersessions": "Aktive Sitzungen",
"label.add": "Hinzufügen", "label.add": "Hinzufügen",
"label.add.account": "Konto hinzufügen", "label.add.account": "Konto hinzufügen",
"label.add.acl": "ACL hinzufügen", "label.add.acl.rule": "ACL hinzufügen",
"label.add.acl.list": "ACL-Liste hinzufügen", "label.add.acl": "ACL-Liste hinzufügen",
"label.add.affinity.group": "Neue Affinitätsgruppe hinzufügen", "label.add.affinity.group": "Neue Affinitätsgruppe hinzufügen",
"label.add.baremetal.dhcp.device": "Baremetal DHCP-Gerät hinzufügen", "label.add.baremetal.dhcp.device": "Baremetal DHCP-Gerät hinzufügen",
"label.add.bigswitchbcf.device": "Füge BigSwitch BCF Controller hinzu", "label.add.bigswitchbcf.device": "Füge BigSwitch BCF Controller hinzu",
@ -169,12 +169,12 @@
"label.add.isolated.network": "Isoliertes Netzwerk hinzufügen", "label.add.isolated.network": "Isoliertes Netzwerk hinzufügen",
"label.add.kubernetes.cluster": "Kubernetes Cluster hinzufügen", "label.add.kubernetes.cluster": "Kubernetes Cluster hinzufügen",
"label.add.ldap.account": "LDAP-Konto hinzufügen", "label.add.ldap.account": "LDAP-Konto hinzufügen",
"label.add.list.name": "ACL-Listename", "label.add.acl.name": "ACL-Listename",
"label.add.more": "Mehr hinzufügen", "label.add.more": "Mehr hinzufügen",
"label.add.netscaler.device": "Netscaler-Gerät hinzufügen", "label.add.netscaler.device": "Netscaler-Gerät hinzufügen",
"label.add.network": "Netzwerk hinzufügen", "label.add.network": "Netzwerk hinzufügen",
"label.add.network.acl": "Netzwerk-ACL hinzufügen", "label.add.network.acl": "Netzwerk-ACL hinzufügen",
"label.add.network.acl.list": "Netzwerk-ACL-Liste hinzufügen", "label.add.network.acl": "Netzwerk-ACL-Liste hinzufügen",
"label.add.network.offering": "Netzwerkangebot hinzufügen", "label.add.network.offering": "Netzwerkangebot hinzufügen",
"label.add.new.gateway": "Neues Gateway hinzufügen", "label.add.new.gateway": "Neues Gateway hinzufügen",
"label.add.new.tier": "Neue Ebene hinzufügen", "label.add.new.tier": "Neue Ebene hinzufügen",
@ -417,7 +417,7 @@
"label.default.view": "Standardansicht", "label.default.view": "Standardansicht",
"label.defaultnetwork": "Standard-Netzwerk", "label.defaultnetwork": "Standard-Netzwerk",
"label.delete": "Löschen", "label.delete": "Löschen",
"label.delete.acl.list": "ACL-Liste ersetzen", "label.delete.acl": "ACL-Liste ersetzen",
"label.delete.affinity.group": "Affinitätsgruppe entfernen", "label.delete.affinity.group": "Affinitätsgruppe entfernen",
"label.delete.alerts": "Alarme löschen", "label.delete.alerts": "Alarme löschen",
"label.delete.backup": "Backup löschen", "label.delete.backup": "Backup löschen",
@ -525,7 +525,7 @@
"label.driver": "Treiber", "label.driver": "Treiber",
"label.dynamicscalingenabled": "Dynamische Skalierung aktiviert", "label.dynamicscalingenabled": "Dynamische Skalierung aktiviert",
"label.edit": "Bearbeiten", "label.edit": "Bearbeiten",
"label.edit.acl.list": "Edit ACL List", "label.edit.acl": "Edit ACL",
"label.edit.acl.rule": "ACL-Regel bearbeiten", "label.edit.acl.rule": "ACL-Regel bearbeiten",
"label.edit.project.details": "Projektdetails bearbeiten", "label.edit.project.details": "Projektdetails bearbeiten",
"label.edit.role": "Rolle bearbeiten", "label.edit.role": "Rolle bearbeiten",
@ -948,7 +948,7 @@
"label.netscaler.vpx": "NetScaler VPX LoadBalancer", "label.netscaler.vpx": "NetScaler VPX LoadBalancer",
"label.network": "Netzwerk", "label.network": "Netzwerk",
"label.network.acl": "Netzwerk-ACL", "label.network.acl": "Netzwerk-ACL",
"label.network.acl.lists": "Netzwerk ACL Listen", "label.network.acls": "Netzwerk ACL Listen",
"label.network.addvm": "Netzwerk zur VM hinzufügen", "label.network.addvm": "Netzwerk zur VM hinzufügen",
"label.network.desc": "Netzwerkbeschreibung", "label.network.desc": "Netzwerkbeschreibung",
"label.network.domain": "Netzwerk-Domain", "label.network.domain": "Netzwerk-Domain",
@ -1198,7 +1198,6 @@
"label.remove.vpc.offering": "VPC-Angebot entfernen", "label.remove.vpc.offering": "VPC-Angebot entfernen",
"label.removing": "am Entfernen", "label.removing": "am Entfernen",
"label.replace.acl": "ACL ersetzen", "label.replace.acl": "ACL ersetzen",
"label.replace.acl.list": "ACL-Liste ersetzen",
"label.report.bug": "Fehler melden", "label.report.bug": "Fehler melden",
"label.required": "Erforderlich", "label.required": "Erforderlich",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
@ -1492,8 +1491,7 @@
"label.usenewdiskoffering": "Replace disk offering?", "label.usenewdiskoffering": "Replace disk offering?",
"label.user": "Benutzer", "label.user": "Benutzer",
"label.user.conflict": "Konflikt", "label.user.conflict": "Konflikt",
"label.userdata": "Benutzerdaten", "label.user.data": "Benutzerdaten",
"label.userdatal2": "Benutzerdaten",
"label.username": "Benutzername", "label.username": "Benutzername",
"label.users": "Benutzer", "label.users": "Benutzer",
"label.usersource": "Benutzertyp", "label.usersource": "Benutzertyp",
@ -1733,7 +1731,7 @@
"message.confirm.archive.selected.alerts": "Bitte bestätigen Sie, dass Sie die ausgewählten Alarme archivieren möchten", "message.confirm.archive.selected.alerts": "Bitte bestätigen Sie, dass Sie die ausgewählten Alarme archivieren möchten",
"message.confirm.archive.selected.events": "Bitte bestätigen Sie, dass Sie die ausgewählten Vorgänge archivieren möchten", "message.confirm.archive.selected.events": "Bitte bestätigen Sie, dass Sie die ausgewählten Vorgänge archivieren möchten",
"message.confirm.attach.disk": "Sind Sie sicher, dass Sie eine Platte hinzufügen möchten?", "message.confirm.attach.disk": "Sind Sie sicher, dass Sie eine Platte hinzufügen möchten?",
"message.confirm.delete.acl.list": "Sind Sie sicher, dass Sie diese ACL-Liste löschen möchten?", "message.confirm.delete.acl": "Sind Sie sicher, dass Sie diese ACL-Liste löschen möchten?",
"message.confirm.delete.bigswitchbcf": "Bitte bestätigen Sie, dass Sie diesen BigSwitch BCF Controller löschen möchten", "message.confirm.delete.bigswitchbcf": "Bitte bestätigen Sie, dass Sie diesen BigSwitch BCF Controller löschen möchten",
"message.confirm.delete.brocadevcs": "Bitte bestätigen Sie, dass Sie Brocade Vcs Switch löschen möchten", "message.confirm.delete.brocadevcs": "Bitte bestätigen Sie, dass Sie Brocade Vcs Switch löschen möchten",
"message.confirm.delete.ciscoasa1000v": "Bitte bestätigen Sie, dass Sie CiscoASA1000v löschen möchten", "message.confirm.delete.ciscoasa1000v": "Bitte bestätigen Sie, dass Sie CiscoASA1000v löschen möchten",

View File

@ -33,10 +33,10 @@
"label.access.kubernetes.nodes": "Πρόσβαση στους κόμβους Κυβερνητών", "label.access.kubernetes.nodes": "Πρόσβαση στους κόμβους Κυβερνητών",
"label.acl.export": "Εξαγωγή Λίστας Πρόσβασης", "label.acl.export": "Εξαγωγή Λίστας Πρόσβασης",
"label.acl.id": "Αναγνωριστικό Λίστας Πρόσβασης", "label.acl.id": "Αναγνωριστικό Λίστας Πρόσβασης",
"label.acl.list.rules": "Κανόνες λίστας Πρόσωασης", "label.acl.rules": "Κανόνες λίστας Πρόσωασης",
"label.acl.reason.description": "Εισαγάγετε αιτιολογία για τον κανόνα", "label.acl.reason.description": "Εισαγάγετε αιτιολογία για τον κανόνα",
"label.aclid": "Λίστα πρόσβασης", "label.aclid": "Λίστα πρόσβασης",
"label.aclname": "Όνομα Λίστας Πρόσβασης", "label.acl.rule.name": "Όνομα Λίστας Πρόσβασης",
"label.acquire.new.ip": "Απόκτηση νέας διεύθυνση IP", "label.acquire.new.ip": "Απόκτηση νέας διεύθυνση IP",
"label.acquire.new.secondary.ip": "Απόκτηση νέας δευτερεύουσας διεύθυνσης IP", "label.acquire.new.secondary.ip": "Απόκτηση νέας δευτερεύουσας διεύθυνσης IP",
"label.acquiring.ip": "Απόδοση IP", "label.acquiring.ip": "Απόδοση IP",
@ -173,7 +173,7 @@
"label.action.unmanage.virtualmachine": "Μη διαχείριση εικονικής μηχανής", "label.action.unmanage.virtualmachine": "Μη διαχείριση εικονικής μηχανής",
"label.action.update.offering.access": "Ενημέρωση πρόσβασης για προσφορές", "label.action.update.offering.access": "Ενημέρωση πρόσβασης για προσφορές",
"label.action.update.resource.count": "Ενημέρωση πλήθους πόρων", "label.action.update.resource.count": "Ενημέρωση πλήθους πόρων",
"label.action.userdata.reset": "Επαναφορά δεδομένων χρήστη", "label.action.user.data.reset": "Επαναφορά δεδομένων χρήστη",
"label.action.vmsnapshot.create": "Λήψη στιγμιότυπου εικονικής μηχανής", "label.action.vmsnapshot.create": "Λήψη στιγμιότυπου εικονικής μηχανής",
"label.action.vmsnapshot.delete": "Διαγραφή στιγμιότυπου εικονικής μηχανής", "label.action.vmsnapshot.delete": "Διαγραφή στιγμιότυπου εικονικής μηχανής",
"label.action.vmsnapshot.revert": "Επαναφορά στο στιγμιότυπο εικονικής μηχανής", "label.action.vmsnapshot.revert": "Επαναφορά στο στιγμιότυπο εικονικής μηχανής",
@ -183,8 +183,8 @@
"label.activeviewersessions": "Ενεργές περίοδοι λειτουργίας", "label.activeviewersessions": "Ενεργές περίοδοι λειτουργίας",
"label.add": "Προσθήκη", "label.add": "Προσθήκη",
"label.add.account": "Προσθήκη λογαριασμού", "label.add.account": "Προσθήκη λογαριασμού",
"label.add.acl": "Προσθήκη εγγραφής στην λίστα πρόσβασης", "label.add.acl.rule": "Προσθήκη εγγραφής στην λίστα πρόσβασης",
"label.add.acl.list": "Προσθήκη λίστας πρόσβασης", "label.add.acl": "Προσθήκη λίστας πρόσβασης",
"label.add.affinity.group": "Προσθήκη νέας ομάδας συνάφειας", "label.add.affinity.group": "Προσθήκη νέας ομάδας συνάφειας",
"label.add.baremetal.dhcp.device": "Προσθήκη συσκευής DHCP baremetal", "label.add.baremetal.dhcp.device": "Προσθήκη συσκευής DHCP baremetal",
"label.add.bigswitchbcf.device": "Προσθήκη ελεγκτή BCF BigSwitch", "label.add.bigswitchbcf.device": "Προσθήκη ελεγκτή BCF BigSwitch",
@ -209,12 +209,12 @@
"label.add.isolated.network": "Προσθήκη απομονωμένου δικτύου", "label.add.isolated.network": "Προσθήκη απομονωμένου δικτύου",
"label.add.kubernetes.cluster": "Προσθήκη ομάδας Κυβερνητών", "label.add.kubernetes.cluster": "Προσθήκη ομάδας Κυβερνητών",
"label.add.ldap.account": "Προσθήκη λογαριασμού LDAP", "label.add.ldap.account": "Προσθήκη λογαριασμού LDAP",
"label.add.list.name": "Όνομα λίστας Πρόσβασης", "label.add.acl.name": "Όνομα λίστας Πρόσβασης",
"label.add.more": "Προσθήκη περισσότερων", "label.add.more": "Προσθήκη περισσότερων",
"label.add.netscaler.device": "Προσθήκη συσκευής Netsccaler", "label.add.netscaler.device": "Προσθήκη συσκευής Netsccaler",
"label.add.network": "Προσθήκη δικτύου", "label.add.network": "Προσθήκη δικτύου",
"label.add.network.acl": "Προσθήκη εγγραφής πρόσβασης δικτύου", "label.add.network.acl": "Προσθήκη εγγραφής πρόσβασης δικτύου",
"label.add.network.acl.list": "Προσθήκη λίστας πρόσβασης δικτύου", "label.add.network.acl": "Προσθήκη λίστας πρόσβασης δικτύου",
"label.add.network.offering": "Προσθήκη προσφοράς υπηρεσίας δικτύου", "label.add.network.offering": "Προσθήκη προσφοράς υπηρεσίας δικτύου",
"label.add.network.permission": "Προσθήκη δικαιωμάτων δικτύου", "label.add.network.permission": "Προσθήκη δικαιωμάτων δικτύου",
"label.add.new.gateway": "Προσθήκη νέας πύλης", "label.add.new.gateway": "Προσθήκη νέας πύλης",
@ -516,7 +516,7 @@
"label.default.view": "Προεπιλεγμένη προβολή", "label.default.view": "Προεπιλεγμένη προβολή",
"label.defaultnetwork": "Προεπιλεγμένο δίκτυο", "label.defaultnetwork": "Προεπιλεγμένο δίκτυο",
"label.delete": "Διαγραφή", "label.delete": "Διαγραφή",
"label.delete.acl.list": "Διαγραφή λίστας πρόσβασης", "label.delete.acl": "Διαγραφή λίστας πρόσβασης",
"label.delete.affinity.group": "Διαγραφή ομάδας συνάφειας", "label.delete.affinity.group": "Διαγραφή ομάδας συνάφειας",
"label.delete.alerts": "Διαγραφή ειδοποιήσεων", "label.delete.alerts": "Διαγραφή ειδοποιήσεων",
"label.delete.backup": "Διαγραφή αντιγράφου ασφαλείας", "label.delete.backup": "Διαγραφή αντιγράφου ασφαλείας",
@ -649,7 +649,7 @@
"label.dynamicscalingenabled": "Δυναμική αναπροσαρμογή Ενεργοποίημένη", "label.dynamicscalingenabled": "Δυναμική αναπροσαρμογή Ενεργοποίημένη",
"label.dynamicscalingenabled.tooltip": "Η εικονική μηχανή μπορεί να αναπροσαρμόζεται δυναμικά μόνο αν το πρότυπο, η προσφερόμενη υπηρεσία και οι γενικές ρυθμίσεις έχουν την επιλογή δυναμικής αναπροσαρμογής ενεργοποιήμενη.", "label.dynamicscalingenabled.tooltip": "Η εικονική μηχανή μπορεί να αναπροσαρμόζεται δυναμικά μόνο αν το πρότυπο, η προσφερόμενη υπηρεσία και οι γενικές ρυθμίσεις έχουν την επιλογή δυναμικής αναπροσαρμογής ενεργοποιήμενη.",
"label.edit": "Επεξεργασία", "label.edit": "Επεξεργασία",
"label.edit.acl.list": "Επεξεργασία λίστας Πρόσβασης", "label.edit.acl": "Επεξεργασία λίστας Πρόσβασης",
"label.edit.acl.rule": "Επεξεργασία κανόνα Λίστας Πρόσβασης", "label.edit.acl.rule": "Επεξεργασία κανόνα Λίστας Πρόσβασης",
"label.edit.project.details": "Επεξεργασία λεπτομερειών έργου", "label.edit.project.details": "Επεξεργασία λεπτομερειών έργου",
"label.edit.project.role": "Επεξεργασία ρόλου έργου", "label.edit.project.role": "Επεξεργασία ρόλου έργου",
@ -1142,7 +1142,7 @@
"label.netscaler.vpx": "Εξισορρόπηση φόρτου VPX του NetScaler", "label.netscaler.vpx": "Εξισορρόπηση φόρτου VPX του NetScaler",
"label.network": "Δίκτυο", "label.network": "Δίκτυο",
"label.network.acl": "ACL δικτύου", "label.network.acl": "ACL δικτύου",
"label.network.acl.lists": "Λίστες Λίστα Πρόσβασης δικτύου", "label.network.acls": "Λίστες Λίστα Πρόσβασης δικτύου",
"label.network.addvm": "Προσθήκη δικτύου για την εικονική μηχανή", "label.network.addvm": "Προσθήκη δικτύου για την εικονική μηχανή",
"label.network.addvm": "Προσθήκη δικτύου σε εικονική μηχανή", "label.network.addvm": "Προσθήκη δικτύου σε εικονική μηχανή",
"label.network.desc": "Δίκτυο Desc", "label.network.desc": "Δίκτυο Desc",
@ -1436,7 +1436,6 @@
"label.remove.vpc.offering": "Κατάργηση προσφοράς υπηρεσίας Εικον. Ιδιωτ. Νέφους", "label.remove.vpc.offering": "Κατάργηση προσφοράς υπηρεσίας Εικον. Ιδιωτ. Νέφους",
"label.removing": "Αφαίρεση", "label.removing": "Αφαίρεση",
"label.replace.acl": "Αντικατάσταση λίστας Πρόσβασης", "label.replace.acl": "Αντικατάσταση λίστας Πρόσβασης",
"label.replace.acl.list": "Αντικατάσταση λίστας Πρόσβασης",
"label.report.bug": "Θέμα αναφοράς", "label.report.bug": "Θέμα αναφοράς",
"label.required": "Απαιτείται", "label.required": "Απαιτείται",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
@ -1455,7 +1454,7 @@
"label.reset.config.value": "Επαναφορά στις τιμές προεπιλογής", "label.reset.config.value": "Επαναφορά στις τιμές προεπιλογής",
"label.reset.ssh.key.pair": "Επαναφορά ζεύγους κλειδιών SSH", "label.reset.ssh.key.pair": "Επαναφορά ζεύγους κλειδιών SSH",
"label.reset.to.default": "Επαναφορά στην τιμή προεπιλογής", "label.reset.to.default": "Επαναφορά στην τιμή προεπιλογής",
"label.reset.userdata.on.vm": "Επαναφορά δεδομένων χρήστη της εικονικής μηχανής", "label.reset.user.data.on.vm": "Επαναφορά δεδομένων χρήστη της εικονικής μηχανής",
"label.reset.vpn.connection": "Επαναφορά σύνδεσης Εικον. Ιδιωτ. Δικτύου", "label.reset.vpn.connection": "Επαναφορά σύνδεσης Εικον. Ιδιωτ. Δικτύου",
"label.resource": "Πόρος", "label.resource": "Πόρος",
"label.resource.limit.exceeded": "Υπέρβαση ορίου πόρων", "label.resource.limit.exceeded": "Υπέρβαση ορίου πόρων",
@ -1811,19 +1810,17 @@
"label.usenewdiskoffering": "Αντικατάσταση προσφοράς υπηρεσίας δίσκου;", "label.usenewdiskoffering": "Αντικατάσταση προσφοράς υπηρεσίας δίσκου;",
"label.user": "Χρήστη", "label.user": "Χρήστη",
"label.user.conflict": "Σύγκρουση", "label.user.conflict": "Σύγκρουση",
"label.user.data": "Δεδομένα χρηστών", "label.user.data": "Δεδομένα χρήστη",
"label.userdata": "Δεδομένα χρήστη", "label.user.data.do.append": "Πρόσθεση δεδομένων χρήστη",
"label.userdata.do.append": "Πρόσθεση δεδομένων χρήστη", "label.user.data.do.override": "Παράκαμψη δεδομένων χρήστη",
"label.userdata.do.override": "Παράκαμψη δεδομένων χρήστη", "label.user.data.registered": "Εγγεγραμένα δεδομένα χρήστη",
"label.userdata.registered": "Εγγεγραμένα δεδομένα χρήστη", "label.user.data.text": "Κείμενο δεδομένων χρήστη",
"label.userdata.text": "Κείμενο δεδομένων χρήστη", "label.user.data.details": "Λεπτομέρειες δεδομένων χρήστη",
"label.userdatadetails": "Λεπτομέρειες δεδομένων χρήστη", "label.user.data.id": "Αναγνωριστικό δεδομένων χρήστη",
"label.userdataid": "Αναγνωριστικό δεδομένων χρήστη", "label.user.data.name": "Όνομα δεδομένων χρήστη",
"label.userdatal2": "Δεδομένα χρήστη", "label.user.data.params": "Παράμετροι δεδομένων χρήστη",
"label.userdataname": "Όνομα δεδομένων χρήστη", "label.user.data.policy": "Συνδεμένες πολιτικές δεδομένων χρήστη",
"label.userdataparams": "Παράμετροι δεδομένων χρήστη", "label.user.data.policy.tooltip": "Τα δεδομένα χρήστη που έχουν συνδεθεί στο πρότυπο μπορούν να παρακαμφθούν απο τα δεδομένα χρηστών που ορίστηκαν κατα την δημιουργία της vm. Διαλέξτε την πολιτική παράκαμψης ανάλογα με τις απαιτήσεις.",
"label.userdatapolicy": "Συνδεμένες πολιτικές δεδομένων χρήστη",
"label.userdatapolicy.tooltip": "Τα δεδομένα χρήστη που έχουν συνδεθεί στο πρότυπο μπορούν να παρακαμφθούν απο τα δεδομένα χρηστών που ορίστηκαν κατα την δημιουργία της vm. Διαλέξτε την πολιτική παράκαμψης ανάλογα με τις απαιτήσεις.",
"label.username": "Όνομα χρήστη", "label.username": "Όνομα χρήστη",
"label.users": "Χρήστες", "label.users": "Χρήστες",
"label.usersource": "Τύπος χρήστη", "label.usersource": "Τύπος χρήστη",
@ -2116,7 +2113,7 @@
"message.confirm.attach.disk": "Είστε βέβαιοι ότι θέλετε να επισυνάψετε το δίσκο;", "message.confirm.attach.disk": "Είστε βέβαιοι ότι θέλετε να επισυνάψετε το δίσκο;",
"message.confirm.change.offering.for.volume": "Παρακαλώ επιβεβαιώστε ότι επιθυμείτε την αλλαγή της προσφοράς δίσκου για αυτόν τον τόμο", "message.confirm.change.offering.for.volume": "Παρακαλώ επιβεβαιώστε ότι επιθυμείτε την αλλαγή της προσφοράς δίσκου για αυτόν τον τόμο",
"message.confirm.configure.ovs": "Είστε βέβαιοι ότι θέλετε να ρυθμίσετε τις παραμέτρους του Ovs;", "message.confirm.configure.ovs": "Είστε βέβαιοι ότι θέλετε να ρυθμίσετε τις παραμέτρους του Ovs;",
"message.confirm.delete.acl.list": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν τη λίστα Λίστα Πρόσβασης;", "message.confirm.delete.acl": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν τη λίστα Λίστα Πρόσβασης;",
"message.confirm.delete.bigswitchbcf": "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτόν τον ελεγκτή BigSwitch BCF", "message.confirm.delete.bigswitchbcf": "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτόν τον ελεγκτή BigSwitch BCF",
"message.confirm.delete.brocadevcs": "Επιβεβαιώστε ότι θέλετε να διαγράψετε το εναλλάκτη Brocade Vcs", "message.confirm.delete.brocadevcs": "Επιβεβαιώστε ότι θέλετε να διαγράψετε το εναλλάκτη Brocade Vcs",
"message.confirm.delete.ciscoasa1000v": "Παρακαλώ επιβεβαιώστε ότι θέλετε να διαγράψετε CiscoASA1000v", "message.confirm.delete.ciscoasa1000v": "Παρακαλώ επιβεβαιώστε ότι θέλετε να διαγράψετε CiscoASA1000v",
@ -2350,7 +2347,7 @@
"message.error.upload.template": "Η αποστολή του προτύπου απέτυχε", "message.error.upload.template": "Η αποστολή του προτύπου απέτυχε",
"message.error.upload.template.description": "Μόνο ένα πρότυπο μπορεί να αποσταλεί κάθε φορά", "message.error.upload.template.description": "Μόνο ένα πρότυπο μπορεί να αποσταλεί κάθε φορά",
"message.error.url": "Πληκτρολογήστε διεύθυνση URL", "message.error.url": "Πληκτρολογήστε διεύθυνση URL",
"message.error.userdata": "Εισάγωγή δεδομένων χρηστών", "message.error.user.data": "Εισάγωγή δεδομένων χρηστών",
"message.error.username": "Εισάγετε το όνομα χρήστη σας", "message.error.username": "Εισάγετε το όνομα χρήστη σας",
"message.error.valid.iops.range": "Εισαγεται ένα σωστό εύρος εργασίων εισαγ./εξαγ ανα δευτ.", "message.error.valid.iops.range": "Εισαγεται ένα σωστό εύρος εργασίων εισαγ./εξαγ ανα δευτ.",
"message.error.vcenter.datacenter": "Πληκτρολογήστε vCenter Datacenter", "message.error.vcenter.datacenter": "Πληκτρολογήστε vCenter Datacenter",

File diff suppressed because it is too large Load Diff

View File

@ -14,12 +14,12 @@
"label.account.specific": "espec\u00edficas de la cuenta", "label.account.specific": "espec\u00edficas de la cuenta",
"label.accounts": "Cuentas", "label.accounts": "Cuentas",
"label.accounttype": "Tipo de Cuenta", "label.accounttype": "Tipo de Cuenta",
"label.acl.export": "Export ACLs", "label.acl.export": "Export ACL rules",
"label.acl.id": "ID de ACL", "label.acl.id": "ID de ACL",
"label.acl.list.rules": "Lista de Reglas ACL", "label.acl.rules": "Lista de Reglas ACL",
"label.acl.reason.description": "Enter the reason behind an ACL rule.", "label.acl.reason.description": "Enter the reason behind an ACL rule.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "Nombre de ACL", "label.acl.rule.name": "Nombre de ACL",
"label.acquire.new.ip": "Adquirir nueva IP", "label.acquire.new.ip": "Adquirir nueva IP",
"label.acquire.new.secondary.ip": "Adquirir nueva IP secundaria", "label.acquire.new.secondary.ip": "Adquirir nueva IP secundaria",
"label.action": "Acci\u00f3n", "label.action": "Acci\u00f3n",
@ -119,8 +119,8 @@
"label.activeviewersessions": "Sesiones activas", "label.activeviewersessions": "Sesiones activas",
"label.add": "Agregar", "label.add": "Agregar",
"label.add.account": "A\u00f1adir Cuenta", "label.add.account": "A\u00f1adir Cuenta",
"label.add.acl": "Agregar ACL", "label.add.acl.rule": "Agregar ACL",
"label.add.acl.list": "Agregar Lista ACL", "label.add.acl": "Agregar Lista ACL",
"label.add.affinity.group": "Agregar un nuevo grupo de afinidad", "label.add.affinity.group": "Agregar un nuevo grupo de afinidad",
"label.add.baremetal.dhcp.device": "Agregar dispositivo DHCP Baremetal", "label.add.baremetal.dhcp.device": "Agregar dispositivo DHCP Baremetal",
"label.add.bigswitchbcf.device": "Agregar Controlador BigSwitch BCF", "label.add.bigswitchbcf.device": "Agregar Controlador BigSwitch BCF",
@ -142,12 +142,12 @@
"label.add.ip.range": "A\u00f1adir Rango IP", "label.add.ip.range": "A\u00f1adir Rango IP",
"label.add.isolated.network": "Agregar Red Aislada", "label.add.isolated.network": "Agregar Red Aislada",
"label.add.ldap.account": "Agregar cuenta LDAP", "label.add.ldap.account": "Agregar cuenta LDAP",
"label.add.list.name": "Nombre de la Lista ACL", "label.add.acl.name": "Nombre de la Lista ACL",
"label.add.more": "A\u00f1adir m\u00e1s", "label.add.more": "A\u00f1adir m\u00e1s",
"label.add.netscaler.device": "Agregar dispositivo Netscaler", "label.add.netscaler.device": "Agregar dispositivo Netscaler",
"label.add.network": "Agregar Red", "label.add.network": "Agregar Red",
"label.add.network.acl": "Agregar ACL de Red", "label.add.network.acl": "Agregar ACL de Red",
"label.add.network.acl.list": "Agregar Lista ACL de Red", "label.add.network.acl": "Agregar Lista ACL de Red",
"label.add.network.offering": "Agregar Oferta de Red", "label.add.network.offering": "Agregar Oferta de Red",
"label.add.new.gateway": "Agregar nuevo gateway", "label.add.new.gateway": "Agregar nuevo gateway",
"label.add.new.tier": "Agregar un nuevo tier", "label.add.new.tier": "Agregar un nuevo tier",
@ -344,7 +344,7 @@
"label.default.use": "Uso por defecto", "label.default.use": "Uso por defecto",
"label.default.view": "Vista Por Defecto", "label.default.view": "Vista Por Defecto",
"label.delete": "Eliminar", "label.delete": "Eliminar",
"label.delete.acl.list": "Borrar Lista ACL", "label.delete.acl": "Borrar Lista ACL",
"label.delete.affinity.group": "Borrar Grupo de Afinidad", "label.delete.affinity.group": "Borrar Grupo de Afinidad",
"label.delete.alerts": "Eliminar alertas", "label.delete.alerts": "Eliminar alertas",
"label.delete.bigswitchbcf": "Remover Controlador BigSwitch BCF", "label.delete.bigswitchbcf": "Remover Controlador BigSwitch BCF",
@ -431,7 +431,7 @@
"label.driver": "Controlador", "label.driver": "Controlador",
"label.dynamicscalingenabled": "Escalado din\u00e1mico habilitado", "label.dynamicscalingenabled": "Escalado din\u00e1mico habilitado",
"label.edit": "Editar", "label.edit": "Editar",
"label.edit.acl.list": "Edit ACL List", "label.edit.acl": "Edit ACL",
"label.edit.acl.rule": "Editar regla ACL", "label.edit.acl.rule": "Editar regla ACL",
"label.edit.project.details": "Editar detalles de proyecto", "label.edit.project.details": "Editar detalles de proyecto",
"label.edit.role": "Editar Rol", "label.edit.role": "Editar Rol",
@ -947,7 +947,6 @@
"label.remove.vpc.offering": "Quitar Oferta VPC", "label.remove.vpc.offering": "Quitar Oferta VPC",
"label.removing": "Quitando..", "label.removing": "Quitando..",
"label.replace.acl": "Reemplazar ACL", "label.replace.acl": "Reemplazar ACL",
"label.replace.acl.list": "Reemplazar Lista ACL",
"label.report.bug": "Reportar un Error", "label.report.bug": "Reportar un Error",
"label.required": "Requerido", "label.required": "Requerido",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
@ -1180,8 +1179,7 @@
"label.usehttps": "Use HTTPS", "label.usehttps": "Use HTTPS",
"label.usenewdiskoffering": "Replace disk offering?", "label.usenewdiskoffering": "Replace disk offering?",
"label.user": "Usuario", "label.user": "Usuario",
"label.userdata": "DatosUsuario", "label.user.data": "DatosUsuario",
"label.userdatal2": "Datos de Usuario",
"label.username": "Nombre de usuario", "label.username": "Nombre de usuario",
"label.users": "Usuarios", "label.users": "Usuarios",
"label.utilization": "Utilisation", "label.utilization": "Utilisation",
@ -1361,7 +1359,7 @@
"message.confirm.archive.selected.alerts": "Por favor confirme que desea archivar las alertas seleccionadas", "message.confirm.archive.selected.alerts": "Por favor confirme que desea archivar las alertas seleccionadas",
"message.confirm.archive.selected.events": "Por favor confirme que desea archivar los eventos seleccionados", "message.confirm.archive.selected.events": "Por favor confirme que desea archivar los eventos seleccionados",
"message.confirm.attach.disk": "\u00bf Est\u00e1 seguro que desea conectar el disco?", "message.confirm.attach.disk": "\u00bf Est\u00e1 seguro que desea conectar el disco?",
"message.confirm.delete.acl.list": "\u00bfEsta seguro que desea borrar esta lista de ACL?", "message.confirm.delete.acl": "\u00bfEsta seguro que desea borrar esta lista de ACL?",
"message.confirm.delete.bigswitchbcf": "Por favor confirme que desa borrar este Controlador BigSwitch BCF", "message.confirm.delete.bigswitchbcf": "Por favor confirme que desa borrar este Controlador BigSwitch BCF",
"message.confirm.delete.brocadevcs": "Por favor confirme que desa borrar este Switch Brocade Vcs", "message.confirm.delete.brocadevcs": "Por favor confirme que desa borrar este Switch Brocade Vcs",
"message.confirm.delete.ciscoasa1000v": "Por favor confirme que desea borrar CiscoASA1000v", "message.confirm.delete.ciscoasa1000v": "Por favor confirme que desea borrar CiscoASA1000v",

View File

@ -14,12 +14,12 @@
"label.account.specific": "Sp\u00e9cifique au compte", "label.account.specific": "Sp\u00e9cifique au compte",
"label.accounts": "Comptes", "label.accounts": "Comptes",
"label.accounttype": "Type Compte", "label.accounttype": "Type Compte",
"label.acl.export": "Export ACLs", "label.acl.export": "Export ACL rules",
"label.acl.id": "ID ACL", "label.acl.id": "ID ACL",
"label.acl.list.rules": "Liste r\u00e8gles ACL", "label.acl.rules": "Liste r\u00e8gles ACL",
"label.acl.reason.description": "Enter the reason behind an ACL rule.", "label.acl.reason.description": "Enter the reason behind an ACL rule.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "Nom ACL", "label.acl.rule.name": "Nom ACL",
"label.acquire.new.ip": "Acqu\u00e9rir nouvelle adr. IP", "label.acquire.new.ip": "Acqu\u00e9rir nouvelle adr. IP",
"label.acquire.new.secondary.ip": "Acqu\u00e9rir nouvelle IP secondaire", "label.acquire.new.secondary.ip": "Acqu\u00e9rir nouvelle IP secondaire",
"label.action": "Action", "label.action": "Action",
@ -119,8 +119,8 @@
"label.activeviewersessions": "Sessions actives", "label.activeviewersessions": "Sessions actives",
"label.add": "Ajouter", "label.add": "Ajouter",
"label.add.account": "Ajouter un compte", "label.add.account": "Ajouter un compte",
"label.add.acl": "Ajouter r\u00e8gle ACL", "label.add.acl.rule": "Ajouter r\u00e8gle ACL",
"label.add.acl.list": "Ajouter Liste ACL", "label.add.acl": "Ajouter Liste ACL",
"label.add.affinity.group": "Ajouter nouveau groupe d'affinit\u00e9", "label.add.affinity.group": "Ajouter nouveau groupe d'affinit\u00e9",
"label.add.baremetal.dhcp.device": "Ajouter un DHCP Baremetal", "label.add.baremetal.dhcp.device": "Ajouter un DHCP Baremetal",
"label.add.bigswitchbcf.device": "Ajouter un contr\u00f4leur BigSwitch BCF", "label.add.bigswitchbcf.device": "Ajouter un contr\u00f4leur BigSwitch BCF",
@ -142,12 +142,12 @@
"label.add.ip.range": "Ajouter une plage IP", "label.add.ip.range": "Ajouter une plage IP",
"label.add.isolated.network": "Ajouter un r\u00e9seau isol\u00e9", "label.add.isolated.network": "Ajouter un r\u00e9seau isol\u00e9",
"label.add.ldap.account": "Ajouter un compte LDAP", "label.add.ldap.account": "Ajouter un compte LDAP",
"label.add.list.name": "Nom Liste ACL", "label.add.acl.name": "Nom Liste ACL",
"label.add.more": "Ajouter plus", "label.add.more": "Ajouter plus",
"label.add.netscaler.device": "Ajouter un Netscaler", "label.add.netscaler.device": "Ajouter un Netscaler",
"label.add.network": "Ajouter un r\u00e9seau", "label.add.network": "Ajouter un r\u00e9seau",
"label.add.network.acl": "Ajouter une r\u00e8gle d'acc\u00e8s r\u00e9seau ACL", "label.add.network.acl": "Ajouter une r\u00e8gle d'acc\u00e8s r\u00e9seau ACL",
"label.add.network.acl.list": "Ajouter Liste ACL r\u00e9seau", "label.add.network.acl": "Ajouter Liste ACL r\u00e9seau",
"label.add.network.offering": "Ajouter Offre R\u00e9seau", "label.add.network.offering": "Ajouter Offre R\u00e9seau",
"label.add.new.gateway": "Ajouter une nouvelle passerelle", "label.add.new.gateway": "Ajouter une nouvelle passerelle",
"label.add.new.tier": "Ajouter un nouveau tiers", "label.add.new.tier": "Ajouter un nouveau tiers",
@ -334,7 +334,7 @@
"label.default.use": "Utilisation par d\u00e9faut", "label.default.use": "Utilisation par d\u00e9faut",
"label.default.view": "Vue par d\u00e9faut", "label.default.view": "Vue par d\u00e9faut",
"label.delete": "Supprimer", "label.delete": "Supprimer",
"label.delete.acl.list": "Supprimer Liste ACL", "label.delete.acl": "Supprimer Liste ACL",
"label.delete.affinity.group": "Supprimer le groupe d'affinit\u00e9", "label.delete.affinity.group": "Supprimer le groupe d'affinit\u00e9",
"label.delete.alerts": "Supprimer alertes", "label.delete.alerts": "Supprimer alertes",
"label.delete.bigswitchbcf": "Supprimer contr\u00f4leur BigSwitch BCF", "label.delete.bigswitchbcf": "Supprimer contr\u00f4leur BigSwitch BCF",
@ -419,7 +419,7 @@
"label.dpd": "D\u00e9tection de pair mort", "label.dpd": "D\u00e9tection de pair mort",
"label.driver": "Pilote", "label.driver": "Pilote",
"label.edit": "Modifier", "label.edit": "Modifier",
"label.edit.acl.list": "Edit ACL List", "label.edit.acl": "Edit ACL",
"label.edit.acl.rule": "Modifier r\u00e8gle ACL", "label.edit.acl.rule": "Modifier r\u00e8gle ACL",
"label.edit.project.details": "Modifier les d\u00e9tails du projet", "label.edit.project.details": "Modifier les d\u00e9tails du projet",
"label.edit.role": "\u00c9diter R\u00f4le", "label.edit.role": "\u00c9diter R\u00f4le",
@ -926,7 +926,6 @@
"label.remove.vpc.offering": "Supprimer offre VPC", "label.remove.vpc.offering": "Supprimer offre VPC",
"label.removing": "Suppression", "label.removing": "Suppression",
"label.replace.acl": "Remplacer ACL", "label.replace.acl": "Remplacer ACL",
"label.replace.acl.list": "Remplacer Liste ACL",
"label.required": "Requis", "label.required": "Requis",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
"label.requiresupgrade": "Mise \u00e0 jour n\u00e9cessaire", "label.requiresupgrade": "Mise \u00e0 jour n\u00e9cessaire",
@ -1152,8 +1151,7 @@
"label.usehttps": "Utiliser HTTPS", "label.usehttps": "Utiliser HTTPS",
"label.usenewdiskoffering": "Replace disk offering?", "label.usenewdiskoffering": "Replace disk offering?",
"label.user": "Utilisateur", "label.user": "Utilisateur",
"label.userdata": "Donn\u00e9es Utilisateur", "label.user.data": "Donn\u00e9es Utilisateur",
"label.userdatal2": "Donn\u00e9es utilisateur",
"label.username": "Identifiant", "label.username": "Identifiant",
"label.users": "Utilisateurs", "label.users": "Utilisateurs",
"label.utilization": "Utilisation", "label.utilization": "Utilisation",
@ -1331,7 +1329,7 @@
"message.confirm.archive.selected.alerts": "Confirmer l'archivage des alertes s\u00e9lectionn\u00e9es", "message.confirm.archive.selected.alerts": "Confirmer l'archivage des alertes s\u00e9lectionn\u00e9es",
"message.confirm.archive.selected.events": "Confirmez l'archivage des \u00e9v\u00e9nements s\u00e9lectionn\u00e9s", "message.confirm.archive.selected.events": "Confirmez l'archivage des \u00e9v\u00e9nements s\u00e9lectionn\u00e9s",
"message.confirm.attach.disk": "Confirmer le rattachement de ce disque ?", "message.confirm.attach.disk": "Confirmer le rattachement de ce disque ?",
"message.confirm.delete.acl.list": "Confirmer la suppression de cette liste ACL ?", "message.confirm.delete.acl": "Confirmer la suppression de cette liste ACL ?",
"message.confirm.delete.bigswitchbcf": "Confirmer que vous voulez supprimer ce contr\u00f4leur BigSwitch BCF", "message.confirm.delete.bigswitchbcf": "Confirmer que vous voulez supprimer ce contr\u00f4leur BigSwitch BCF",
"message.confirm.delete.brocadevcs": "Confirmer la suppression du switch Brocade Vcs", "message.confirm.delete.brocadevcs": "Confirmer la suppression du switch Brocade Vcs",
"message.confirm.delete.ciscoasa1000v": "Confirmez la suppression du CiscoASA1000v", "message.confirm.delete.ciscoasa1000v": "Confirmez la suppression du CiscoASA1000v",

View File

@ -6,7 +6,7 @@
"label.accounts": "लेखा", "label.accounts": "लेखा",
"label.accounttype": "खाता प्रकार", "label.accounttype": "खाता प्रकार",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "ACL नाम", "label.acl.rule.name": "ACL नाम",
"label.actions": "क्रियाएँ", "label.actions": "क्रियाएँ",
"label.add": "जोड़ें", "label.add": "जोड़ें",
"label.adding": "जोड़ना", "label.adding": "जोड़ना",
@ -410,7 +410,7 @@
"label.usageunit": "Unit", "label.usageunit": "Unit",
"label.usehttps": "HTTPS का उपयोग करें", "label.usehttps": "HTTPS का उपयोग करें",
"label.user": "उपयोगकर्ता", "label.user": "उपयोगकर्ता",
"label.userdata": "Userdata", "label.user.data": "User Data",
"label.username": "उपयोगकर्ता नाम", "label.username": "उपयोगकर्ता नाम",
"label.users": "उपयोगकर्ता", "label.users": "उपयोगकर्ता",
"label.uuid": "ID", "label.uuid": "ID",

View File

@ -14,12 +14,12 @@
"label.account.specific": "Sz\u00e1mla-specifikus", "label.account.specific": "Sz\u00e1mla-specifikus",
"label.accounts": "Sz\u00e1ml\u00e1k", "label.accounts": "Sz\u00e1ml\u00e1k",
"label.accounttype": "Sz\u00e1mla t\u00edpus", "label.accounttype": "Sz\u00e1mla t\u00edpus",
"label.acl.export": "Export ACLs", "label.acl.export": "Export ACL rules",
"label.acl.id": "ACL ID", "label.acl.id": "ACL ID",
"label.acl.list.rules": "ACL List Rules", "label.acl.rules": "ACL Rules",
"label.acl.reason.description": "Enter the reason behind an ACL rule.", "label.acl.reason.description": "Enter the reason behind an ACL rule.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "ACL n\u00e9v", "label.acl.rule.name": "ACL n\u00e9v",
"label.acquire.new.ip": "\u00daj IP c\u00edm beszerz\u00e9se", "label.acquire.new.ip": "\u00daj IP c\u00edm beszerz\u00e9se",
"label.acquire.new.secondary.ip": "\u00daj m\u00e1sodlagos IP c\u00edm beszerz\u00e9se", "label.acquire.new.secondary.ip": "\u00daj m\u00e1sodlagos IP c\u00edm beszerz\u00e9se",
"label.action": "M\u0171velet", "label.action": "M\u0171velet",
@ -119,8 +119,8 @@
"label.activeviewersessions": "Akt\u00edv munkamenetek", "label.activeviewersessions": "Akt\u00edv munkamenetek",
"label.add": "Felv\u00e9tel", "label.add": "Felv\u00e9tel",
"label.add.account": "Sz\u00e1mla felv\u00e9tele", "label.add.account": "Sz\u00e1mla felv\u00e9tele",
"label.add.acl": "ACL felv\u00e9tele", "label.add.acl.rule": "ACL felv\u00e9tele",
"label.add.acl.list": "ACL lista felv\u00e9tele", "label.add.acl": "ACL Lista felv\u00e9tele",
"label.add.affinity.group": "\u00daj affin\u00edt\u00e1si csoport felv\u00e9tele", "label.add.affinity.group": "\u00daj affin\u00edt\u00e1si csoport felv\u00e9tele",
"label.add.baremetal.dhcp.device": "Baremetal DHCP eszk\u00f6z felv\u00e9tele", "label.add.baremetal.dhcp.device": "Baremetal DHCP eszk\u00f6z felv\u00e9tele",
"label.add.bigswitchbcf.device": "BigSwitch BCF vez\u00e9rl\u0151 felv\u00e9tele", "label.add.bigswitchbcf.device": "BigSwitch BCF vez\u00e9rl\u0151 felv\u00e9tele",
@ -142,12 +142,12 @@
"label.add.ip.range": "IP c\u00edmtartom\u00e1ny felv\u00e9tele", "label.add.ip.range": "IP c\u00edmtartom\u00e1ny felv\u00e9tele",
"label.add.isolated.network": "Izol\u00e1lt h\u00e1l\u00f3zat felv\u00e9tele", "label.add.isolated.network": "Izol\u00e1lt h\u00e1l\u00f3zat felv\u00e9tele",
"label.add.ldap.account": "LDAP hozz\u00e1f\u00e9r\u00e9s felv\u00e9tele", "label.add.ldap.account": "LDAP hozz\u00e1f\u00e9r\u00e9s felv\u00e9tele",
"label.add.list.name": "ACL lista n\u00e9v", "label.add.acl.name": "ACL Lista n\u00e9v",
"label.add.more": "Tov\u00e1bbi felv\u00e9tele", "label.add.more": "Tov\u00e1bbi felv\u00e9tele",
"label.add.netscaler.device": "Netscaler eszk\u00f6z felv\u00e9tele", "label.add.netscaler.device": "Netscaler eszk\u00f6z felv\u00e9tele",
"label.add.network": "H\u00e1l\u00f3zat felv\u00e9tele", "label.add.network": "H\u00e1l\u00f3zat felv\u00e9tele",
"label.add.network.acl": "H\u00e1l\u00f3zati ACL felv\u00e9tele", "label.add.network.acl": "H\u00e1l\u00f3zati ACL felv\u00e9tele",
"label.add.network.acl.list": "H\u00e1l\u00f3zati ACL lista felv\u00e9tele", "label.add.network.acl": "H\u00e1l\u00f3zati ACL Lista felv\u00e9tele",
"label.add.network.offering": "H\u00e1l\u00f3zati aj\u00e1nlat felv\u00e9tele", "label.add.network.offering": "H\u00e1l\u00f3zati aj\u00e1nlat felv\u00e9tele",
"label.add.new.gateway": "\u00daj \u00e1tj\u00e1r\u00f3 felv\u00e9tele", "label.add.new.gateway": "\u00daj \u00e1tj\u00e1r\u00f3 felv\u00e9tele",
"label.add.new.tier": "\u00daj r\u00e9teg felv\u00e9tele", "label.add.new.tier": "\u00daj r\u00e9teg felv\u00e9tele",
@ -334,7 +334,7 @@
"label.default.use": "Alap\u00e9rtelmezett haszn\u00e1lat", "label.default.use": "Alap\u00e9rtelmezett haszn\u00e1lat",
"label.default.view": "Alap\u00e9rtelmezett n\u00e9zet", "label.default.view": "Alap\u00e9rtelmezett n\u00e9zet",
"label.delete": "T\u00f6rl\u00e9s", "label.delete": "T\u00f6rl\u00e9s",
"label.delete.acl.list": "ACL lista t\u00f6rl\u00e9se", "label.delete.acl": "ACL Lista t\u00f6rl\u00e9se",
"label.delete.affinity.group": "Affin\u00edt\u00e1si csoport t\u00f6rl\u00e9se", "label.delete.affinity.group": "Affin\u00edt\u00e1si csoport t\u00f6rl\u00e9se",
"label.delete.alerts": "T\u00f6rl\u00e9s riaszt\u00e1sok", "label.delete.alerts": "T\u00f6rl\u00e9s riaszt\u00e1sok",
"label.delete.bigswitchbcf": "BigSwitch BCF vez\u00e9rl\u0151 elt\u00e1vol\u00edt\u00e1sa", "label.delete.bigswitchbcf": "BigSwitch BCF vez\u00e9rl\u0151 elt\u00e1vol\u00edt\u00e1sa",
@ -419,7 +419,7 @@
"label.driver": "Driver", "label.driver": "Driver",
"label.dynamicscalingenabled": "dinamikus m\u00e9retez\u00e9s enged\u00e9lyezve", "label.dynamicscalingenabled": "dinamikus m\u00e9retez\u00e9s enged\u00e9lyezve",
"label.edit": "Szerkeszt\u00e9s", "label.edit": "Szerkeszt\u00e9s",
"label.edit.acl.list": "Edit ACL List", "label.edit.acl": "Edit ACL",
"label.edit.acl.rule": "ACL szab\u00e1ly szerkeszt\u00e9se", "label.edit.acl.rule": "ACL szab\u00e1ly szerkeszt\u00e9se",
"label.edit.project.details": "Projekt r\u00e9szletek szerkeszt\u00e9se", "label.edit.project.details": "Projekt r\u00e9szletek szerkeszt\u00e9se",
"label.edit.role": "Edit Role", "label.edit.role": "Edit Role",
@ -924,7 +924,6 @@
"label.remove.vpc.offering": "VPC aj\u00e1nlat t\u00f6rl\u00e9se", "label.remove.vpc.offering": "VPC aj\u00e1nlat t\u00f6rl\u00e9se",
"label.removing": "T\u00f6rl\u00e9s", "label.removing": "T\u00f6rl\u00e9s",
"label.replace.acl": "ACL csere", "label.replace.acl": "ACL csere",
"label.replace.acl.list": "ACL lista cser\u00e9je",
"label.required": "Sz\u00fcks\u00e9ges", "label.required": "Sz\u00fcks\u00e9ges",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
"label.requiresupgrade": "Friss\u00edt\u00e9st ig\u00e9nyel", "label.requiresupgrade": "Friss\u00edt\u00e9st ig\u00e9nyel",
@ -1150,8 +1149,7 @@
"label.usehttps": "HTTPS haszn\u00e1lata", "label.usehttps": "HTTPS haszn\u00e1lata",
"label.usenewdiskoffering": "Replace disk offering?", "label.usenewdiskoffering": "Replace disk offering?",
"label.user": "Felhaszn\u00e1l\u00f3", "label.user": "Felhaszn\u00e1l\u00f3",
"label.userdata": "Felhaszn\u00e1l\u00f3 adat", "label.user.data": "Felhaszn\u00e1l\u00f3 adat",
"label.userdatal2": "Felhaszn\u00e1l\u00f3i adat",
"label.username": "Felhaszn\u00e1l\u00f3n\u00e9v", "label.username": "Felhaszn\u00e1l\u00f3n\u00e9v",
"label.users": "Felhaszn\u00e1l\u00f3k", "label.users": "Felhaszn\u00e1l\u00f3k",
"label.utilization": "Utilisation", "label.utilization": "Utilisation",
@ -1329,7 +1327,7 @@
"message.confirm.archive.selected.alerts": "Er\u0151s\u00edtsd meg, hogy le akarod archiv\u00e1lni a kiv\u00e1lasztott riaszt\u00e1sokat!", "message.confirm.archive.selected.alerts": "Er\u0151s\u00edtsd meg, hogy le akarod archiv\u00e1lni a kiv\u00e1lasztott riaszt\u00e1sokat!",
"message.confirm.archive.selected.events": "Er\u0151s\u00edtsd meg, hogy archiv\u00e1lni szeretn\u00e9d a kiv\u00e1lasztott esem\u00e9nyeket!", "message.confirm.archive.selected.events": "Er\u0151s\u00edtsd meg, hogy archiv\u00e1lni szeretn\u00e9d a kiv\u00e1lasztott esem\u00e9nyeket!",
"message.confirm.attach.disk": "Biztosan csatolni szeretn\u00e9d a merevlemezt?", "message.confirm.attach.disk": "Biztosan csatolni szeretn\u00e9d a merevlemezt?",
"message.confirm.delete.acl.list": "Biztosan t\u00f6r\u00f6lni akarod ezt a ACL list\u00e1t?", "message.confirm.delete.acl": "Biztosan t\u00f6r\u00f6lni akarod ezt a ACL List\u00e1t?",
"message.confirm.delete.bigswitchbcf": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni szeretn\u00e9d ezt a BigSwitch BCF vez\u00e9rl\u0151t!", "message.confirm.delete.bigswitchbcf": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni szeretn\u00e9d ezt a BigSwitch BCF vez\u00e9rl\u0151t!",
"message.confirm.delete.brocadevcs": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni szeretn\u00e9d a Brocade Vcs Switch-et", "message.confirm.delete.brocadevcs": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni szeretn\u00e9d a Brocade Vcs Switch-et",
"message.confirm.delete.ciscoasa1000v": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni akarod a CiscoASA1000v-t", "message.confirm.delete.ciscoasa1000v": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni akarod a CiscoASA1000v-t",
@ -1354,7 +1352,7 @@
"message.confirm.remove.selected.events": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni szeretn\u00e9d a kiv\u00e1lasztott esem\u00e9nyeket", "message.confirm.remove.selected.events": "Er\u0151s\u00edtsd meg, hogy t\u00f6r\u00f6lni szeretn\u00e9d a kiv\u00e1lasztott esem\u00e9nyeket",
"message.confirm.remove.vmware.datacenter": "Er\u0151s\u00edtsd meg, hogy el akarod t\u00e1vol\u00edtani a VMware adatk\u00f6zpontot!", "message.confirm.remove.vmware.datacenter": "Er\u0151s\u00edtsd meg, hogy el akarod t\u00e1vol\u00edtani a VMware adatk\u00f6zpontot!",
"message.confirm.remove.vpc.offering": "Biztos vagy abban, hogy t\u00f6r\u00f6lni akarod ezt a VPC aj\u00e1nlatot?", "message.confirm.remove.vpc.offering": "Biztos vagy abban, hogy t\u00f6r\u00f6lni akarod ezt a VPC aj\u00e1nlatot?",
"message.confirm.replace.acl.new.one": "Le akarod cser\u00e9lni ez ACL list\u00e1t egy \u00fajjal?", "message.confirm.replace.acl.new.one": "Le akarod cser\u00e9lni ez ACL List\u00e1t egy \u00fajjal?",
"message.confirm.scale.up.router.vm": "Biztosan fel akarod m\u00e9retezni a router VM-et?", "message.confirm.scale.up.router.vm": "Biztosan fel akarod m\u00e9retezni a router VM-et?",
"message.confirm.scale.up.system.vm": "Biztosan fel akarod m\u00e9retezni a rendszer VM-et?", "message.confirm.scale.up.system.vm": "Biztosan fel akarod m\u00e9retezni a rendszer VM-et?",
"message.confirm.start.lb.vm": "Er\u0151s\u00edtsd meg, hogy el akarod ind\u00edtani az LB VM-et!", "message.confirm.start.lb.vm": "Er\u0151s\u00edtsd meg, hogy el akarod ind\u00edtani az LB VM-et!",

View File

@ -14,12 +14,12 @@
"label.account.specific": "Specifico dell'Account", "label.account.specific": "Specifico dell'Account",
"label.accounts": "Utenti", "label.accounts": "Utenti",
"label.accounttype": "Account Type", "label.accounttype": "Account Type",
"label.acl.export": "Export ACLs", "label.acl.export": "Export ACL rules",
"label.acl.id": "ACL ID", "label.acl.id": "ACL ID",
"label.acl.list.rules": "ACL List Rules", "label.acl.rules": "ACL Rules",
"label.acl.reason.description": "Enter the reason behind an ACL rule.", "label.acl.reason.description": "Enter the reason behind an ACL rule.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "ACL Name", "label.acl.rule.name": "ACL Name",
"label.acquire.new.ip": "Acquisizione nuovo indirizzo IP", "label.acquire.new.ip": "Acquisizione nuovo indirizzo IP",
"label.acquire.new.secondary.ip": "Acquisizione nuovo IP secondario", "label.acquire.new.secondary.ip": "Acquisizione nuovo IP secondario",
"label.action": "Action", "label.action": "Action",
@ -119,8 +119,8 @@
"label.activeviewersessions": "Sessioni Attive", "label.activeviewersessions": "Sessioni Attive",
"label.add": "Add", "label.add": "Add",
"label.add.account": "Aggiungi un Account", "label.add.account": "Aggiungi un Account",
"label.add.acl": "Aggiungere ACL", "label.add.acl.rule": "Aggiungere ACL",
"label.add.acl.list": "Add ACL List", "label.add.acl": "Add ACL",
"label.add.affinity.group": "Aggiungere un nuovo gruppo di affinit\u00e0", "label.add.affinity.group": "Aggiungere un nuovo gruppo di affinit\u00e0",
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device", "label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
"label.add.bigswitchbcf.device": "Aggiungere Controller BigSwitch BCF", "label.add.bigswitchbcf.device": "Aggiungere Controller BigSwitch BCF",
@ -142,12 +142,12 @@
"label.add.ip.range": "Aggiungere un IP Range", "label.add.ip.range": "Aggiungere un IP Range",
"label.add.isolated.network": "Add Isolated Network", "label.add.isolated.network": "Add Isolated Network",
"label.add.ldap.account": "Aggiungi un account LDAP", "label.add.ldap.account": "Aggiungi un account LDAP",
"label.add.list.name": "ACL List Name", "label.add.acl.name": "ACL Name",
"label.add.more": "Add More", "label.add.more": "Add More",
"label.add.netscaler.device": "Aggiungere device Netscaler", "label.add.netscaler.device": "Aggiungere device Netscaler",
"label.add.network": "Aggiungere una Rete", "label.add.network": "Aggiungere una Rete",
"label.add.network.acl": "Aggiungere le ACL di rete", "label.add.network.acl": "Aggiungere le ACL di rete",
"label.add.network.acl.list": "Add Network ACL List", "label.add.network.acl": "Add Network ACL",
"label.add.network.offering": "Aggiungere offerta di rete", "label.add.network.offering": "Aggiungere offerta di rete",
"label.add.new.gateway": "Aggiungere un nuovo gateway", "label.add.new.gateway": "Aggiungere un nuovo gateway",
"label.add.new.tier": "Aggiungere un nuovo livello", "label.add.new.tier": "Aggiungere un nuovo livello",
@ -334,7 +334,7 @@
"label.default.use": "Default Use", "label.default.use": "Default Use",
"label.default.view": "Vista di default", "label.default.view": "Vista di default",
"label.delete": "Cancellare", "label.delete": "Cancellare",
"label.delete.acl.list": "Delete ACL List", "label.delete.acl": "Delete ACL",
"label.delete.affinity.group": "Cancellare Gruppo di Affinit\u00e0", "label.delete.affinity.group": "Cancellare Gruppo di Affinit\u00e0",
"label.delete.alerts": "Cancella allarmi", "label.delete.alerts": "Cancella allarmi",
"label.delete.bigswitchbcf": "Rimuovere Controller BigSwitch BCF", "label.delete.bigswitchbcf": "Rimuovere Controller BigSwitch BCF",
@ -419,7 +419,7 @@
"label.dpd": "Dead Peer Detection", "label.dpd": "Dead Peer Detection",
"label.driver": "Driver", "label.driver": "Driver",
"label.edit": "Modifica", "label.edit": "Modifica",
"label.edit.acl.list": "Edit ACL List", "label.edit.acl": "Edit ACL",
"label.edit.acl.rule": "Edit ACL rule", "label.edit.acl.rule": "Edit ACL rule",
"label.edit.project.details": "Modificare i dettagli del progetto", "label.edit.project.details": "Modificare i dettagli del progetto",
"label.edit.role": "Edit Role", "label.edit.role": "Edit Role",
@ -924,7 +924,6 @@
"label.remove.vpc.offering": "Remove VPC offering", "label.remove.vpc.offering": "Remove VPC offering",
"label.removing": "Rimozione", "label.removing": "Rimozione",
"label.replace.acl": "Replace ACL", "label.replace.acl": "Replace ACL",
"label.replace.acl.list": "Replace ACL List",
"label.required": "Required", "label.required": "Required",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
"label.requiresupgrade": "Requires Upgrade", "label.requiresupgrade": "Requires Upgrade",
@ -1150,8 +1149,7 @@
"label.usehttps": "Utilizzare HTTPS", "label.usehttps": "Utilizzare HTTPS",
"label.usenewdiskoffering": "Replace disk offering?", "label.usenewdiskoffering": "Replace disk offering?",
"label.user": "User", "label.user": "User",
"label.userdata": "Userdata", "label.user.data": "User Data",
"label.userdatal2": "User Data",
"label.username": "Username", "label.username": "Username",
"label.users": "Users", "label.users": "Users",
"label.utilization": "Utilisation", "label.utilization": "Utilisation",
@ -1329,7 +1327,7 @@
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts", "message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events", "message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
"message.confirm.attach.disk": "Are you sure you want to attach disk?", "message.confirm.attach.disk": "Are you sure you want to attach disk?",
"message.confirm.delete.acl.list": "Are you sure you want to delete this ACL list?", "message.confirm.delete.acl": "Are you sure you want to delete this ACL?",
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller", "message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch", "message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v", "message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",

View File

@ -58,11 +58,11 @@
"label.access.kubernetes.nodes": "Kubernetesードに接続", "label.access.kubernetes.nodes": "Kubernetesードに接続",
"label.acl.export": "エクスポートACLs", "label.acl.export": "エクスポートACLs",
"label.acl.id": "ACL ID", "label.acl.id": "ACL ID",
"label.acl.list.rules": "ACLルールのリスト", "label.acl.rules": "ACLルールのリスト",
"label.acl.reason.description": "ACLルールの理由を入力してください。", "label.acl.reason.description": "ACLルールの理由を入力してください。",
"label.acl.replaced": "ACLが置き換えられました", "label.acl.replaced": "ACLが置き換えられました",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "ACL名", "label.acl.rule.name": "ACL名",
"label.acltotal": "ネットワークACL合計", "label.acltotal": "ネットワークACL合計",
"label.acquire.new.ip": "新しいIPアドレスの取得", "label.acquire.new.ip": "新しいIPアドレスの取得",
"label.acquire.new.secondary.ip": "セカンダリIPアドレスの取得", "label.acquire.new.secondary.ip": "セカンダリIPアドレスの取得",
@ -298,8 +298,8 @@
"label.add.account": "アカウント追加", "label.add.account": "アカウント追加",
"label.add.accounts": "アカウント追加", "label.add.accounts": "アカウント追加",
"label.add.accounts.to": "アカウントの追加先:", "label.add.accounts.to": "アカウントの追加先:",
"label.add.acl": "ACL追加", "label.add.acl.rule": "ACL追加",
"label.add.acl.list": "ACL一覧追加", "label.add.acl": "ACL一覧追加",
"label.add.affinity.group": "新しいアフィニティグループ追加", "label.add.affinity.group": "新しいアフィニティグループ追加",
"label.add.baremetal.dhcp.device": "ベアメタルDHCPデバイス追加", "label.add.baremetal.dhcp.device": "ベアメタルDHCPデバイス追加",
"label.add.baremetal.rack.configuration": "ベアメタルラック設定追加", "label.add.baremetal.rack.configuration": "ベアメタルラック設定追加",
@ -333,14 +333,14 @@
"label.add.l2.guest.network": "L2ゲストネットワーク追加", "label.add.l2.guest.network": "L2ゲストネットワーク追加",
"label.add.ldap.account": "LDAPアカウント追加", "label.add.ldap.account": "LDAPアカウント追加",
"label.add.ldap.list.users": "LDAPユーザー一覧", "label.add.ldap.list.users": "LDAPユーザー一覧",
"label.add.list.name": "ACL一覧名", "label.add.acl.name": "ACL一覧名",
"label.add.load.balancer": "ロードバランサー追加", "label.add.load.balancer": "ロードバランサー追加",
"label.add.management.ip.range": "マネージメントIP範囲追加", "label.add.management.ip.range": "マネージメントIP範囲追加",
"label.add.more": "その他の項目追加", "label.add.more": "その他の項目追加",
"label.add.netscaler.device": "NetScalerデバイス追加", "label.add.netscaler.device": "NetScalerデバイス追加",
"label.add.network": "ネットワーク追加", "label.add.network": "ネットワーク追加",
"label.add.network.acl": "ネットワークACL追加", "label.add.network.acl": "ネットワークACL追加",
"label.add.network.acl.list": "ネットワークACL一覧追加", "label.add.network.acl": "ネットワークACL一覧追加",
"label.add.network.device": "ネットワークデバイス追加", "label.add.network.device": "ネットワークデバイス追加",
"label.add.network.offering": "ネットワークオファリング追加", "label.add.network.offering": "ネットワークオファリング追加",
"label.add.new.f5": "新しいF5追加", "label.add.new.f5": "新しいF5追加",
@ -718,7 +718,7 @@
"label.default.view": "デフォルトビュー", "label.default.view": "デフォルトビュー",
"label.defaultnetwork": "デフォルトネットワーク", "label.defaultnetwork": "デフォルトネットワーク",
"label.delete": "削除", "label.delete": "削除",
"label.delete.acl.list": "ACL一覧削除", "label.delete.acl": "ACL一覧削除",
"label.delete.affinity.group": "アフィニティグループ削除", "label.delete.affinity.group": "アフィニティグループ削除",
"label.delete.alerts": "アラート削除", "label.delete.alerts": "アラート削除",
"label.delete.backup": "バックアップ削除", "label.delete.backup": "バックアップ削除",
@ -872,7 +872,7 @@
"label.dynamicscalingenabled": "ダイナミックスケーリング有効", "label.dynamicscalingenabled": "ダイナミックスケーリング有効",
"label.dynamicscalingenabled.tooltip": "テンプレート、サービスオファリング、およびグローバル設定で動的スケーリングが有効になっている場合にのみ、VMは動的にスケーリングできます。", "label.dynamicscalingenabled.tooltip": "テンプレート、サービスオファリング、およびグローバル設定で動的スケーリングが有効になっている場合にのみ、VMは動的にスケーリングできます。",
"label.edit": "編集", "label.edit": "編集",
"label.edit.acl.list": "ACL一覧編集", "label.edit.acl": "ACL一覧編集",
"label.edit.acl.rule": "ACLルール編集", "label.edit.acl.rule": "ACLルール編集",
"label.edit.affinity.group": "アフィニティグループ編集", "label.edit.affinity.group": "アフィニティグループ編集",
"label.edit.lb.rule": "LBルール編集", "label.edit.lb.rule": "LBルール編集",
@ -1498,7 +1498,7 @@
"label.netscaler.vpx": "NetScaler VPXロードバランサー", "label.netscaler.vpx": "NetScaler VPXロードバランサー",
"label.network": "ネットワーク", "label.network": "ネットワーク",
"label.network.acl": "ネットワークACL", "label.network.acl": "ネットワークACL",
"label.network.acl.lists": "ネットワークACL一覧", "label.network.acls": "ネットワークACL一覧",
"label.network.acls": "ネットワークACL", "label.network.acls": "ネットワークACL",
"label.network.addvm": "VMへのネットワーク追加", "label.network.addvm": "VMへのネットワーク追加",
"label.network.desc": "ネットワークの説明", "label.network.desc": "ネットワークの説明",
@ -1871,7 +1871,6 @@
"label.removing": "削除しています", "label.removing": "削除しています",
"label.removing.user": "ユーザーを削除しています", "label.removing.user": "ユーザーを削除しています",
"label.replace.acl": "ACLの置き換え", "label.replace.acl": "ACLの置き換え",
"label.replace.acl.list": "ACL一覧の置き換え",
"label.report.bug": "問題レポート", "label.report.bug": "問題レポート",
"label.required": "必須です", "label.required": "必須です",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
@ -2321,8 +2320,7 @@
"label.user.details": "ユーザーの詳細", "label.user.details": "ユーザーの詳細",
"label.user.source": "ソース", "label.user.source": "ソース",
"label.user.vm": "ユーザーVM", "label.user.vm": "ユーザーVM",
"label.userdata": "ユーザーデータ", "label.user.data": "ユーザーデータ",
"label.userdatal2": "ユーザーデータ",
"label.username": "ユーザー名", "label.username": "ユーザー名",
"label.users": "ユーザー", "label.users": "ユーザー",
"label.usersource": "ユーザータイプ", "label.usersource": "ユーザータイプ",
@ -2727,7 +2725,7 @@
"message.confirm.dedicate.host.domain.account": "このホストをドメイン/アカウント専用に設定してもよろしいですか?", "message.confirm.dedicate.host.domain.account": "このホストをドメイン/アカウント専用に設定してもよろしいですか?",
"message.confirm.dedicate.pod.domain.account": "このポッドをドメイン/アカウント専用に設定してもよろしいですか?", "message.confirm.dedicate.pod.domain.account": "このポッドをドメイン/アカウント専用に設定してもよろしいですか?",
"message.confirm.dedicate.zone": "このゾーンをドメイン/アカウント専用に設定してもよろしいですか?", "message.confirm.dedicate.zone": "このゾーンをドメイン/アカウント専用に設定してもよろしいですか?",
"message.confirm.delete.acl.list": "このACL一覧を削除してもよろしいですか", "message.confirm.delete.acl": "このACL一覧を削除してもよろしいですか",
"message.confirm.delete.alert": "このアラートを削除してもよろしいですか?", "message.confirm.delete.alert": "このアラートを削除してもよろしいですか?",
"message.confirm.delete.baremetal.rack.configuration": "ベアメタルラック設定を削除してもよろしいですか?", "message.confirm.delete.baremetal.rack.configuration": "ベアメタルラック設定を削除してもよろしいですか?",
"message.confirm.delete.bigswitchbcf": "このBigSwitchBCFコントローラーを削除してもよろしいですか", "message.confirm.delete.bigswitchbcf": "このBigSwitchBCFコントローラーを削除してもよろしいですか",

View File

@ -32,10 +32,10 @@
"label.accounttype": "\uacc4\uc815 \uc720\ud615", "label.accounttype": "\uacc4\uc815 \uc720\ud615",
"label.acl.export": "ACL \ub0b4\ubcf4\ub0b4\uae30", "label.acl.export": "ACL \ub0b4\ubcf4\ub0b4\uae30",
"label.acl.id": "ACL ID", "label.acl.id": "ACL ID",
"label.acl.list.rules": "ACL \ubaa9\ub85d \uaddc\uce59", "label.acl.rules": "ACL \ubaa9\ub85d \uaddc\uce59",
"label.acl.reason.description": "ACL \uaddc\uce59 \ub4a4\uc5d0 \uc124\uba85\uc744 \uc785\ub825\ud558\uc2ed\uc2dc\uc624.", "label.acl.reason.description": "ACL \uaddc\uce59 \ub4a4\uc5d0 \uc124\uba85\uc744 \uc785\ub825\ud558\uc2ed\uc2dc\uc624.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "ACL \uc774\ub984", "label.acl.rule.name": "ACL \uc774\ub984",
"label.acquire.new.ip": "\uc0c8 IP \uc8fc\uc18c \uac00\uc838\uc624\uae30", "label.acquire.new.ip": "\uc0c8 IP \uc8fc\uc18c \uac00\uc838\uc624\uae30",
"label.acquire.new.secondary.ip": "\uc0c8 \ubcf4\uc870 IP \uc8fc\uc18c \uac00\uc838\uc624\uae30", "label.acquire.new.secondary.ip": "\uc0c8 \ubcf4\uc870 IP \uc8fc\uc18c \uac00\uc838\uc624\uae30",
"label.acquiring.ip": "IP \uac00\uc838\uc624\uae30", "label.acquiring.ip": "IP \uac00\uc838\uc624\uae30",
@ -153,8 +153,8 @@
"label.activeviewersessions": "\ud65c\uc131 \uc138\uc158", "label.activeviewersessions": "\ud65c\uc131 \uc138\uc158",
"label.add": "\ucd94\uac00", "label.add": "\ucd94\uac00",
"label.add.account": "\uacc4\uc815 \ucd94\uac00", "label.add.account": "\uacc4\uc815 \ucd94\uac00",
"label.add.acl": "\uad8c\ud55c \uad00\ub9ac(ACL) \ucd94\uac00", "label.add.acl.rule": "\uad8c\ud55c \uad00\ub9ac(ACL) \ucd94\uac00",
"label.add.acl.list": "ACL \ubaa9\ub85d \ucd94\uac00", "label.add.acl": "ACL \ubaa9\ub85d \ucd94\uac00",
"label.add.affinity.group": "\uc0c8 Affinity \uadf8\ub8f9 \ucd94\uac00", "label.add.affinity.group": "\uc0c8 Affinity \uadf8\ub8f9 \ucd94\uac00",
"label.add.baremetal.dhcp.device": "Baremetal DHCP \uc7a5\uce58 \ucd94\uac00", "label.add.baremetal.dhcp.device": "Baremetal DHCP \uc7a5\uce58 \ucd94\uac00",
"label.add.bigswitchbcf.device": "BigSwitch BCF \ucee8\ud2b8\ub864\ub7ec \ucd94\uac00", "label.add.bigswitchbcf.device": "BigSwitch BCF \ucee8\ud2b8\ub864\ub7ec \ucd94\uac00",
@ -178,12 +178,12 @@
"label.add.isolated.network": "isolated \ub124\ud2b8\uc6cc\ud06c \ucd94\uac00", "label.add.isolated.network": "isolated \ub124\ud2b8\uc6cc\ud06c \ucd94\uac00",
"label.add.kubernetes.cluster": "\ucfe0\ubc84\ub124\ud14c\uc2a4 \ud074\ub7ec\uc2a4\ud130 \ucd94\uac00", "label.add.kubernetes.cluster": "\ucfe0\ubc84\ub124\ud14c\uc2a4 \ud074\ub7ec\uc2a4\ud130 \ucd94\uac00",
"label.add.ldap.account": "LDAP \uacc4\uc815 \ucd94\uac00", "label.add.ldap.account": "LDAP \uacc4\uc815 \ucd94\uac00",
"label.add.list.name": "ACL \ubaa9\ub85d \uc774\ub984", "label.add.acl.name": "ACL \ubaa9\ub85d \uc774\ub984",
"label.add.more": "\ub2e4\ub978 \ud56d\ubaa9 \ucd94\uac00", "label.add.more": "\ub2e4\ub978 \ud56d\ubaa9 \ucd94\uac00",
"label.add.netscaler.device": "Netscaler \uc7a5\uce58 \ucd94\uac00", "label.add.netscaler.device": "Netscaler \uc7a5\uce58 \ucd94\uac00",
"label.add.network": "\ub124\ud2b8\uc6cc\ud06c \ucd94\uac00", "label.add.network": "\ub124\ud2b8\uc6cc\ud06c \ucd94\uac00",
"label.add.network.acl": "\ub124\ud2b8\uc6cc\ud06c \uad8c\ud55c \uad00\ub9ac(ACL) \ucd94\uac00", "label.add.network.acl": "\ub124\ud2b8\uc6cc\ud06c \uad8c\ud55c \uad00\ub9ac(ACL) \ucd94\uac00",
"label.add.network.acl.list": "\ub124\ud2b8\uc6cc\ud06c ACL \ubaa9\ub85d \ucd94\uac00", "label.add.network.acl": "\ub124\ud2b8\uc6cc\ud06c ACL \ubaa9\ub85d \ucd94\uac00",
"label.add.network.offering": "\ub124\ud2b8\uc6cc\ud06c \uc624\ud37c\ub9c1 \ucd94\uac00", "label.add.network.offering": "\ub124\ud2b8\uc6cc\ud06c \uc624\ud37c\ub9c1 \ucd94\uac00",
"label.add.new.gateway": "\uc0c8 \uac8c\uc774\ud2b8\uc6e8\uc774 \ucd94\uac00\ud558\uae30", "label.add.new.gateway": "\uc0c8 \uac8c\uc774\ud2b8\uc6e8\uc774 \ucd94\uac00\ud558\uae30",
"label.add.new.tier": "\uc0c8 \uc11c\ube0c\ub137 \ucd94\uac00", "label.add.new.tier": "\uc0c8 \uc11c\ube0c\ub137 \ucd94\uac00",
@ -436,7 +436,7 @@
"label.default.view": "\uae30\ubcf8 \ubcf4\uae30", "label.default.view": "\uae30\ubcf8 \ubcf4\uae30",
"label.defaultnetwork": "\uae30\ubcf8 \ub124\ud2b8\uc6cc\ud06c", "label.defaultnetwork": "\uae30\ubcf8 \ub124\ud2b8\uc6cc\ud06c",
"label.delete": "\uc0ad\uc81c", "label.delete": "\uc0ad\uc81c",
"label.delete.acl.list": "ACL \ubaa9\ub85d \uc0ad\uc81c", "label.delete.acl": "ACL \ubaa9\ub85d \uc0ad\uc81c",
"label.delete.affinity.group": "Affinity \uadf8\ub8f9 \uc0ad\uc81c", "label.delete.affinity.group": "Affinity \uadf8\ub8f9 \uc0ad\uc81c",
"label.delete.alerts": "\uc54c\ub9bc \uc0ad\uc81c", "label.delete.alerts": "\uc54c\ub9bc \uc0ad\uc81c",
"label.delete.backup": "\ubc31\uc5c5 \uc0ad\uc81c", "label.delete.backup": "\ubc31\uc5c5 \uc0ad\uc81c",
@ -549,7 +549,7 @@
"label.dpd": "Dead \ud53c\uc5b4 \uac10\uc9c0", "label.dpd": "Dead \ud53c\uc5b4 \uac10\uc9c0",
"label.driver": "\ub4dc\ub77c\uc774\ubc84", "label.driver": "\ub4dc\ub77c\uc774\ubc84",
"label.edit": "\ud3b8\uc9d1", "label.edit": "\ud3b8\uc9d1",
"label.edit.acl.list": "ACL \ubaa9\ub85d \ud3b8\uc9d1", "label.edit.acl": "ACL \ubaa9\ub85d \ud3b8\uc9d1",
"label.edit.acl.rule": "ACL \uaddc\uce59 \ud3b8\uc9d1", "label.edit.acl.rule": "ACL \uaddc\uce59 \ud3b8\uc9d1",
"label.edit.project.details": "\ud504\ub85c\uc81d\ud2b8 \uc0c1\uc138 \ud3b8\uc9d1", "label.edit.project.details": "\ud504\ub85c\uc81d\ud2b8 \uc0c1\uc138 \ud3b8\uc9d1",
"label.edit.project.role": "\ud504\ub85c\uc81d\ud2b8 \uc5ed\ud560 \ud3b8\uc9d1", "label.edit.project.role": "\ud504\ub85c\uc81d\ud2b8 \uc5ed\ud560 \ud3b8\uc9d1",
@ -985,7 +985,7 @@
"label.netscaler.vpx": "NetScaler VPX \ub85c\ub4dc\ubc38\ub7f0\uc11c", "label.netscaler.vpx": "NetScaler VPX \ub85c\ub4dc\ubc38\ub7f0\uc11c",
"label.network": "\ub124\ud2b8\uc6cc\ud06c", "label.network": "\ub124\ud2b8\uc6cc\ud06c",
"label.network.acl": "\ub124\ud2b8\uc6cc\ud06c \uad8c\ud55c \uad00\ub9ac(ACL)", "label.network.acl": "\ub124\ud2b8\uc6cc\ud06c \uad8c\ud55c \uad00\ub9ac(ACL)",
"label.network.acl.lists": "Network ACL \ubaa9\ub85d", "label.network.acls": "Network ACL \ubaa9\ub85d",
"label.network.addvm": "VM\uc5d0 \ub124\ud2b8\uc6cc\ud06c \ucd94\uac00", "label.network.addvm": "VM\uc5d0 \ub124\ud2b8\uc6cc\ud06c \ucd94\uac00",
"label.network.desc": "\ub124\ud2b8\uc6cc\ud06c \uc124\uba85", "label.network.desc": "\ub124\ud2b8\uc6cc\ud06c \uc124\uba85",
"label.network.domain": "\ub124\ud2b8\uc6cc\ud06c \ub3c4\uba54\uc778", "label.network.domain": "\ub124\ud2b8\uc6cc\ud06c \ub3c4\uba54\uc778",
@ -1251,7 +1251,6 @@
"label.remove.vpc.offering": "VPC \uc624\ud37c\ub9c1 \uc0ad\uc81c", "label.remove.vpc.offering": "VPC \uc624\ud37c\ub9c1 \uc0ad\uc81c",
"label.removing": "\uc0ad\uc81c\ud558\ub294 \uc911...", "label.removing": "\uc0ad\uc81c\ud558\ub294 \uc911...",
"label.replace.acl": "ACL \uad50\uccb4", "label.replace.acl": "ACL \uad50\uccb4",
"label.replace.acl.list": "ACL \ubaa9\ub85d \uad50\uccb4",
"label.report.bug": "\uc774\uc288 \ub9ac\ud3ec\ud2b8", "label.report.bug": "\uc774\uc288 \ub9ac\ud3ec\ud2b8",
"label.required": "\ud544\uc218 \uc0ac\ud56d", "label.required": "\ud544\uc218 \uc0ac\ud56d",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
@ -1560,8 +1559,7 @@
"label.usenewdiskoffering": "\ub514\uc2a4\ud06c \uc624\ud37c\ub9c1\uc744 \ubcc0\uacbd\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?", "label.usenewdiskoffering": "\ub514\uc2a4\ud06c \uc624\ud37c\ub9c1\uc744 \ubcc0\uacbd\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
"label.user": "\uc0ac\uc6a9\uc790", "label.user": "\uc0ac\uc6a9\uc790",
"label.user.conflict": "\ucda9\ub3cc", "label.user.conflict": "\ucda9\ub3cc",
"label.userdata": "\uc0ac\uc6a9\uc790 \ub370\uc774\ud130", "label.user.data": "\uc0ac\uc6a9\uc790 \ub370\uc774\ud130",
"label.userdatal2": "\uc0ac\uc6a9\uc790 \ub370\uc774\ud130",
"label.username": "\uc0ac\uc6a9\uc790 \uc774\ub984", "label.username": "\uc0ac\uc6a9\uc790 \uc774\ub984",
"label.users": "\uc0ac\uc6a9\uc790", "label.users": "\uc0ac\uc6a9\uc790",
"label.usersource": "\uc0ac\uc6a9\uc790 \uc720\ud615", "label.usersource": "\uc0ac\uc6a9\uc790 \uc720\ud615",
@ -1818,7 +1816,7 @@
"message.confirm.archive.selected.events": "\uc120\ud0dd\ud55c \uc774\ubca4\ud2b8\ub97c \ubcf4\uad00\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.", "message.confirm.archive.selected.events": "\uc120\ud0dd\ud55c \uc774\ubca4\ud2b8\ub97c \ubcf4\uad00\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.",
"message.confirm.attach.disk": "\ub514\uc2a4\ud06c\ub97c \uc5f0\uacb0 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?", "message.confirm.attach.disk": "\ub514\uc2a4\ud06c\ub97c \uc5f0\uacb0 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
"message.confirm.configure.ovs": "Ovs\ub97c \uad6c\uc131\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?", "message.confirm.configure.ovs": "Ovs\ub97c \uad6c\uc131\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
"message.confirm.delete.acl.list": "\uc774 ACL \ubaa9\ub85d\uc744 \uc0ad\uc81c \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?", "message.confirm.delete.acl": "\uc774 ACL \ubaa9\ub85d\uc744 \uc0ad\uc81c \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
"message.confirm.delete.bigswitchbcf": "\uc774 BigSwitch BCF \ucee8\ud2b8\ub864\ub7ec\ub97c \uc0ad\uc81c\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.", "message.confirm.delete.bigswitchbcf": "\uc774 BigSwitch BCF \ucee8\ud2b8\ub864\ub7ec\ub97c \uc0ad\uc81c\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.",
"message.confirm.delete.brocadevcs": "Brocade Vcs \uc2a4\uc704\uce58\ub97c \uc0ad\uc81c\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.", "message.confirm.delete.brocadevcs": "Brocade Vcs \uc2a4\uc704\uce58\ub97c \uc0ad\uc81c\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.",
"message.confirm.delete.ciscoasa1000v": "CiscoASA1000\uc744 \uc0ad\uc81c\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.", "message.confirm.delete.ciscoasa1000v": "CiscoASA1000\uc744 \uc0ad\uc81c\ud560 \uac83\uc778\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.",

View File

@ -14,12 +14,12 @@
"label.account.specific": "Kontospesifikk", "label.account.specific": "Kontospesifikk",
"label.accounts": "Kontoer", "label.accounts": "Kontoer",
"label.accounttype": "Kontotype", "label.accounttype": "Kontotype",
"label.acl.export": "Export ACLs", "label.acl.export": "Export ACL rules",
"label.acl.id": "ACL ID", "label.acl.id": "ACL ID",
"label.acl.list.rules": "ACL Liste Regler", "label.acl.rules": "ACL Liste Regler",
"label.acl.reason.description": "Enter the reason behind an ACL rule.", "label.acl.reason.description": "Enter the reason behind an ACL rule.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "ACL Navn", "label.acl.rule.name": "ACL Navn",
"label.acquire.new.ip": "Tilegne ny IP", "label.acquire.new.ip": "Tilegne ny IP",
"label.acquire.new.secondary.ip": "Tilegne ny sekund\u00e6r IP", "label.acquire.new.secondary.ip": "Tilegne ny sekund\u00e6r IP",
"label.action": "Handling", "label.action": "Handling",
@ -119,8 +119,8 @@
"label.activeviewersessions": "Aktive sesjoner", "label.activeviewersessions": "Aktive sesjoner",
"label.add": "Legg til", "label.add": "Legg til",
"label.add.account": "Legg til konto", "label.add.account": "Legg til konto",
"label.add.acl": "Legg til ACL", "label.add.acl.rule": "Legg til ACL",
"label.add.acl.list": "Legg til ACL liste", "label.add.acl": "Legg til ACL liste",
"label.add.affinity.group": "Legg til affinitetsgruppe", "label.add.affinity.group": "Legg til affinitetsgruppe",
"label.add.baremetal.dhcp.device": "Legg Til Barmetall DHCP Enhet", "label.add.baremetal.dhcp.device": "Legg Til Barmetall DHCP Enhet",
"label.add.bigswitchbcf.device": "Legg til BigSwitch BCF kontroller", "label.add.bigswitchbcf.device": "Legg til BigSwitch BCF kontroller",
@ -142,12 +142,12 @@
"label.add.ip.range": "Legg til IP-rekke", "label.add.ip.range": "Legg til IP-rekke",
"label.add.isolated.network": "Legg Til Isolert Nettverk", "label.add.isolated.network": "Legg Til Isolert Nettverk",
"label.add.ldap.account": "Legg til LDAP-konto", "label.add.ldap.account": "Legg til LDAP-konto",
"label.add.list.name": "ACL listenavn", "label.add.acl.name": "ACL listenavn",
"label.add.more": "Legg til mer", "label.add.more": "Legg til mer",
"label.add.netscaler.device": "Legg til Netscaler enhet", "label.add.netscaler.device": "Legg til Netscaler enhet",
"label.add.network": "Legg til nettverk", "label.add.network": "Legg til nettverk",
"label.add.network.acl": "Legg til nettverk ACL", "label.add.network.acl": "Legg til nettverk ACL",
"label.add.network.acl.list": "Legg til nettverk ACL liste", "label.add.network.acl": "Legg til nettverk ACL liste",
"label.add.network.offering": "Legg til nettverkstilbud", "label.add.network.offering": "Legg til nettverkstilbud",
"label.add.new.gateway": "Legg til ny gateway", "label.add.new.gateway": "Legg til ny gateway",
"label.add.new.tier": "Legg til ny gren", "label.add.new.tier": "Legg til ny gren",
@ -334,7 +334,7 @@
"label.default.use": "Standard bruk", "label.default.use": "Standard bruk",
"label.default.view": "Standardvisning", "label.default.view": "Standardvisning",
"label.delete": "Slett", "label.delete": "Slett",
"label.delete.acl.list": "Slett ACL liste", "label.delete.acl": "Slett ACL liste",
"label.delete.affinity.group": "Slett affinitetsgruppe", "label.delete.affinity.group": "Slett affinitetsgruppe",
"label.delete.alerts": "Slette varsler", "label.delete.alerts": "Slette varsler",
"label.delete.bigswitchbcf": "Fjern BigSwitch BCF-kontroller", "label.delete.bigswitchbcf": "Fjern BigSwitch BCF-kontroller",
@ -419,7 +419,7 @@
"label.dpd": "D\u00f8d endepunkt-deteksjon", "label.dpd": "D\u00f8d endepunkt-deteksjon",
"label.driver": "Driver", "label.driver": "Driver",
"label.edit": "Editer", "label.edit": "Editer",
"label.edit.acl.list": "Edit ACL List", "label.edit.acl": "Edit ACL",
"label.edit.acl.rule": "Endre ACL regel", "label.edit.acl.rule": "Endre ACL regel",
"label.edit.project.details": "Editer prosjektdetaljer", "label.edit.project.details": "Editer prosjektdetaljer",
"label.edit.role": "Edit Role", "label.edit.role": "Edit Role",
@ -924,7 +924,6 @@
"label.remove.vpc.offering": "Fjern VPC tilbud", "label.remove.vpc.offering": "Fjern VPC tilbud",
"label.removing": "Fjerner", "label.removing": "Fjerner",
"label.replace.acl": "Erstatt ACL", "label.replace.acl": "Erstatt ACL",
"label.replace.acl.list": "Erstatt ACL Liste",
"label.required": "P\u00e5krevd", "label.required": "P\u00e5krevd",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
"label.requiresupgrade": "Krever oppgradering", "label.requiresupgrade": "Krever oppgradering",
@ -1150,8 +1149,7 @@
"label.usehttps": "Bruk HTTPS", "label.usehttps": "Bruk HTTPS",
"label.usenewdiskoffering": "Replace disk offering?", "label.usenewdiskoffering": "Replace disk offering?",
"label.user": "Bruker", "label.user": "Bruker",
"label.userdata": "Brukerdata", "label.user.data": "Brukerdata",
"label.userdatal2": "Brukerdata",
"label.username": "Brukernavn", "label.username": "Brukernavn",
"label.users": "Brukere", "label.users": "Brukere",
"label.utilization": "Utilisation", "label.utilization": "Utilisation",
@ -1329,7 +1327,7 @@
"message.confirm.archive.selected.alerts": "Vennligst bekreft at du \u00f8nsker \u00e5 arkivere valgte varsler", "message.confirm.archive.selected.alerts": "Vennligst bekreft at du \u00f8nsker \u00e5 arkivere valgte varsler",
"message.confirm.archive.selected.events": "Vennligst bekreft at du vil arkivere valgte hendelser", "message.confirm.archive.selected.events": "Vennligst bekreft at du vil arkivere valgte hendelser",
"message.confirm.attach.disk": "Er du sikker p\u00e5 at du vil tildele disk?", "message.confirm.attach.disk": "Er du sikker p\u00e5 at du vil tildele disk?",
"message.confirm.delete.acl.list": "Er du sikker p\u00e5 at du \u00f8nsker \u00e5 slette denne ACL listen?", "message.confirm.delete.acl": "Er du sikker p\u00e5 at du \u00f8nsker \u00e5 slette denne ACL listen?",
"message.confirm.delete.bigswitchbcf": "Vennligst bekreft at du \u00f8nsker \u00e5 slette denne BigSwitch BCF Controlleren?", "message.confirm.delete.bigswitchbcf": "Vennligst bekreft at du \u00f8nsker \u00e5 slette denne BigSwitch BCF Controlleren?",
"message.confirm.delete.brocadevcs": "Vennligst bekreft at du vil slette denne Brocade Vcs svitsjen", "message.confirm.delete.brocadevcs": "Vennligst bekreft at du vil slette denne Brocade Vcs svitsjen",
"message.confirm.delete.ciscoasa1000v": "Vennligst bekreft at du vil slette CiscoASA1000v", "message.confirm.delete.ciscoasa1000v": "Vennligst bekreft at du vil slette CiscoASA1000v",

View File

@ -14,12 +14,12 @@
"label.account.specific": "Account-specifiek", "label.account.specific": "Account-specifiek",
"label.accounts": "Accounts", "label.accounts": "Accounts",
"label.accounttype": "Account type", "label.accounttype": "Account type",
"label.acl.export": "Export ACLs", "label.acl.export": "Export ACL rules",
"label.acl.id": "ACL ID", "label.acl.id": "ACL ID",
"label.acl.list.rules": "ACL lijst regels", "label.acl.rules": "ACL lijst regels",
"label.acl.reason.description": "Enter the reason behind an ACL rule.", "label.acl.reason.description": "Enter the reason behind an ACL rule.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "ACL naam", "label.acl.rule.name": "ACL naam",
"label.acquire.new.ip": "Bemachtig nieuw IP", "label.acquire.new.ip": "Bemachtig nieuw IP",
"label.acquire.new.secondary.ip": "Verkrijg nieuw secundair IP", "label.acquire.new.secondary.ip": "Verkrijg nieuw secundair IP",
"label.action": "Actie", "label.action": "Actie",
@ -119,8 +119,8 @@
"label.activeviewersessions": "Actieve Sessies", "label.activeviewersessions": "Actieve Sessies",
"label.add": "Voeg toe", "label.add": "Voeg toe",
"label.add.account": "Voeg Account toe", "label.add.account": "Voeg Account toe",
"label.add.acl": "Voeg ACL toe", "label.add.acl.rule": "Voeg ACL toe",
"label.add.acl.list": "voeg een ACL lijst toe", "label.add.acl": "voeg een ACL lijst toe",
"label.add.affinity.group": "Nieuwe affinity groep toevoegen", "label.add.affinity.group": "Nieuwe affinity groep toevoegen",
"label.add.baremetal.dhcp.device": "Voeg Baremetal DHCP Apparaat toe", "label.add.baremetal.dhcp.device": "Voeg Baremetal DHCP Apparaat toe",
"label.add.bigswitchbcf.device": "Voeg eenBigSwitch BCF controller toe", "label.add.bigswitchbcf.device": "Voeg eenBigSwitch BCF controller toe",
@ -142,12 +142,12 @@
"label.add.ip.range": "Voeg IP range toe", "label.add.ip.range": "Voeg IP range toe",
"label.add.isolated.network": "Geisoleerd Netwerk Toevoegen", "label.add.isolated.network": "Geisoleerd Netwerk Toevoegen",
"label.add.ldap.account": "Voeg LDAP account toe", "label.add.ldap.account": "Voeg LDAP account toe",
"label.add.list.name": "ACL lijst naam", "label.add.acl.name": "ACL lijst naam",
"label.add.more": "Voeg meer toe", "label.add.more": "Voeg meer toe",
"label.add.netscaler.device": "Voeg Netscaler apparaat toe", "label.add.netscaler.device": "Voeg Netscaler apparaat toe",
"label.add.network": "Voeg Netwerk toe", "label.add.network": "Voeg Netwerk toe",
"label.add.network.acl": "Voeg netwerk ACL toe", "label.add.network.acl": "Voeg netwerk ACL toe",
"label.add.network.acl.list": "voeg netwerk ACL lijst toe", "label.add.network.acl": "voeg netwerk ACL lijst toe",
"label.add.network.offering": "Voeg netwerk aanbieding toe", "label.add.network.offering": "Voeg netwerk aanbieding toe",
"label.add.new.gateway": "Voeg nieuwe gateway toe", "label.add.new.gateway": "Voeg nieuwe gateway toe",
"label.add.new.tier": "Voeg nieuwe Tier toe", "label.add.new.tier": "Voeg nieuwe Tier toe",
@ -334,7 +334,7 @@
"label.default.use": "Standaard Gebruik", "label.default.use": "Standaard Gebruik",
"label.default.view": "Standaard Weergave", "label.default.view": "Standaard Weergave",
"label.delete": "Verwijder", "label.delete": "Verwijder",
"label.delete.acl.list": "verwijder ACL lijst", "label.delete.acl": "verwijder ACL lijst",
"label.delete.affinity.group": "Verwijder Affinity Groep", "label.delete.affinity.group": "Verwijder Affinity Groep",
"label.delete.alerts": "Verwijder waarschuwingen", "label.delete.alerts": "Verwijder waarschuwingen",
"label.delete.bigswitchbcf": "Verwijder BigSwitch BCF Controller", "label.delete.bigswitchbcf": "Verwijder BigSwitch BCF Controller",
@ -420,7 +420,7 @@
"label.driver": "Driver", "label.driver": "Driver",
"label.dynamicscalingenabled": "Dynamisch schalen ingeschakeld\n", "label.dynamicscalingenabled": "Dynamisch schalen ingeschakeld\n",
"label.edit": "Wijzig", "label.edit": "Wijzig",
"label.edit.acl.list": "Verander een ACL lijst", "label.edit.acl": "Verander een ACL lijst",
"label.edit.acl.rule": "wijzig ACL regel", "label.edit.acl.rule": "wijzig ACL regel",
"label.edit.project.details": "Wijzig project details", "label.edit.project.details": "Wijzig project details",
"label.edit.role": "Edit Role", "label.edit.role": "Edit Role",
@ -925,7 +925,6 @@
"label.remove.vpc.offering": "VPC aanbieding verwijderen", "label.remove.vpc.offering": "VPC aanbieding verwijderen",
"label.removing": "Verwijderen", "label.removing": "Verwijderen",
"label.replace.acl": "vervang ACL", "label.replace.acl": "vervang ACL",
"label.replace.acl.list": "vervang ACL lijst",
"label.required": "Vereist", "label.required": "Vereist",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
"label.requiresupgrade": "Upgrade Benodigd", "label.requiresupgrade": "Upgrade Benodigd",
@ -1151,8 +1150,7 @@
"label.usehttps": "Gebruik HTTPS", "label.usehttps": "Gebruik HTTPS",
"label.usenewdiskoffering": "Replace disk offering?", "label.usenewdiskoffering": "Replace disk offering?",
"label.user": "Gebruiker", "label.user": "Gebruiker",
"label.userdata": "Gebruikers gegevens", "label.user.data": "Gebruiker Data",
"label.userdatal2": "Gebruiker Data",
"label.username": "Gebruikersnaam", "label.username": "Gebruikersnaam",
"label.users": "Gebruikers", "label.users": "Gebruikers",
"label.utilization": "Utilisation", "label.utilization": "Utilisation",
@ -1330,7 +1328,7 @@
"message.confirm.archive.selected.alerts": "bevestig dat u de geselecteerde meldingen wilt archiveren, alstublieft", "message.confirm.archive.selected.alerts": "bevestig dat u de geselecteerde meldingen wilt archiveren, alstublieft",
"message.confirm.archive.selected.events": "bevestig dat u de geselecteerde gebeurtenissen wilt archiveren, alstublieft", "message.confirm.archive.selected.events": "bevestig dat u de geselecteerde gebeurtenissen wilt archiveren, alstublieft",
"message.confirm.attach.disk": "Weet U zeker dat U een disk wilt koppelen?", "message.confirm.attach.disk": "Weet U zeker dat U een disk wilt koppelen?",
"message.confirm.delete.acl.list": "Weet U zeker dat U dit ACL wilt verwijderen?", "message.confirm.delete.acl": "Weet U zeker dat U dit ACL wilt verwijderen?",
"message.confirm.delete.bigswitchbcf": "bevestig dat u deze BigSwitch BCF Controller wilt verwijderen, alstublieft", "message.confirm.delete.bigswitchbcf": "bevestig dat u deze BigSwitch BCF Controller wilt verwijderen, alstublieft",
"message.confirm.delete.brocadevcs": "bevestigd dat Brocade Vcs Switch wilt verwijderen, altublieft", "message.confirm.delete.brocadevcs": "bevestigd dat Brocade Vcs Switch wilt verwijderen, altublieft",
"message.confirm.delete.ciscoasa1000v": "bevestig dat u CiscoASA100v wilt verwijderen, alstublieft", "message.confirm.delete.ciscoasa1000v": "bevestig dat u CiscoASA100v wilt verwijderen, alstublieft",

View File

@ -14,12 +14,12 @@
"label.account.specific": "Account-Specific", "label.account.specific": "Account-Specific",
"label.accounts": "Konta", "label.accounts": "Konta",
"label.accounttype": "Account Type", "label.accounttype": "Account Type",
"label.acl.export": "Export ACLs", "label.acl.export": "Export ACL rules",
"label.acl.id": "ACL ID", "label.acl.id": "ACL ID",
"label.acl.list.rules": "ACL List Rules", "label.acl.rules": "ACL Rules",
"label.acl.reason.description": "Enter the reason behind an ACL rule.", "label.acl.reason.description": "Enter the reason behind an ACL rule.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "ACL Name", "label.acl.rule.name": "ACL Name",
"label.acquire.new.ip": "Acquire New IP", "label.acquire.new.ip": "Acquire New IP",
"label.acquire.new.secondary.ip": "Acquire new secondary IP", "label.acquire.new.secondary.ip": "Acquire new secondary IP",
"label.action": "Action", "label.action": "Action",
@ -119,8 +119,8 @@
"label.activeviewersessions": "Active Sessions", "label.activeviewersessions": "Active Sessions",
"label.add": "Dodaj", "label.add": "Dodaj",
"label.add.account": "Dodaj konto", "label.add.account": "Dodaj konto",
"label.add.acl": "Dodaj ACL", "label.add.acl.rule": "Dodaj ACL",
"label.add.acl.list": "Add ACL List", "label.add.acl": "Add ACL rule List",
"label.add.affinity.group": "Add new affinity group", "label.add.affinity.group": "Add new affinity group",
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device", "label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
"label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller", "label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller",
@ -142,12 +142,12 @@
"label.add.ip.range": "Add IP Range", "label.add.ip.range": "Add IP Range",
"label.add.isolated.network": "Add Isolated Network", "label.add.isolated.network": "Add Isolated Network",
"label.add.ldap.account": "Add LDAP account", "label.add.ldap.account": "Add LDAP account",
"label.add.list.name": "ACL List Name", "label.add.acl.name": "ACL Name",
"label.add.more": "Dodaj wi\u0119cej", "label.add.more": "Dodaj wi\u0119cej",
"label.add.netscaler.device": "Add Netscaler device", "label.add.netscaler.device": "Add Netscaler device",
"label.add.network": "Dodaj sie\u0107", "label.add.network": "Dodaj sie\u0107",
"label.add.network.acl": "Add network ACL", "label.add.network.acl": "Add network ACL",
"label.add.network.acl.list": "Add Network ACL List", "label.add.network.acl": "Add Network ACL",
"label.add.network.offering": "Add network offering", "label.add.network.offering": "Add network offering",
"label.add.new.gateway": "Add new gateway", "label.add.new.gateway": "Add new gateway",
"label.add.new.tier": "Add new tier", "label.add.new.tier": "Add new tier",
@ -334,7 +334,7 @@
"label.default.use": "Default Use", "label.default.use": "Default Use",
"label.default.view": "Widok domy\u015blny", "label.default.view": "Widok domy\u015blny",
"label.delete": "Usu\u0144", "label.delete": "Usu\u0144",
"label.delete.acl.list": "Delete ACL List", "label.delete.acl": "Delete ACL",
"label.delete.affinity.group": "Delete Affinity Group", "label.delete.affinity.group": "Delete Affinity Group",
"label.delete.alerts": "Delete alerts", "label.delete.alerts": "Delete alerts",
"label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller", "label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller",
@ -419,7 +419,7 @@
"label.dpd": "Dead Peer Detection", "label.dpd": "Dead Peer Detection",
"label.driver": "Driver", "label.driver": "Driver",
"label.edit": "Edytuj", "label.edit": "Edytuj",
"label.edit.acl.list": "Edit ACL List", "label.edit.acl": "Edit ACL",
"label.edit.acl.rule": "Edit ACL rule", "label.edit.acl.rule": "Edit ACL rule",
"label.edit.project.details": "Zmie\u0144 szczeg\u00f3\u0142y projektu", "label.edit.project.details": "Zmie\u0144 szczeg\u00f3\u0142y projektu",
"label.edit.role": "Edit Role", "label.edit.role": "Edit Role",
@ -924,7 +924,6 @@
"label.remove.vpc.offering": "Remove VPC offering", "label.remove.vpc.offering": "Remove VPC offering",
"label.removing": "Usuwanie", "label.removing": "Usuwanie",
"label.replace.acl": "Replace ACL", "label.replace.acl": "Replace ACL",
"label.replace.acl.list": "Replace ACL List",
"label.required": "Wymagane", "label.required": "Wymagane",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
"label.requiresupgrade": "Requires Upgrade", "label.requiresupgrade": "Requires Upgrade",
@ -1150,8 +1149,7 @@
"label.usehttps": "Use HTTPS", "label.usehttps": "Use HTTPS",
"label.usenewdiskoffering": "Replace disk offering?", "label.usenewdiskoffering": "Replace disk offering?",
"label.user": "U\u017cytkowni", "label.user": "U\u017cytkowni",
"label.userdata": "Userdata", "label.user.data": "User Data",
"label.userdatal2": "User Data",
"label.username": "Nazwa u\u017cytkownika", "label.username": "Nazwa u\u017cytkownika",
"label.users": "U\u017cytkownicy", "label.users": "U\u017cytkownicy",
"label.utilization": "Utilisation", "label.utilization": "Utilisation",
@ -1329,7 +1327,7 @@
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts", "message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events", "message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
"message.confirm.attach.disk": "Are you sure you want to attach disk?", "message.confirm.attach.disk": "Are you sure you want to attach disk?",
"message.confirm.delete.acl.list": "Are you sure you want to delete this ACL list?", "message.confirm.delete.acl": "Are you sure you want to delete this ACL?",
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller", "message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch", "message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v", "message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",

View File

@ -33,10 +33,10 @@
"label.accounttype": "Tipo de conta", "label.accounttype": "Tipo de conta",
"label.acl.export": "Exportar ACLs", "label.acl.export": "Exportar ACLs",
"label.acl.id": "ACL ID", "label.acl.id": "ACL ID",
"label.acl.list.rules": "Lista de regras de ACL", "label.acl.rules": "Lista de regras de ACL",
"label.acl.reason.description": "Motivo para se utilizar a regra.", "label.acl.reason.description": "Motivo para se utilizar a regra.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "Nome da ACL", "label.acl.rule.name": "Nome da ACL",
"label.acquire.new.ip": "Adquirir novo IP", "label.acquire.new.ip": "Adquirir novo IP",
"label.acquire.new.secondary.ip": "Adquira um novo IP secund\u00e1rio", "label.acquire.new.secondary.ip": "Adquira um novo IP secund\u00e1rio",
"label.acquiring.ip": "Obtendo IP", "label.acquiring.ip": "Obtendo IP",
@ -171,8 +171,8 @@
"label.activeviewersessions": "Sess\u00f5es ativas", "label.activeviewersessions": "Sess\u00f5es ativas",
"label.add": "Adicionar", "label.add": "Adicionar",
"label.add.account": "Adicionar conta", "label.add.account": "Adicionar conta",
"label.add.acl": "Adicionar ACL", "label.add.acl.rule": "Adicionar ACL",
"label.add.acl.list": "Adiciona lista ACL", "label.add.acl": "Adiciona lista ACL",
"label.add.affinity.group": "Adicionar um grupo de afinidade", "label.add.affinity.group": "Adicionar um grupo de afinidade",
"label.add.baremetal.dhcp.device": "Adicionar dispositivo DHCP baremetal", "label.add.baremetal.dhcp.device": "Adicionar dispositivo DHCP baremetal",
"label.add.bigswitchbcf.device": "Adicionar controlador BigSwitch BCF", "label.add.bigswitchbcf.device": "Adicionar controlador BigSwitch BCF",
@ -196,12 +196,12 @@
"label.add.isolated.network": "Adiciona rede isolada", "label.add.isolated.network": "Adiciona rede isolada",
"label.add.kubernetes.cluster": "Adicionar cluster Kubernetes", "label.add.kubernetes.cluster": "Adicionar cluster Kubernetes",
"label.add.ldap.account": "Adicionar conta LDAP", "label.add.ldap.account": "Adicionar conta LDAP",
"label.add.list.name": "Nome da lista ACL", "label.add.acl.name": "Nome da lista ACL",
"label.add.more": "Adicionar mais", "label.add.more": "Adicionar mais",
"label.add.netscaler.device": "Adicionar dispositivo Netscaler", "label.add.netscaler.device": "Adicionar dispositivo Netscaler",
"label.add.network": "Adicionar rede", "label.add.network": "Adicionar rede",
"label.add.network.acl": "Adicione ACL de rede", "label.add.network.acl": "Adicione ACL de rede",
"label.add.network.acl.list": "Adicionar lista de ACL de rede", "label.add.network.acl": "Adicionar lista de ACL de rede",
"label.add.network.offering": "Adicionar oferta de rede", "label.add.network.offering": "Adicionar oferta de rede",
"label.add.new.gateway": "Adicionar novo gateway", "label.add.new.gateway": "Adicionar novo gateway",
"label.add.new.tier": "Adicionar nova camada", "label.add.new.tier": "Adicionar nova camada",
@ -485,7 +485,7 @@
"label.default.view": "Visualiza\u00e7\u00e3o padr\u00e3o", "label.default.view": "Visualiza\u00e7\u00e3o padr\u00e3o",
"label.defaultnetwork": "Rede padr\u00e3o", "label.defaultnetwork": "Rede padr\u00e3o",
"label.delete": "Remover", "label.delete": "Remover",
"label.delete.acl.list": "Apagar lista ACL", "label.delete.acl": "Apagar lista ACL",
"label.delete.affinity.group": "Apagar grupo de afinidade", "label.delete.affinity.group": "Apagar grupo de afinidade",
"label.delete.alerts": "Remover alertas", "label.delete.alerts": "Remover alertas",
"label.delete.backup": "Apagar backup", "label.delete.backup": "Apagar backup",
@ -612,7 +612,7 @@
"label.dynamicscalingenabled": "Escalonamento din\u00e2mico habilitado", "label.dynamicscalingenabled": "Escalonamento din\u00e2mico habilitado",
"label.dynamicscalingenabled.tooltip": "VM s\u00f3 pode ser dinamicamente escalonada quando o escalonamento din\u00e2mico estiver habilitado no template, oferta de computa\u00e7\u00e3o e nas configura\u00e7\u00e3oes globais", "label.dynamicscalingenabled.tooltip": "VM s\u00f3 pode ser dinamicamente escalonada quando o escalonamento din\u00e2mico estiver habilitado no template, oferta de computa\u00e7\u00e3o e nas configura\u00e7\u00e3oes globais",
"label.edit": "Editar", "label.edit": "Editar",
"label.edit.acl.list": "Editar lista ACL", "label.edit.acl": "Editar lista ACL",
"label.edit.acl.rule": "Editar regra ACL", "label.edit.acl.rule": "Editar regra ACL",
"label.edit.project.details": "Editar detalhes do projeto", "label.edit.project.details": "Editar detalhes do projeto",
"label.edit.project.role": "Editar fun\u00e7\u00e3o do projeto", "label.edit.project.role": "Editar fun\u00e7\u00e3o do projeto",
@ -1069,7 +1069,7 @@
"label.netscaler.vpx": "NetScaler VPX LoadBalancer", "label.netscaler.vpx": "NetScaler VPX LoadBalancer",
"label.network": "Rede", "label.network": "Rede",
"label.network.acl": "ACL de rede", "label.network.acl": "ACL de rede",
"label.network.acl.lists": "Lista de redes ACL", "label.network.acls": "Lista de redes ACL",
"label.network.addvm": "Adicionar rede para VM", "label.network.addvm": "Adicionar rede para VM",
"label.network.desc": "Descri\u00e7\u00e3o de rede", "label.network.desc": "Descri\u00e7\u00e3o de rede",
"label.network.domain": "Dom\u00ednio de rede", "label.network.domain": "Dom\u00ednio de rede",
@ -1356,7 +1356,6 @@
"label.removed": "Removido", "label.removed": "Removido",
"label.removing": "Removendo", "label.removing": "Removendo",
"label.replace.acl": "Substituir ACL", "label.replace.acl": "Substituir ACL",
"label.replace.acl.list": "Substituir lista ACL",
"label.report.bug": "Reportar um problema", "label.report.bug": "Reportar um problema",
"label.required": "Obrigat\u00f3rio", "label.required": "Obrigat\u00f3rio",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
@ -1701,8 +1700,7 @@
"label.usenewdiskoffering": "Substituir a oferta de disco?", "label.usenewdiskoffering": "Substituir a oferta de disco?",
"label.user": "Usu\u00e1rio", "label.user": "Usu\u00e1rio",
"label.user.conflict": "Conflito", "label.user.conflict": "Conflito",
"label.userdata": "Dados de usu\u00e1rio", "label.user.data": "Dados de usu\u00e1rio",
"label.userdatal2": "Dados de usu\u00e1rio",
"label.username": "Nome de usu\u00e1rio", "label.username": "Nome de usu\u00e1rio",
"label.users": "Usu\u00e1rios", "label.users": "Usu\u00e1rios",
"label.usersource": "Tipo de usu\u00e1rio", "label.usersource": "Tipo de usu\u00e1rio",
@ -1978,7 +1976,7 @@
"message.confirm.archive.selected.events": "Por favor confirme que voc\u00ea deseja arquivar os eventos selecionados", "message.confirm.archive.selected.events": "Por favor confirme que voc\u00ea deseja arquivar os eventos selecionados",
"message.confirm.attach.disk": "Voc\u00ea tem certeza que deseja conectar este disco?", "message.confirm.attach.disk": "Voc\u00ea tem certeza que deseja conectar este disco?",
"message.confirm.configure.ovs": "Voc\u00ea tem certeza de que quer configurar os Ovs?", "message.confirm.configure.ovs": "Voc\u00ea tem certeza de que quer configurar os Ovs?",
"message.confirm.delete.acl.list": "Voc\u00ea tem certeza que deseja apagar esta lista ACL?", "message.confirm.delete.acl": "Voc\u00ea tem certeza que deseja apagar esta lista ACL?",
"message.confirm.delete.bigswitchbcf": "Por favor, confirme que voc\u00ea deseja deletar este controlador BigSwitch BCF", "message.confirm.delete.bigswitchbcf": "Por favor, confirme que voc\u00ea deseja deletar este controlador BigSwitch BCF",
"message.confirm.delete.brocadevcs": "Por favor confirme que voc\u00ea deseja remover o switch Brocade Vcs", "message.confirm.delete.brocadevcs": "Por favor confirme que voc\u00ea deseja remover o switch Brocade Vcs",
"message.confirm.delete.ciscoasa1000v": "Favor confirmar que voc\u00ea deseja apagar este CiscoASA1000v", "message.confirm.delete.ciscoasa1000v": "Favor confirmar que voc\u00ea deseja apagar este CiscoASA1000v",

View File

@ -14,12 +14,12 @@
"label.account.specific": "\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430 \u0430\u043a\u043a\u0430\u0443\u043d\u043d\u0442\u0430", "label.account.specific": "\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430 \u0430\u043a\u043a\u0430\u0443\u043d\u043d\u0442\u0430",
"label.accounts": "\u0423\u0447\u0451\u0442\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438", "label.accounts": "\u0423\u0447\u0451\u0442\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438",
"label.accounttype": "Account Type", "label.accounttype": "Account Type",
"label.acl.export": "Export ACLs", "label.acl.export": "Export ACL rules",
"label.acl.id": "ACL ID", "label.acl.id": "ACL ID",
"label.acl.list.rules": "ACL List Rules", "label.acl.rules": "ACL Rules",
"label.acl.reason.description": "Enter the reason behind an ACL rule.", "label.acl.reason.description": "Enter the reason behind an ACL rule.",
"label.aclid": "ACL", "label.aclid": "ACL",
"label.aclname": "ACL Name", "label.acl.rule.name": "ACL Name",
"label.acquire.new.ip": "\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 IP", "label.acquire.new.ip": "\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 IP",
"label.acquire.new.secondary.ip": "\u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 IP-\u0430\u0434\u0440\u0435\u0441", "label.acquire.new.secondary.ip": "\u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 IP-\u0430\u0434\u0440\u0435\u0441",
"label.action": "\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f", "label.action": "\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f",
@ -119,8 +119,8 @@
"label.activeviewersessions": "\u0410\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0435\u0441\u0441\u0438\u0438", "label.activeviewersessions": "\u0410\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0435\u0441\u0441\u0438\u0438",
"label.add": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c", "label.add": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c",
"label.add.account": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c", "label.add.account": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c",
"label.add.acl": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c ACL", "label.add.acl.rule": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c ACL",
"label.add.acl.list": "Add ACL List", "label.add.acl": "Add ACL",
"label.add.affinity.group": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e affinity group", "label.add.affinity.group": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e affinity group",
"label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device", "label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
"label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller", "label.add.bigswitchbcf.device": "Add BigSwitch BCF Controller",
@ -142,12 +142,12 @@
"label.add.ip.range": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0430\u0434\u0440\u0435\u0441\u043e\u0432", "label.add.ip.range": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0430\u0434\u0440\u0435\u0441\u043e\u0432",
"label.add.isolated.network": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441\u0435\u0442\u044c", "label.add.isolated.network": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441\u0435\u0442\u044c",
"label.add.ldap.account": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c LDAP \u0430\u043a\u043a\u0430\u0443\u043d\u0442", "label.add.ldap.account": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c LDAP \u0430\u043a\u043a\u0430\u0443\u043d\u0442",
"label.add.list.name": "ACL List Name", "label.add.acl.name": "ACL Name",
"label.add.more": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0435\u0449\u0435", "label.add.more": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0435\u0449\u0435",
"label.add.netscaler.device": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c Netscaler \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e", "label.add.netscaler.device": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c Netscaler \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e",
"label.add.network": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u044c", "label.add.network": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u044c",
"label.add.network.acl": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u0443\u044e ACL", "label.add.network.acl": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u0443\u044e ACL",
"label.add.network.acl.list": "Add Network ACL List", "label.add.network.acl": "Add Network ACL",
"label.add.network.offering": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b", "label.add.network.offering": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b",
"label.add.new.gateway": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0448\u043b\u044e\u0437", "label.add.new.gateway": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0448\u043b\u044e\u0437",
"label.add.new.tier": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 Tier", "label.add.new.tier": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 Tier",
@ -334,7 +334,7 @@
"label.default.use": "\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e", "label.default.use": "\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e",
"label.default.view": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u0438\u0434", "label.default.view": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u0438\u0434",
"label.delete": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c", "label.delete": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c",
"label.delete.acl.list": "Delete ACL List", "label.delete.acl": "Delete ACL",
"label.delete.affinity.group": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c affinity group", "label.delete.affinity.group": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c affinity group",
"label.delete.alerts": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u0440\u0435\u0432\u043e\u0433\u0438", "label.delete.alerts": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u0440\u0435\u0432\u043e\u0433\u0438",
"label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller", "label.delete.bigswitchbcf": "Remove BigSwitch BCF Controller",
@ -418,7 +418,7 @@
"label.dpd": "Dead Peer Detection", "label.dpd": "Dead Peer Detection",
"label.driver": "Driver", "label.driver": "Driver",
"label.edit": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c", "label.edit": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c",
"label.edit.acl.list": "Edit ACL List", "label.edit.acl": "Edit ACL",
"label.edit.acl.rule": "Edit ACL rule", "label.edit.acl.rule": "Edit ACL rule",
"label.edit.project.details": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430", "label.edit.project.details": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430",
"label.edit.role": "Edit Role", "label.edit.role": "Edit Role",
@ -923,7 +923,6 @@
"label.remove.vpc.offering": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0443\u0441\u043b\u0443\u0433\u0443 VPC", "label.remove.vpc.offering": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0443\u0441\u043b\u0443\u0433\u0443 VPC",
"label.removing": "\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435", "label.removing": "\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435",
"label.replace.acl": "Replace ACL", "label.replace.acl": "Replace ACL",
"label.replace.acl.list": "Replace ACL List",
"label.required": "\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f", "label.required": "\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f",
"label.requireshvm": "HVM", "label.requireshvm": "HVM",
"label.requiresupgrade": "Requires Upgrade", "label.requiresupgrade": "Requires Upgrade",
@ -1149,8 +1148,7 @@
"label.usehttps": "\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 HTTPS", "label.usehttps": "\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 HTTPS",
"label.usenewdiskoffering": "Replace disk offering?", "label.usenewdiskoffering": "Replace disk offering?",
"label.user": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c", "label.user": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c",
"label.userdata": "Userdata", "label.user.data": "User Data",
"label.userdatal2": "User Data",
"label.username": "\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f", "label.username": "\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f",
"label.users": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438", "label.users": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438",
"label.utilization": "Utilisation", "label.utilization": "Utilisation",
@ -1328,7 +1326,7 @@
"message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts", "message.confirm.archive.selected.alerts": "Please confirm you would like to archive the selected alerts",
"message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events", "message.confirm.archive.selected.events": "Please confirm you would like to archive the selected events",
"message.confirm.attach.disk": "Are you sure you want to attach disk?", "message.confirm.attach.disk": "Are you sure you want to attach disk?",
"message.confirm.delete.acl.list": "Are you sure you want to delete this ACL list?", "message.confirm.delete.acl": "Are you sure you want to delete this ACL?",
"message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller", "message.confirm.delete.bigswitchbcf": "Please confirm that you would like to delete this BigSwitch BCF Controller",
"message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch", "message.confirm.delete.brocadevcs": "Please confirm that you would like to delete Brocade Vcs Switch",
"message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v", "message.confirm.delete.ciscoasa1000v": "Please confirm you want to delete CiscoASA1000v",

View File

@ -66,12 +66,12 @@
"label.acl.export": "\u5BFC\u51FA ACL \u89C4\u5219", "label.acl.export": "\u5BFC\u51FA ACL \u89C4\u5219",
"label.acl.id": "ACL \u6807\u8BC6\u7801", "label.acl.id": "ACL \u6807\u8BC6\u7801",
"label.acl.list.rules": "ACL\u5217\u8868\u7B56\u7565", "label.acl.rules": "ACL\u5217\u8868\u7B56\u7565",
"label.acl.reason.description": "\u8F93\u5165\u5B9A\u4E49 ACL \u7B56\u7565\u7684\u539F\u56E0\u3002", "label.acl.reason.description": "\u8F93\u5165\u5B9A\u4E49 ACL \u7B56\u7565\u7684\u539F\u56E0\u3002",
"label.acl.replaced": "ACL \u5DF2\u66FF\u6362", "label.acl.replaced": "ACL \u5DF2\u66FF\u6362",
"label.aclid": "\u8BBF\u95EE\u63A7\u5236\uFF08ACL\uFF09", "label.aclid": "\u8BBF\u95EE\u63A7\u5236\uFF08ACL\uFF09",
"label.aclname": "ACL \u540D\u79F0", "label.acl.rule.name": "ACL \u540D\u79F0",
"label.acltotal": "\u7F51\u7EDC ACL \u603B\u6570", "label.acltotal": "\u7F51\u7EDC ACL \u603B\u6570",
"label.acquire.new.ip": "\u83B7\u53D6\u65B0 IP \u5730\u5740", "label.acquire.new.ip": "\u83B7\u53D6\u65B0 IP \u5730\u5740",
"label.acquire.new.secondary.ip": "\u83B7\u53D6\u65B0\u4E8C\u7EA7 IP \u5730\u5740", "label.acquire.new.secondary.ip": "\u83B7\u53D6\u65B0\u4E8C\u7EA7 IP \u5730\u5740",
@ -336,8 +336,8 @@
"label.add.account": "\u6DFB\u52A0\u5E10\u6237", "label.add.account": "\u6DFB\u52A0\u5E10\u6237",
"label.add.accounts": "\u6DFB\u52A0\u5E10\u6237", "label.add.accounts": "\u6DFB\u52A0\u5E10\u6237",
"label.add.accounts.to": "\u6DFB\u52A0\u5E10\u6237\u81F3", "label.add.accounts.to": "\u6DFB\u52A0\u5E10\u6237\u81F3",
"label.add.acl": "\u6DFB\u52A0 ACL", "label.add.acl.rule": "\u6DFB\u52A0 ACL",
"label.add.acl.list": "\u6DFB\u52A0 ACL \u5217\u8868", "label.add.acl": "\u6DFB\u52A0 ACL \u5217\u8868",
"label.add.affinity.group": "\u6DFB\u52A0\u65B0\u5173\u8054\u6027\u7EC4", "label.add.affinity.group": "\u6DFB\u52A0\u65B0\u5173\u8054\u6027\u7EC4",
"label.add.baremetal.dhcp.device": "\u6DFB\u52A0\u88F8\u673A DHCP \u8BBE\u5907", "label.add.baremetal.dhcp.device": "\u6DFB\u52A0\u88F8\u673A DHCP \u8BBE\u5907",
@ -381,7 +381,7 @@
"label.add.l2.guest.network": "\u6DFB\u52A0 L2 \u6765\u5BBE\u7F51\u7EDC", "label.add.l2.guest.network": "\u6DFB\u52A0 L2 \u6765\u5BBE\u7F51\u7EDC",
"label.add.ldap.account": "\u6DFB\u52A0 LDAP \u8D26\u6237", "label.add.ldap.account": "\u6DFB\u52A0 LDAP \u8D26\u6237",
"label.add.ldap.list.users": "\u5217\u51FA LDAP \u7528\u6237", "label.add.ldap.list.users": "\u5217\u51FA LDAP \u7528\u6237",
"label.add.list.name": "ACL \u5217\u8868\u540D\u79F0", "label.add.acl.name": "ACL \u5217\u8868\u540D\u79F0",
"label.add.load.balancer": "\u6DFB\u52A0\u8D1F\u8F7D\u5747\u8861\u5668", "label.add.load.balancer": "\u6DFB\u52A0\u8D1F\u8F7D\u5747\u8861\u5668",
"label.add.management.ip.range": "\u6DFB\u52A0\u7BA1\u7406 IP \u5730\u5740\u8303\u56F4", "label.add.management.ip.range": "\u6DFB\u52A0\u7BA1\u7406 IP \u5730\u5740\u8303\u56F4",
@ -389,7 +389,7 @@
"label.add.netscaler.device": "\u6DFB\u52A0 Netscaler \u8BBE\u5907", "label.add.netscaler.device": "\u6DFB\u52A0 Netscaler \u8BBE\u5907",
"label.add.network": "\u6DFB\u52A0\u7F51\u7EDC", "label.add.network": "\u6DFB\u52A0\u7F51\u7EDC",
"label.add.network.acl": "\u6DFB\u52A0\u7F51\u7EDC ACL", "label.add.network.acl": "\u6DFB\u52A0\u7F51\u7EDC ACL",
"label.add.network.acl.list": "\u6DFB\u52A0\u7F51\u7EDC ACL \u5217\u8868", "label.add.network.acl": "\u6DFB\u52A0\u7F51\u7EDC ACL \u5217\u8868",
"label.add.network.device": "\u6DFB\u52A0\u7F51\u7EDC\u8BBE\u5907", "label.add.network.device": "\u6DFB\u52A0\u7F51\u7EDC\u8BBE\u5907",
"label.add.network.offering": "\u6DFB\u52A0\u7F51\u7EDC\u65B9\u6848", "label.add.network.offering": "\u6DFB\u52A0\u7F51\u7EDC\u65B9\u6848",
@ -829,7 +829,7 @@
"label.defaultnetwork": "\u9ED8\u8BA4\u7F51\u7EDC", "label.defaultnetwork": "\u9ED8\u8BA4\u7F51\u7EDC",
"label.delete": "\u5220\u9664", "label.delete": "\u5220\u9664",
"label.delete.acl.list": "\u5220\u9664 ACL \u5217\u8868", "label.delete.acl": "\u5220\u9664 ACL \u5217\u8868",
"label.delete.affinity.group": "\u5220\u9664\u5173\u8054\u6027\u7EC4", "label.delete.affinity.group": "\u5220\u9664\u5173\u8054\u6027\u7EC4",
"label.delete.alerts": "\u5220\u9664\u8B66\u62A5", "label.delete.alerts": "\u5220\u9664\u8B66\u62A5",
"label.delete.backup": "\u5220\u9664\u5907\u4EFD", "label.delete.backup": "\u5220\u9664\u5907\u4EFD",
@ -1007,7 +1007,7 @@
"label.computeonly.offering.tooltip": "\u5728\u8BA1\u7B97\u65B9\u6848\u4E2D\u6307\u5B9A\u4E0E\u6839\u78C1\u76D8\u76F8\u5173\u7684\u4FE1\u606F\u6216\u5C06\u78C1\u76D8\u65B9\u6848\u76F4\u63A5\u94FE\u63A5\u5230\u8BA1\u7B97\u65B9\u6848\u7684\u9009\u9879", "label.computeonly.offering.tooltip": "\u5728\u8BA1\u7B97\u65B9\u6848\u4E2D\u6307\u5B9A\u4E0E\u6839\u78C1\u76D8\u76F8\u5173\u7684\u4FE1\u606F\u6216\u5C06\u78C1\u76D8\u65B9\u6848\u76F4\u63A5\u94FE\u63A5\u5230\u8BA1\u7B97\u65B9\u6848\u7684\u9009\u9879",
"label.edit": "\u7F16\u8F91", "label.edit": "\u7F16\u8F91",
"label.edit.acl.list": "\u7F16\u8F91 ACL \u5217\u8868", "label.edit.acl": "\u7F16\u8F91 ACL \u5217\u8868",
"label.edit.acl.rule": "\u7F16\u8F91 ACL \u89C4\u5219", "label.edit.acl.rule": "\u7F16\u8F91 ACL \u89C4\u5219",
"label.edit.affinity.group": "\u7F16\u8F91\u5173\u8054\u6027\u7EC4", "label.edit.affinity.group": "\u7F16\u8F91\u5173\u8054\u6027\u7EC4",
"label.edit.lb.rule": "\u7F16\u8F91\u8D1F\u8F7D\u5747\u8861\u5668\u89C4\u5219", "label.edit.lb.rule": "\u7F16\u8F91\u8D1F\u8F7D\u5747\u8861\u5668\u89C4\u5219",
@ -1717,7 +1717,7 @@
"label.netscaler.vpx": "NetScaler VPX \u8D1F\u8F7D\u5747\u8861\u5668", "label.netscaler.vpx": "NetScaler VPX \u8D1F\u8F7D\u5747\u8861\u5668",
"label.network": "\u7F51\u7EDC", "label.network": "\u7F51\u7EDC",
"label.network.acl": "\u7F51\u7EDC ACL", "label.network.acl": "\u7F51\u7EDC ACL",
"label.network.acl.lists": "\u7F51\u7EDC ACL \u5217\u8868", "label.network.acls": "\u7F51\u7EDC ACL \u5217\u8868",
"label.network.acls": "\u7F51\u7EDC ACL", "label.network.acls": "\u7F51\u7EDC ACL",
"label.network.addvm": "\u5C06\u7F51\u7EDC\u6DFB\u52A0\u5230\u865A\u62DF\u673A", "label.network.addvm": "\u5C06\u7F51\u7EDC\u6DFB\u52A0\u5230\u865A\u62DF\u673A",
"label.network.desc": "\u7F51\u7EDC\u63CF\u8FF0", "label.network.desc": "\u7F51\u7EDC\u63CF\u8FF0",
@ -2136,7 +2136,6 @@
"label.removing.user": "\u6B63\u5728\u5220\u9664\u7528\u6237", "label.removing.user": "\u6B63\u5728\u5220\u9664\u7528\u6237",
"label.replace.acl": "\u66FF\u6362 ACL", "label.replace.acl": "\u66FF\u6362 ACL",
"label.replace.acl.list": "\u66FF\u6362 ACL \u5217\u8868",
"label.report.bug": "\u62A5\u544A\u95EE\u9898", "label.report.bug": "\u62A5\u544A\u95EE\u9898",
"label.required": "\u5FC5\u586B\u9879", "label.required": "\u5FC5\u586B\u9879",
@ -2666,8 +2665,7 @@
"label.user.details": "\u7528\u6237\u8BE6\u60C5", "label.user.details": "\u7528\u6237\u8BE6\u60C5",
"label.user.source": "\u6765\u6E90", "label.user.source": "\u6765\u6E90",
"label.user.vm": "\u7528\u6237\u865A\u62DF\u673A", "label.user.vm": "\u7528\u6237\u865A\u62DF\u673A",
"label.userdata": "\u7528\u6237\u6570\u636E", "label.user.data": "\u7528\u6237\u6570\u636E",
"label.userdatal2": "\u7528\u6237\u6570\u636E",
"label.username": "\u7528\u6237\u540D", "label.username": "\u7528\u6237\u540D",
"label.users": "\u7528\u6237", "label.users": "\u7528\u6237",
"label.usersource": "\u7528\u6237\u7C7B\u578B", "label.usersource": "\u7528\u6237\u7C7B\u578B",
@ -3129,7 +3127,7 @@
"message.confirm.dedicate.pod.domain.account": "\u662F\u5426\u786E\u5B9E\u8981\u5C06\u6B64\u63D0\u4F9B\u70B9\u4E13\u7528\u4E8E\u57DF/\u5E10\u6237\uFF1F", "message.confirm.dedicate.pod.domain.account": "\u662F\u5426\u786E\u5B9E\u8981\u5C06\u6B64\u63D0\u4F9B\u70B9\u4E13\u7528\u4E8E\u57DF/\u5E10\u6237\uFF1F",
"message.confirm.dedicate.zone": "\u662F\u5426\u8981\u5C06\u6B64\u8D44\u6E90\u57DF\u4E13\u7528\u4E8E\u57DF/\u5E10\u6237\uFF1F", "message.confirm.dedicate.zone": "\u662F\u5426\u8981\u5C06\u6B64\u8D44\u6E90\u57DF\u4E13\u7528\u4E8E\u57DF/\u5E10\u6237\uFF1F",
"message.confirm.delete.acl.list": "\u662F\u5426\u786E\u5B9E\u8981\u5220\u9664\u6B64 ACL \u5217\u8868\uFF1F", "message.confirm.delete.acl": "\u662F\u5426\u786E\u5B9E\u8981\u5220\u9664\u6B64 ACL \u5217\u8868\uFF1F",
"message.confirm.delete.alert": "\u662F\u5426\u786E\u5B9E\u8981\u5220\u9664\u6B64\u8B66\u62A5\uFF1F", "message.confirm.delete.alert": "\u662F\u5426\u786E\u5B9E\u8981\u5220\u9664\u6B64\u8B66\u62A5\uFF1F",
"message.confirm.delete.baremetal.rack.configuration": "\u8BF7\u786E\u8BA4\u60A8\u786E\u5B9E\u8981\u5220\u9664 Baremetal Rack \u914D\u7F6E", "message.confirm.delete.baremetal.rack.configuration": "\u8BF7\u786E\u8BA4\u60A8\u786E\u5B9E\u8981\u5220\u9664 Baremetal Rack \u914D\u7F6E",
"message.confirm.delete.bigswitchbcf": "\u8BF7\u786E\u8BA4\u60A8\u786E\u5B9E\u8981\u5220\u9664\u6B64 BigSwitch BCF \u63A7\u5236\u5668", "message.confirm.delete.bigswitchbcf": "\u8BF7\u786E\u8BA4\u60A8\u786E\u5B9E\u8981\u5220\u9664\u6B64 BigSwitch BCF \u63A7\u5236\u5668",

View File

@ -34,6 +34,9 @@
<span v-if="resourceIcon && !['router', 'systemvm', 'volume'].includes($route.path.split('/')[1])"> <span v-if="resourceIcon && !['router', 'systemvm', 'volume'].includes($route.path.split('/')[1])">
<resource-icon :image="resourceIcon" size="4x" style="margin-right: 5px"/> <resource-icon :image="resourceIcon" size="4x" style="margin-right: 5px"/>
</span> </span>
<span v-else-if="resource.vmtype === 'sharedfsvm'">
<file-text-outlined style="font-size: 36px;" />
</span>
<span v-else> <span v-else>
<os-logo v-if="resource.ostypeid || resource.ostypename || ['guestoscategory'].includes($route.path.split('/')[1])" :osId="resource.ostypeid" :osName="resource.ostypename || resource.osdisplayname || resource.name" size="3x" /> <os-logo v-if="resource.ostypeid || resource.ostypename || ['guestoscategory'].includes($route.path.split('/')[1])" :osId="resource.ostypeid" :osName="resource.ostypename || resource.osdisplayname || resource.name" size="3x" />
<render-icon v-else-if="typeof $route.meta.icon ==='string'" style="font-size: 36px" :icon="$route.meta.icon" /> <render-icon v-else-if="typeof $route.meta.icon ==='string'" style="font-size: 36px" :icon="$route.meta.icon" />
@ -750,7 +753,7 @@
</div> </div>
</div> </div>
<div class="resource-detail-item" v-if="resource.userdataname"> <div class="resource-detail-item" v-if="resource.userdataname">
<div class="resource-detail-item__label">{{ $t('label.userdata') }}</div> <div class="resource-detail-item__label">{{ $t('label.user.data') }}</div>
<div class="resource-detail-item__details"> <div class="resource-detail-item__details">
<solution-outlined /> <solution-outlined />
<router-link v-if="!isStatic && $router.resolve('/userdata/' + resource.userdataid).matched[0].redirect !== '/exception/404'" :to="{ path: '/userdata/' + resource.userdataid }">{{ resource.userdataname || resource.userdataid }}</router-link> <router-link v-if="!isStatic && $router.resolve('/userdata/' + resource.userdataid).matched[0].redirect !== '/exception/404'" :to="{ path: '/userdata/' + resource.userdataid }">{{ resource.userdataname || resource.userdataid }}</router-link>
@ -824,6 +827,18 @@
<span v-else>{{ resource.webhookname || resource.webhookid }}</span> <span v-else>{{ resource.webhookname || resource.webhookid }}</span>
</div> </div>
</div> </div>
<div class="resource-detail-item" v-if="resource.boottype">
<div class="resource-detail-item__label">{{ $t('label.boottype') }}</div>
<div class="resource-detail-item__details">
<span>{{ resource.boottype }}</span>
</div>
</div>
<div class="resource-detail-item" v-if="resource.bootmode">
<div class="resource-detail-item__label">{{ $t('label.bootmode') }}</div>
<div class="resource-detail-item__details">
<span>{{ resource.bootmode }}</span>
</div>
</div>
<div class="resource-detail-item" v-if="resource.managementserverid"> <div class="resource-detail-item" v-if="resource.managementserverid">
<div class="resource-detail-item__label">{{ $t('label.management.servers') }}</div> <div class="resource-detail-item__label">{{ $t('label.management.servers') }}</div>
<div class="resource-detail-item__details"> <div class="resource-detail-item__details">
@ -976,6 +991,7 @@ import eventBus from '@/config/eventBus'
import ResourceIcon from '@/components/view/ResourceIcon' import ResourceIcon from '@/components/view/ResourceIcon'
import ResourceLabel from '@/components/widgets/ResourceLabel' import ResourceLabel from '@/components/widgets/ResourceLabel'
import ImageDeployInstanceButton from '@/components/view/ImageDeployInstanceButton' import ImageDeployInstanceButton from '@/components/view/ImageDeployInstanceButton'
import { FileTextOutlined } from '@ant-design/icons-vue'
export default { export default {
name: 'InfoCard', name: 'InfoCard',
@ -988,7 +1004,8 @@ export default {
UploadResourceIcon, UploadResourceIcon,
ResourceIcon, ResourceIcon,
ResourceLabel, ResourceLabel,
ImageDeployInstanceButton ImageDeployInstanceButton,
FileTextOutlined
}, },
props: { props: {
resource: { resource: {
@ -1323,6 +1340,9 @@ export default {
if (item.name === 'template') { if (item.name === 'template') {
query.templatefilter = 'self' query.templatefilter = 'self'
query.filter = 'self' query.filter = 'self'
} else if (item.name === 'iso') {
query.isofilter = 'self'
query.filter = 'self'
} }
if (item.param === 'account') { if (item.param === 'account') {

View File

@ -60,12 +60,10 @@
size="2x" size="2x"
/> />
</span> </span>
<os-logo <span v-else-if="record.vmtype === 'sharedfsvm'">
v-else <file-text-outlined style="font-size: 18px;" />
:osId="record.ostypeid" </span>
:osName="record.osdisplayname" <os-logo v-else :osId="record.ostypeid" :osName="record.osdisplayname" size="xl" />
size="xl"
/>
</span> </span>
<span style="min-width: 120px"> <span style="min-width: 120px">
<QuickView <QuickView
@ -1008,6 +1006,7 @@ import { createPathBasedOnVmType } from '@/utils/plugins'
import { validateLinks } from '@/utils/links' import { validateLinks } from '@/utils/links'
import cronstrue from 'cronstrue/i18n' import cronstrue from 'cronstrue/i18n'
import moment from 'moment-timezone' import moment from 'moment-timezone'
import { FileTextOutlined } from '@ant-design/icons-vue'
export default { export default {
name: 'ListView', name: 'ListView',
@ -1018,7 +1017,8 @@ export default {
CopyLabel, CopyLabel,
TooltipButton, TooltipButton,
ResourceIcon, ResourceIcon,
ResourceLabel ResourceLabel,
FileTextOutlined
}, },
props: { props: {
columns: { columns: {

View File

@ -55,7 +55,7 @@ export default {
param: 'account' param: 'account'
}, { }, {
name: 'userdata', name: 'userdata',
title: 'label.userdata', title: 'label.user.data',
param: 'account' param: 'account'
}, { }, {
name: 'template', name: 'template',

View File

@ -400,7 +400,7 @@ export default {
{ {
api: 'resetUserDataForVirtualMachine', api: 'resetUserDataForVirtualMachine',
icon: 'solution-outlined', icon: 'solution-outlined',
label: 'label.reset.userdata.on.vm', label: 'label.reset.user.data.on.vm',
message: 'message.desc.reset.userdata', message: 'message.desc.reset.userdata',
docHelp: 'adminguide/virtual_machines.html#resetting-userdata', docHelp: 'adminguide/virtual_machines.html#resetting-userdata',
dataView: true, dataView: true,
@ -941,7 +941,7 @@ export default {
}, },
{ {
name: 'userdata', name: 'userdata',
title: 'label.user.data', title: 'label.user.data.library',
icon: 'solution-outlined', icon: 'solution-outlined',
docHelp: 'adminguide/virtual_machines.html#user-data-and-meta-data', docHelp: 'adminguide/virtual_machines.html#user-data-and-meta-data',
permission: ['listUserData'], permission: ['listUserData'],
@ -980,7 +980,7 @@ export default {
api: 'registerUserData', api: 'registerUserData',
icon: 'plus-outlined', icon: 'plus-outlined',
label: 'label.register.user.data', label: 'label.register.user.data',
docHelp: 'adminguide/virtual_machines.html#creating-the-ssh-keypair', docHelp: 'adminguide/virtual_machines.html#user-data-and-meta-data',
listView: true, listView: true,
popup: true, popup: true,
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/RegisterUserData.vue'))) component: shallowRef(defineAsyncComponent(() => import('@/views/compute/RegisterUserData.vue')))

View File

@ -48,6 +48,11 @@ export default {
name: 'template', name: 'template',
title: 'label.templates', title: 'label.templates',
param: 'domainid' param: 'domainid'
},
{
name: 'iso',
title: 'label.isos',
param: 'domainid'
}], }],
tabs: [ tabs: [
{ {

View File

@ -182,7 +182,7 @@ export default {
{ {
api: 'replaceNetworkACLList', api: 'replaceNetworkACLList',
icon: 'swap-outlined', icon: 'swap-outlined',
label: 'label.replace.acl.list', label: 'label.replace.acl',
message: 'message.confirm.replace.acl.new.one', message: 'message.confirm.replace.acl.new.one',
docHelp: 'adminguide/networking_and_traffic.html#configuring-network-access-control-list', docHelp: 'adminguide/networking_and_traffic.html#configuring-network-access-control-list',
dataView: true, dataView: true,
@ -698,7 +698,7 @@ export default {
{ {
api: 'resetUserDataForVirtualMachine', api: 'resetUserDataForVirtualMachine',
icon: 'solution-outlined', icon: 'solution-outlined',
label: 'label.reset.userdata.on.vm', label: 'label.reset.user.data.on.vm',
message: 'message.desc.reset.userdata', message: 'message.desc.reset.userdata',
docHelp: 'adminguide/virtual_machines.html#resetting-userdata', docHelp: 'adminguide/virtual_machines.html#resetting-userdata',
dataView: true, dataView: true,
@ -965,7 +965,7 @@ export default {
{ {
api: 'replaceNetworkACLList', api: 'replaceNetworkACLList',
icon: 'swap-outlined', icon: 'swap-outlined',
label: 'label.replace.acl.list', label: 'label.replace.acl',
message: 'message.confirm.replace.acl.new.one', message: 'message.confirm.replace.acl.new.one',
docHelp: 'adminguide/networking_and_traffic.html#acl-on-private-gateway', docHelp: 'adminguide/networking_and_traffic.html#acl-on-private-gateway',
dataView: true, dataView: true,
@ -1061,10 +1061,9 @@ export default {
}, },
{ {
name: 'acllist', name: 'acllist',
title: 'label.network.acl.lists', title: 'label.network.acls',
icon: 'bars-outlined', icon: 'bars-outlined',
docHelp: 'adminguide/networking_and_traffic.html#configuring-network-access-control-list', docHelp: 'adminguide/networking_and_traffic.html#configuring-network-access-control-list',
hidden: true,
permission: ['listNetworkACLLists'], permission: ['listNetworkACLLists'],
columns: ['name', 'description', 'id'], columns: ['name', 'description', 'id'],
details: ['name', 'description', 'id'], details: ['name', 'description', 'id'],
@ -1072,15 +1071,15 @@ export default {
name: 'details', name: 'details',
component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue'))) component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue')))
}, { }, {
name: 'acl.list.rules', name: 'acl.rules',
component: shallowRef(defineAsyncComponent(() => import('@/views/network/AclListRulesTab.vue'))), component: shallowRef(defineAsyncComponent(() => import('@/views/network/AclRulesTab.vue'))),
show: () => true show: () => true
}], }],
actions: [ actions: [
{ {
api: 'createNetworkACLList', api: 'createNetworkACLList',
icon: 'plus-outlined', icon: 'plus-outlined',
label: 'label.add.acl.list', label: 'label.add.acl',
docHelp: 'adminguide/networking_and_traffic.html#creating-acl-lists', docHelp: 'adminguide/networking_and_traffic.html#creating-acl-lists',
listView: true, listView: true,
args: ['name', 'description', 'vpcid'] args: ['name', 'description', 'vpcid']
@ -1088,15 +1087,15 @@ export default {
{ {
api: 'updateNetworkACLList', api: 'updateNetworkACLList',
icon: 'edit-outlined', icon: 'edit-outlined',
label: 'label.edit.acl.list', label: 'label.edit.acl',
dataView: true, dataView: true,
args: ['name', 'description'] args: ['name', 'description']
}, },
{ {
api: 'deleteNetworkACLList', api: 'deleteNetworkACLList',
icon: 'delete-outlined', icon: 'delete-outlined',
label: 'label.delete.acl.list', label: 'label.delete.acl',
message: 'message.confirm.delete.acl.list', message: 'message.confirm.delete.acl',
dataView: true dataView: true
} }
] ]

View File

@ -39,7 +39,7 @@ export default {
} }
}, },
columns: () => { columns: () => {
const fields = ['name', 'state', 'sizegb', 'type', 'vmname', 'vmstate'] const fields = ['name', 'state', 'size', 'type', 'vmname', 'vmstate']
const metricsFields = ['diskkbsread', 'diskkbswrite', 'diskiopstotal'] const metricsFields = ['diskkbsread', 'diskkbswrite', 'diskiopstotal']
if (store.getters.userInfo.roletype === 'Admin') { if (store.getters.userInfo.roletype === 'Admin') {

View File

@ -76,7 +76,7 @@
<div class="form" v-if="userdataid"> <div class="form" v-if="userdataid">
<div class="form__item"> <div class="form__item">
<div class="form__label"> <div class="form__label">
<tooltip-label :title="$t('label.userdataid')"/> <tooltip-label :title="$t('label.user.data.id')"/>
</div> </div>
{{ userdataid }} {{ userdataid }}
</div> </div>
@ -84,7 +84,7 @@
<div class="form" v-if="userdataname"> <div class="form" v-if="userdataname">
<div class="form__item"> <div class="form__item">
<div class="form__label"> <div class="form__label">
<tooltip-label :title="$t('label.userdataname')"/> <tooltip-label :title="$t('label.user.data.name')"/>
</div> </div>
{{ userdataname }} {{ userdataname }}
</div> </div>
@ -92,7 +92,7 @@
<div class="form" v-if="userdatadetails"> <div class="form" v-if="userdatadetails">
<div class="form__item"> <div class="form__item">
<div class="form__label"> <div class="form__label">
<tooltip-label :title="$t('label.userdatadetails')"/> <tooltip-label :title="$t('label.user.data.details')"/>
</div> </div>
{{ userdatadetails }} {{ userdatadetails }}
</div> </div>
@ -100,7 +100,7 @@
<div class="form" v-if="userdatapolicy"> <div class="form" v-if="userdatapolicy">
<div class="form__item"> <div class="form__item">
<div class="form__label"> <div class="form__label">
<tooltip-label :title="$t('label.userdatapolicy')"/> <tooltip-label :title="$t('label.user.data.policy')"/>
</div> </div>
{{ userdatapolicy }} {{ userdatapolicy }}
</div> </div>
@ -108,7 +108,7 @@
<div class="form"> <div class="form">
<div class="form__item"> <div class="form__item">
<div class="form__label"> <div class="form__label">
<tooltip-label :title="$t('label.userdata')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/> <tooltip-label :title="$t('label.user.data')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/>
</div> </div>
<a-textarea v-model:value="userdata" rows="5" :disabled="true"> <a-textarea v-model:value="userdata" rows="5" :disabled="true">
</a-textarea> </a-textarea>
@ -124,7 +124,7 @@
<div class="form__item"> <div class="form__item">
<a-button ref="submit" :disabled="!('updateAutoScaleVmProfile' in $store.getters.apis) || resource.state !== 'DISABLED'" type="primary" @click="showUpdateUserDataForm = true"> <a-button ref="submit" :disabled="!('updateAutoScaleVmProfile' in $store.getters.apis) || resource.state !== 'DISABLED'" type="primary" @click="showUpdateUserDataForm = true">
<template #icon><solution-outlined /></template> <template #icon><solution-outlined /></template>
{{ $t('label.reset.userdata.on.autoscale.vm.group') }} {{ $t('label.reset.user.data.on.autoscale.vm.group') }}
</a-button> </a-button>
</div> </div>
</div> </div>
@ -291,7 +291,7 @@
<a-modal <a-modal
:visible="showUpdateUserDataForm" :visible="showUpdateUserDataForm"
:title="$t('label.reset.userdata.on.autoscale.vm.group')" :title="$t('label.reset.user.data.on.autoscale.vm.group')"
:closable="true" :closable="true"
:maskClosable="false" :maskClosable="false"
:footer="null" :footer="null"

View File

@ -763,7 +763,7 @@
</a-form-item> </a-form-item>
<a-form-item> <a-form-item>
<template #label> <template #label>
<tooltip-label :title="$t('label.userdata')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/> <tooltip-label :title="$t('label.user.data')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/>
</template> </template>
<a-card> <a-card>
<div v-if="this.template && this.template.userdataid"> <div v-if="this.template && this.template.userdataid">
@ -791,11 +791,11 @@
</div><br/><br/> </div><br/><br/>
<div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy"> <div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy">
<span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" > <span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" >
{{ $t('label.userdata.do.override') }} {{ $t('label.user.data.do.override') }}
<a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/> <a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/>
</span> </span>
<span v-if="userdataDefaultOverridePolicy === 'APPEND'"> <span v-if="userdataDefaultOverridePolicy === 'APPEND'">
{{ $t('label.userdata.do.append') }} {{ $t('label.user.data.do.append') }}
<a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/> <a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/>
</span> </span>
<a-step <a-step
@ -1258,11 +1258,11 @@ export default {
userDataValues: {}, userDataValues: {},
templateUserDataCols: [ templateUserDataCols: [
{ {
title: this.$t('label.userdata'), title: this.$t('label.user.data'),
dataIndex: 'userdata' dataIndex: 'userdata'
}, },
{ {
title: this.$t('label.userdatapolicy'), title: this.$t('label.user.data.policy'),
dataIndex: 'userdataoverridepolicy' dataIndex: 'userdataoverridepolicy'
} }
], ],
@ -1459,11 +1459,11 @@ export default {
let tabList = [] let tabList = []
tabList = [{ tabList = [{
key: 'userdataregistered', key: 'userdataregistered',
tab: this.$t('label.userdata.registered') tab: this.$t('label.user.data.registered')
}, },
{ {
key: 'userdatatext', key: 'userdatatext',
tab: this.$t('label.userdata.text') tab: this.$t('label.user.data.text')
}] }]
return tabList return tabList
}, },

View File

@ -616,7 +616,7 @@
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
<a-form-item :label="$t('label.userdata')"> <a-form-item :label="$t('label.user.data')">
<a-card> <a-card>
<div v-if="this.template && this.template.userdataid"> <div v-if="this.template && this.template.userdataid">
<a-typography-text> <a-typography-text>
@ -670,11 +670,11 @@
</div><br/><br/> </div><br/><br/>
<div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy"> <div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy">
<span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" > <span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" >
{{ $t('label.userdata.do.override') }} {{ $t('label.user.data.do.override') }}
<a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/> <a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/>
</span> </span>
<span v-if="userdataDefaultOverridePolicy === 'APPEND'"> <span v-if="userdataDefaultOverridePolicy === 'APPEND'">
{{ $t('label.userdata.do.append') }} {{ $t('label.user.data.do.append') }}
<a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/> <a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/>
</span> </span>
<a-step <a-step
@ -1014,8 +1014,7 @@ export default {
keyboards: [], keyboards: [],
bootTypes: [], bootTypes: [],
bootModes: [], bootModes: [],
ioPolicyTypes: [], ioPolicyTypes: []
dynamicScalingVmConfig: false
}, },
rowCount: {}, rowCount: {},
loading: { loading: {
@ -1076,11 +1075,11 @@ export default {
userDataValues: {}, userDataValues: {},
templateUserDataCols: [ templateUserDataCols: [
{ {
title: this.$t('label.userdata'), title: this.$t('label.user.data'),
dataIndex: 'userdata' dataIndex: 'userdata'
}, },
{ {
title: this.$t('label.userdatapolicy'), title: this.$t('label.user.data.policy'),
dataIndex: 'userdataoverridepolicy' dataIndex: 'userdataoverridepolicy'
} }
], ],
@ -1438,11 +1437,11 @@ export default {
let tabList = [] let tabList = []
tabList = [{ tabList = [{
key: 'userdataregistered', key: 'userdataregistered',
tab: this.$t('label.userdata.registered') tab: this.$t('label.user.data.registered')
}, },
{ {
key: 'userdatatext', key: 'userdatatext',
tab: this.$t('label.userdata.text') tab: this.$t('label.user.data.text')
}] }]
return tabList return tabList
@ -1469,7 +1468,7 @@ export default {
return Boolean('listUserData' in this.$store.getters.apis) return Boolean('listUserData' in this.$store.getters.apis)
}, },
dynamicScalingVmConfigValue () { dynamicScalingVmConfigValue () {
return this.options.dynamicScalingVmConfig?.[0]?.value === 'true' return this.$store.getters.features.dynamicscalingenabled
}, },
isCustomizedDiskIOPS () { isCustomizedDiskIOPS () {
return this.diskSelected?.iscustomizediops || false return this.diskSelected?.iscustomizediops || false
@ -2529,20 +2528,29 @@ export default {
if (exclude && exclude.length > 0 && exclude.includes(name)) { if (exclude && exclude.length > 0 && exclude.includes(name)) {
return resolve(null) return resolve(null)
} }
}
this.loading[name] = true this.loading[name] = true
param.loading = true param.loading = true
param.opts = [] param.opts = []
const options = param.options || {} const options = param.options || {}
if (!('listall' in options) && !['zones', 'pods', 'clusters', 'hosts', 'dynamicScalingVmConfig', 'hypervisors'].includes(name)) { if (!('listall' in options) && !['zones', 'pods', 'clusters', 'hosts', 'hypervisors'].includes(name)) {
options.listall = true options.listall = true
} }
postAPI(param.list, options).then((response) => { postApi(param.list, options).then((response) => {
param.loading = false param.loading = false
_.map(response, (responseItem, responseKey) => { _.map(response, (responseItem, responseKey) => {
if (Object.keys(responseItem).length === 0) { if (Object.keys(responseItem).length === 0) {
this.rowCount[name] = 0 this.rowCount[name] = 0
this.options[name] = [] this.options[name] = []
return resolve(null) return
}
if (!responseKey.includes('response')) {
return
}
_.map(responseItem, (response, key) => {
if (key === 'count') {
this.rowCount[name] = response
return
} }
if (!responseKey.includes('response')) { if (!responseKey.includes('response')) {
return resolve(null) return resolve(null)

View File

@ -550,7 +550,7 @@
@change="val => { dynamicscalingenabled = val }"/> @change="val => { dynamicscalingenabled = val }"/>
</a-form-item> </a-form-item>
</a-form-item> </a-form-item>
<a-form-item :label="$t('label.userdata')"> <a-form-item :label="$t('label.user.data')">
<a-card> <a-card>
<div v-if="this.template && this.template.userdataid"> <div v-if="this.template && this.template.userdataid">
<a-typography-text> <a-typography-text>
@ -604,11 +604,11 @@
</div><br/><br/> </div><br/><br/>
<div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy"> <div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy">
<span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" > <span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" >
{{ $t('label.userdata.do.override') }} {{ $t('label.user.data.do.override') }}
<a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/> <a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/>
</span> </span>
<span v-if="userdataDefaultOverridePolicy === 'APPEND'"> <span v-if="userdataDefaultOverridePolicy === 'APPEND'">
{{ $t('label.userdata.do.append') }} {{ $t('label.user.data.do.append') }}
<a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/> <a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/>
</span> </span>
<a-step <a-step
@ -953,8 +953,7 @@ export default {
keyboards: [], keyboards: [],
bootTypes: [], bootTypes: [],
bootModes: [], bootModes: [],
ioPolicyTypes: [], ioPolicyTypes: []
dynamicScalingVmConfig: false
}, },
rowCount: {}, rowCount: {},
loading: { loading: {
@ -1012,11 +1011,11 @@ export default {
userDataValues: {}, userDataValues: {},
templateUserDataCols: [ templateUserDataCols: [
{ {
title: this.$t('label.userdata'), title: this.$t('label.user.data'),
dataIndex: 'userdata' dataIndex: 'userdata'
}, },
{ {
title: this.$t('label.userdatapolicy'), title: this.$t('label.user.data.policy'),
dataIndex: 'userdataoverridepolicy' dataIndex: 'userdataoverridepolicy'
} }
], ],
@ -1291,16 +1290,17 @@ export default {
}] }]
}, },
userdataTabList () { userdataTabList () {
return [ let tabList = []
{ tabList = [{
key: 'userdataregistered', key: 'userdataregistered',
tab: this.$t('label.userdata.registered') tab: this.$t('label.user.data.registered')
}, },
{ {
key: 'userdatatext', key: 'userdatatext',
tab: this.$t('label.userdata.text') tab: this.$t('label.user.data.text')
} }]
]
return tabList
}, },
showVnfNicsSection () { showVnfNicsSection () {
return this.networks && this.networks.length > 0 && this.vm.templateid && this.templateVnfNics && this.templateVnfNics.length > 0 return this.networks && this.networks.length > 0 && this.vm.templateid && this.templateVnfNics && this.templateVnfNics.length > 0
@ -1331,7 +1331,7 @@ export default {
return Boolean('listUserData' in this.$store.getters.apis) return Boolean('listUserData' in this.$store.getters.apis)
}, },
dynamicScalingVmConfigValue () { dynamicScalingVmConfigValue () {
return this.options.dynamicScalingVmConfig?.[0]?.value === 'true' return this.$store.getters.features.dynamicscalingenabled
}, },
isCustomizedDiskIOPS () { isCustomizedDiskIOPS () {
return this.diskSelected?.iscustomizediops || false return this.diskSelected?.iscustomizediops || false
@ -2472,20 +2472,29 @@ export default {
if (exclude && exclude.length > 0 && exclude.includes(name)) { if (exclude && exclude.length > 0 && exclude.includes(name)) {
return resolve(null) return resolve(null)
} }
}
this.loading[name] = true this.loading[name] = true
param.loading = true param.loading = true
param.opts = [] param.opts = []
const options = param.options || {} const options = param.options || {}
if (!('listall' in options) && !['zones', 'pods', 'clusters', 'hosts', 'dynamicScalingVmConfig', 'hypervisors'].includes(name)) { if (!('listall' in options) && !['zones', 'pods', 'clusters', 'hosts', 'hypervisors'].includes(name)) {
options.listall = true options.listall = true
} }
postAPI(param.list, options).then((response) => { postApi(param.list, options).then((response) => {
param.loading = false param.loading = false
_.map(response, (responseItem, responseKey) => { _.map(response, (responseItem, responseKey) => {
if (Object.keys(responseItem).length === 0) { if (Object.keys(responseItem).length === 0) {
this.rowCount[name] = 0 this.rowCount[name] = 0
this.options[name] = [] this.options[name] = []
return resolve(null) return
}
if (!responseKey.includes('response')) {
return
}
_.map(responseItem, (response, key) => {
if (key === 'count') {
this.rowCount[name] = response
return
} }
if (!responseKey.includes('response')) { if (!responseKey.includes('response')) {
return resolve(null) return resolve(null)

Some files were not shown because too many files have changed in this diff Show More