diff --git a/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java b/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java index c01345ca21b..dd388d2a2d8 100644 --- a/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java +++ b/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java @@ -37,7 +37,7 @@ import com.cloud.resource.ServerResource; * AgentManager manages hosts. It directly coordinates between the DAOs and the connections it manages. */ public interface AgentManager { - static final ConfigKey Wait = new ConfigKey("Advanced", Integer.class, "wait", "1800", "Time in seconds to wait for control commands to return", + ConfigKey Wait = new ConfigKey("Advanced", Integer.class, "wait", "1800", "Time in seconds to wait for control commands to return", true); ConfigKey EnableKVMAutoEnableDisable = new ConfigKey<>(Boolean.class, "enable.kvm.host.auto.enable.disable", @@ -54,7 +54,7 @@ public interface AgentManager { "This timeout overrides the wait global config. This holds a comma separated key value pairs containing timeout (in seconds) for specific commands. " + "For example: DhcpEntryCommand=600, SavePasswordCommand=300, VmDataCommand=300", false); - public enum TapAgentsAction { + enum TapAgentsAction { Add, Del, Contains, } diff --git a/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java index 6d4bcb7b0d9..9b410ce82a5 100644 --- a/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java @@ -55,8 +55,8 @@ import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.management.ManagementServerHost; import org.apache.cloudstack.outofbandmanagement.dao.OutOfBandManagementDao; import org.apache.cloudstack.utils.identity.ManagementServerNode; -import org.apache.commons.collections.MapUtils; import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils; +import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.ThreadContext; @@ -223,6 +223,8 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl "Number of maximum concurrent new connections server allows for remote (indirect) agents. " + "If set to zero (default value) then no limit will be enforced on concurrent new connections", false); + protected final ConfigKey RemoteAgentNewConnectionsMonitorInterval = new ConfigKey<>("Advanced", Integer.class, "agent.connections.monitor.interval", "1800", + "Time in seconds to monitor the new agent connections and cleanup the expired connections.", false); protected final ConfigKey AlertWait = new ConfigKey<>("Advanced", Integer.class, "alert.wait", "1800", "Seconds to wait before alerting on a disconnected agent", true); protected final ConfigKey DirectAgentLoadSize = new ConfigKey<>("Advanced", Integer.class, "direct.agent.load.size", "16", @@ -1945,7 +1947,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl @Override protected void runInContext() { logger.trace("Agent New Connections Monitor is started."); - final int cleanupTime = Wait.value(); + final int cleanupTime = RemoteAgentNewConnectionsMonitorInterval.value(); Set> entrySet = newAgentConnections.entrySet(); long cutOff = System.currentTimeMillis() - (cleanupTime * 1000L); List expiredConnections = newAgentConnections.entrySet() @@ -2040,7 +2042,8 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl public ConfigKey[] getConfigKeys() { return new ConfigKey[] { CheckTxnBeforeSending, Workers, Port, Wait, AlertWait, DirectAgentLoadSize, DirectAgentPoolSize, DirectAgentThreadCap, EnableKVMAutoEnableDisable, ReadyCommandWait, - GranularWaitTimeForCommands, RemoteAgentSslHandshakeTimeout, RemoteAgentMaxConcurrentNewConnections }; + GranularWaitTimeForCommands, RemoteAgentSslHandshakeTimeout, RemoteAgentMaxConcurrentNewConnections, + RemoteAgentNewConnectionsMonitorInterval }; } protected class SetHostParamsListener implements Listener { diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index 576f7793565..15e3110f51b 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -427,7 +427,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac static final ConfigKey VmOpCleanupInterval = new ConfigKey("Advanced", Long.class, "vm.op.cleanup.interval", "86400", "Interval to run the thread that cleans up the vm operations (in seconds)", false); static final ConfigKey VmOpCleanupWait = new ConfigKey("Advanced", Long.class, "vm.op.cleanup.wait", "3600", - "Time (in seconds) to wait before cleanuping up any vm work items", true); + "Time (in seconds) to wait before cleaning up any vm work items", true); static final ConfigKey VmOpCancelInterval = new ConfigKey("Advanced", Long.class, "vm.op.cancel.interval", "3600", "Time (in seconds) to wait before cancelling a operation", false); static final ConfigKey VmDestroyForcestop = new ConfigKey("Advanced", Boolean.class, "vm.destroy.forcestop", "false", diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java index 4298c9a7218..1d405316ad7 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java @@ -23,6 +23,7 @@ import static com.cloud.utils.ReflectUtil.flattenProperties; import static com.google.common.collect.Lists.newArrayList; import java.io.File; +import java.io.UnsupportedEncodingException; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; @@ -810,7 +811,7 @@ public class XenServerStorageProcessor implements StorageProcessor { final SR poolSr = hypervisorResource.getStorageRepository(conn, CitrixHelper.getSRNameLabel(primaryStore.getUuid(), primaryStore.getPoolType(), primaryStore.getPath())); VDI.Record vdir = new VDI.Record(); - vdir.nameLabel = volume.getName(); + vdir.nameLabel = getEncodedVolumeName(volume.getName()); vdir.SR = poolSr; vdir.type = Types.VdiType.USER; @@ -831,6 +832,26 @@ public class XenServerStorageProcessor implements StorageProcessor { } } + private String getEncodedVolumeName(String volumeName) throws UnsupportedEncodingException { + byte[] utf8Bytes = volumeName.getBytes("UTF-8"); + // Decode UTF-8 into a Java String (UTF-16) + String decoded = new String(utf8Bytes, "UTF-8"); + // Print each code unit as a Unicode escape + StringBuilder unicodeEscaped = new StringBuilder(); + for (int i = 0; i < decoded.length(); i++) { + char ch = decoded.charAt(i); + if (ch <= 127 && Character.isLetterOrDigit(ch)) { + // Keep ASCII alphanumerics as-is + unicodeEscaped.append(ch); + } else { + // Escape non-ASCII characters + unicodeEscaped.append(String.format("\\u%04X", (int) ch)); + } + } + + return unicodeEscaped.toString(); + } + @Override public Answer cloneVolumeFromBaseTemplate(final CopyCommand cmd) { final Connection conn = hypervisorResource.getConnection(); diff --git a/plugins/storage/object/ceph/src/main/java/org/apache/cloudstack/storage/datastore/driver/CephObjectStoreDriverImpl.java b/plugins/storage/object/ceph/src/main/java/org/apache/cloudstack/storage/datastore/driver/CephObjectStoreDriverImpl.java index 7eb350a0643..5b5eaa08dc5 100644 --- a/plugins/storage/object/ceph/src/main/java/org/apache/cloudstack/storage/datastore/driver/CephObjectStoreDriverImpl.java +++ b/plugins/storage/object/ceph/src/main/java/org/apache/cloudstack/storage/datastore/driver/CephObjectStoreDriverImpl.java @@ -95,8 +95,8 @@ public class CephObjectStoreDriverImpl extends BaseObjectStoreDriverImpl { AmazonS3 s3client = getS3Client(storeId, accountId); try { - if (s3client.getBucketAcl(bucketName) != null) { - throw new CloudRuntimeException("Bucket already exists with name " + bucketName); + if (s3client.doesBucketExistV2(bucketName)) { + throw new CloudRuntimeException("Bucket already exists with the name: " + bucketName); } } catch (AmazonS3Exception e) { if (e.getStatusCode() != 404) { @@ -221,9 +221,11 @@ public class CephObjectStoreDriverImpl extends BaseObjectStoreDriverImpl { if (user.isPresent()) { logger.info("User already exists in Ceph RGW: " + username); return true; + } else { + logger.debug("User does not exist. Creating user in Ceph RGW: " + username); } } catch (Exception e) { - logger.debug("User does not exist. Creating user in Ceph RGW: " + username); + logger.debug("Get user info failed for user {} with exception {}. Proceeding with user creation.", username, e.getMessage()); } try { @@ -348,7 +350,7 @@ public class CephObjectStoreDriverImpl extends BaseObjectStoreDriverImpl { new AWSStaticCredentialsProvider( new BasicAWSCredentials(accessKey, secretKey))) .withEndpointConfiguration( - new AwsClientBuilder.EndpointConfiguration(url, "auto")) + new AwsClientBuilder.EndpointConfiguration(url, null)) .build(); if (client == null) { diff --git a/plugins/storage/object/ceph/src/test/java/org/apache/cloudstack/storage/datastore/driver/CephObjectStoreDriverImplTest.java b/plugins/storage/object/ceph/src/test/java/org/apache/cloudstack/storage/datastore/driver/CephObjectStoreDriverImplTest.java index d0cd2e86a22..33919107b5a 100644 --- a/plugins/storage/object/ceph/src/test/java/org/apache/cloudstack/storage/datastore/driver/CephObjectStoreDriverImplTest.java +++ b/plugins/storage/object/ceph/src/test/java/org/apache/cloudstack/storage/datastore/driver/CephObjectStoreDriverImplTest.java @@ -96,7 +96,7 @@ public class CephObjectStoreDriverImplTest { when(bucketDao.findById(anyLong())).thenReturn(new BucketVO(bucket.getName())); Bucket bucketRet = cephObjectStoreDriverImpl.createBucket(bucket, false); assertEquals(bucketRet.getName(), bucket.getName()); - verify(rgwClient, times(1)).getBucketAcl(anyString()); + verify(rgwClient, times(1)).doesBucketExistV2(anyString()); verify(rgwClient, times(1)).createBucket(anyString()); } diff --git a/python/lib/cloudutils/networkConfig.py b/python/lib/cloudutils/networkConfig.py index 2d1f9936d39..ac51f92aa58 100644 --- a/python/lib/cloudutils/networkConfig.py +++ b/python/lib/cloudutils/networkConfig.py @@ -41,7 +41,7 @@ class networkConfig: return devs @staticmethod def getDefaultNetwork(): - cmd = bash("route -n|awk \'/^0.0.0.0/ {print $2,$8}\'") + cmd = bash("ip route show default | awk \'{print $3,$5}\'") if not cmd.isSuccess(): logging.debug("Failed to get default route") raise CloudRuntimeException("Failed to get default route") diff --git a/server/src/main/java/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java b/server/src/main/java/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java index 936d9cfb3d6..17e0c46faab 100644 --- a/server/src/main/java/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java +++ b/server/src/main/java/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java @@ -229,11 +229,6 @@ public class AdvancedNetworkTopology extends BasicNetworkTopology { public boolean applyNetworkACLs(final Network network, final List rules, final VirtualRouter router, final boolean isPrivateGateway) throws ResourceUnavailableException { - if (rules == null || rules.isEmpty()) { - logger.debug("No network ACLs to be applied for network {}", network); - return true; - } - logger.debug("APPLYING NETWORK ACLs RULES"); final String typeString = "network acls"; diff --git a/server/src/test/java/org/apache/cloudstack/resource/ResourceCleanupServiceImplTest.java b/server/src/test/java/org/apache/cloudstack/resource/ResourceCleanupServiceImplTest.java index 7446e290488..2ca9c0ef11b 100644 --- a/server/src/test/java/org/apache/cloudstack/resource/ResourceCleanupServiceImplTest.java +++ b/server/src/test/java/org/apache/cloudstack/resource/ResourceCleanupServiceImplTest.java @@ -17,6 +17,11 @@ package org.apache.cloudstack.resource; import java.lang.reflect.Field; +import java.time.Duration; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.zone.ZoneRules; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -629,9 +634,23 @@ public class ResourceCleanupServiceImplTest { Date result = resourceCleanupService.calculatePastDateFromConfig( ResourceCleanupService.ExpungedResourcesPurgeKeepPastDays.key(), days); - Date today = new Date(); - long diff = today.getTime() - result.getTime(); - Assert.assertEquals(days, TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS)); + Instant resultInstant = result.toInstant(); + ZoneId systemZone = ZoneId.systemDefault(); + ZoneRules rules = systemZone.getRules(); + ZonedDateTime resultDateTime = resultInstant.atZone(systemZone); + boolean isDSTInResultDateTime = rules.isDaylightSavings(resultDateTime.toInstant()); + + ZonedDateTime todayDateTime = ZonedDateTime.now(systemZone); + boolean isDSTInTodayDateTime = rules.isDaylightSavings(todayDateTime.toInstant()); + + Duration duration = Duration.between(resultDateTime, todayDateTime); + long actualDays = TimeUnit.DAYS.convert(duration.toMillis(), TimeUnit.MILLISECONDS); + + if (!isDSTInResultDateTime && isDSTInTodayDateTime) { + Assert.assertEquals(days - 1, actualDays); + } else { + Assert.assertEquals(days, actualDays); + } } @Test diff --git a/ui/src/config/section/infra/hosts.js b/ui/src/config/section/infra/hosts.js index 16b67d40a6e..5810c9b146f 100644 --- a/ui/src/config/section/infra/hosts.js +++ b/ui/src/config/section/infra/hosts.js @@ -32,7 +32,12 @@ export default { }, params: { type: 'routing' }, columns: () => { - const fields = ['name', 'state', 'resourcestate', 'ipaddress', 'arch', 'hypervisor', 'instances', 'powerstate', 'version'] + const fields = [ + 'name', 'state', 'resourcestate', 'ipaddress', + 'arch', 'hypervisor', 'instances', + { field: 'systeminstances', customTitle: 'system.vms' }, + 'powerstate', 'version' + ] const metricsFields = ['cpunumber', 'cputotalghz', 'cpuusedghz', 'cpuallocatedghz', 'memorytotalgb', 'memoryusedgb', 'memoryallocatedgb', 'networkread', 'networkwrite'] if (store.getters.metrics) { fields.push(...metricsFields) diff --git a/ui/src/views/compute/EditVM.vue b/ui/src/views/compute/EditVM.vue index 75a297cee3e..fad1dcc254e 100644 --- a/ui/src/views/compute/EditVM.vue +++ b/ui/src/views/compute/EditVM.vue @@ -185,7 +185,6 @@ export default { isdynamicallyscalable: this.resource.isdynamicallyscalable, deleteprotection: this.resource.deleteprotection, group: this.resource.group, - securitygroupids: this.resource.securitygroup.map(x => x.id), userdata: '', haenable: this.resource.haenable }) diff --git a/ui/src/views/image/RegisterOrUploadIso.vue b/ui/src/views/image/RegisterOrUploadIso.vue index acf4c3fd15b..6c26f08b581 100644 --- a/ui/src/views/image/RegisterOrUploadIso.vue +++ b/ui/src/views/image/RegisterOrUploadIso.vue @@ -88,6 +88,15 @@ + + + + +