mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	Merge branch '4.20'
This commit is contained in:
		
						commit
						d7d9d131b2
					
				| @ -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<Integer> Wait = new ConfigKey<Integer>("Advanced", Integer.class, "wait", "1800", "Time in seconds to wait for control commands to return", | ||||
|     ConfigKey<Integer> Wait = new ConfigKey<Integer>("Advanced", Integer.class, "wait", "1800", "Time in seconds to wait for control commands to return", | ||||
|             true); | ||||
|     ConfigKey<Boolean> 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, | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -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<Integer> 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<Integer> AlertWait = new ConfigKey<>("Advanced", Integer.class, "alert.wait", "1800", | ||||
|             "Seconds to wait before alerting on a disconnected agent", true); | ||||
|     protected final ConfigKey<Integer> 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<Map.Entry<String, Long>> entrySet = newAgentConnections.entrySet(); | ||||
|             long cutOff = System.currentTimeMillis() - (cleanupTime * 1000L); | ||||
|             List<String> 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 { | ||||
|  | ||||
| @ -427,7 +427,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac | ||||
|     static final ConfigKey<Long> VmOpCleanupInterval = new ConfigKey<Long>("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<Long> VmOpCleanupWait = new ConfigKey<Long>("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<Long> VmOpCancelInterval = new ConfigKey<Long>("Advanced", Long.class, "vm.op.cancel.interval", "3600", | ||||
|             "Time (in seconds) to wait before cancelling a operation", false); | ||||
|     static final ConfigKey<Boolean> VmDestroyForcestop = new ConfigKey<Boolean>("Advanced", Boolean.class, "vm.destroy.forcestop", "false", | ||||
|  | ||||
| @ -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(); | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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()); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -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") | ||||
|  | ||||
| @ -229,11 +229,6 @@ public class AdvancedNetworkTopology extends BasicNetworkTopology { | ||||
|     public boolean applyNetworkACLs(final Network network, final List<? extends NetworkACLItem> 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"; | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
| @ -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 | ||||
|       }) | ||||
|  | ||||
| @ -88,6 +88,15 @@ | ||||
|           <a-switch v-model:checked="form.directdownload"/> | ||||
|         </a-form-item> | ||||
| 
 | ||||
|         <a-form-item ref="checksum" name="checksum"> | ||||
|           <template #label> | ||||
|             <tooltip-label :title="$t('label.checksum')" :tooltip="apiParams.checksum.description"/> | ||||
|           </template> | ||||
|           <a-input | ||||
|             v-model:value="form.checksum" | ||||
|             :placeholder="apiParams.checksum.description" /> | ||||
|         </a-form-item> | ||||
| 
 | ||||
|         <a-form-item ref="zoneid" name="zoneid"> | ||||
|           <template #label> | ||||
|             <tooltip-label :title="$t('label.zoneid')" :tooltip="apiParams.zoneid.description"/> | ||||
|  | ||||
| @ -214,8 +214,8 @@ | ||||
|             </a-form-item> | ||||
|           </a-col> | ||||
|         </a-row> | ||||
|         <a-row :gutter="12" v-if="(hyperKVMShow || hyperCustomShow) && currentForm === 'Create'"> | ||||
|           <a-col :md="24" :lg="12"> | ||||
|         <a-row :gutter="12"> | ||||
|           <a-col :md="24" :lg="12" v-if="(hyperKVMShow || hyperCustomShow) && currentForm === 'Create'"> | ||||
|             <a-form-item ref="directdownload" name="directdownload"> | ||||
|               <template #label> | ||||
|                 <tooltip-label :title="$t('label.directdownload')" :tooltip="apiParams.directdownload.description"/> | ||||
| @ -223,7 +223,7 @@ | ||||
|               <a-switch v-model:checked="form.directdownload" @change="handleChangeDirect" /> | ||||
|             </a-form-item> | ||||
|           </a-col> | ||||
|           <a-col :md="24" :lg="12" v-if="allowDirectDownload"> | ||||
|           <a-col :md="24" :lg="12"> | ||||
|             <a-form-item ref="checksum" name="checksum"> | ||||
|               <template #label> | ||||
|                 <tooltip-label :title="$t('label.checksum')" :tooltip="apiParams.checksum.description"/> | ||||
|  | ||||
| @ -247,7 +247,6 @@ public abstract class NioConnection implements Callable<Boolean> { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     protected void accept(final SelectionKey key) throws IOException { | ||||
|         final ServerSocketChannel serverSocketChannel = (ServerSocketChannel)key.channel(); | ||||
|         final SocketChannel socketChannel = serverSocketChannel.accept(); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user