This is an automated email from the ASF dual-hosted git repository. weizhouapache pushed a commit to branch 4.22 in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit c7e2c748f74619e3b0454d6f2904b89abaf39003 Merge: 57671274d86 a4b102fb3f9 Author: Wei Zhou <[email protected]> AuthorDate: Fri Jul 10 13:29:39 2026 +0200 Merge remote-tracking branch 'apache/4.20' into 4.22 .../service/NetworkOrchestrationService.java | 3 + .../engine/orchestration/NetworkOrchestrator.java | 2 +- .../com/cloud/upgrade/DatabaseUpgradeChecker.java | 6 +- .../com/cloud/upgrade/dao/Upgrade42030to42040.java | 58 +++++++++ .../resourcedetail/ResourceDetailsDao.java | 2 + .../resourcedetail/ResourceDetailsDaoBase.java | 14 +++ .../framework/jobs/impl/AsyncJobManagerImpl.java | 38 +++--- .../framework/jobs/AsyncJobManagerTest.java | 20 ++++ .../kvm/storage/KVMStorageProcessor.java | 2 +- .../org/apache/cloudstack/utils/qemu/QemuImg.java | 6 +- .../adapter/flasharray/FlashArrayAdapter.java | 38 +++++- server/src/main/java/com/cloud/api/ApiServer.java | 8 +- server/src/main/java/com/cloud/api/ApiServlet.java | 22 ++-- .../main/java/com/cloud/configuration/Config.java | 9 -- .../configuration/ConfigurationManagerImpl.java | 2 +- .../consoleproxy/ConsoleProxyManagerImpl.java | 9 +- .../network/element/VirtualRouterElement.java | 24 ++-- .../com/cloud/resource/ResourceManagerImpl.java | 2 +- .../cloudstack/backup/BackupManagerImpl.java | 2 +- .../cloudstack/cluster/ClusterDrsServiceImpl.java | 34 +++--- .../cluster/ClusterDrsServiceImplTest.java | 46 +++---- tools/marvin/setup.py | 2 +- ui/public/locales/en.json | 5 + ui/src/style/vars.less | 2 +- ui/src/utils/ssvmProbe.js | 30 +++++ ui/src/views/image/RegisterOrUploadIso.vue | 50 ++++++-- ui/src/views/image/RegisterOrUploadTemplate.vue | 45 ++++++- ui/src/views/infra/network/IpRangesTabPublic.vue | 4 + ui/src/views/storage/UploadLocalVolume.vue | 133 ++++++++++++++------- 29 files changed, 451 insertions(+), 167 deletions(-) diff --cc engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java index b7b548fb940,97e2a979aa4..d851867ef13 --- a/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java +++ b/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java @@@ -76,61 -76,45 +76,64 @@@ public interface NetworkOrchestrationSe */ Long RVRHandoverTime = 10000L; - ConfigKey<String> MinVRVersion = new ConfigKey<String>(String.class, MinVRVersionCK, "Advanced", "4.10.0", + ConfigKey<String> MinVRVersion = new ConfigKey<>(String.class, MinVRVersionCK, "Advanced", "4.10.0", "What version should the Virtual Routers report", true, ConfigKey.Scope.Zone, null); - ConfigKey<Integer> NetworkLockTimeout = new ConfigKey<Integer>(Integer.class, NetworkLockTimeoutCK, "Network", "600", - "Lock wait timeout (seconds) while implementing Network", true, Scope.Global, null); + ConfigKey<Integer> NetworkLockTimeout = new ConfigKey<>(Integer.class, NetworkLockTimeoutCK, "Network", "600", + "Lock wait timeout (seconds) while implementing Network", true, Scope.Global, null); - ConfigKey<String> DeniedRoutes = new ConfigKey<String>(String.class, "denied.routes", "Network", "", + ConfigKey<String> DeniedRoutes = new ConfigKey<>(String.class, "denied.routes", "Network", "", "Routes that are denied, can not be used for Static Routes creation for the VPC Private Gateway", true, ConfigKey.Scope.Zone, null); - ConfigKey<String> GuestDomainSuffix = new ConfigKey<String>(String.class, GuestDomainSuffixCK, "Network", "cloud.internal", - "Default domain name for vms inside virtualized networks fronted by router", true, ConfigKey.Scope.Zone, null); + ConfigKey<String> GuestDomainSuffix = new ConfigKey<>(String.class, GuestDomainSuffixCK, "Network", "cloud.internal", + "Default domain name for vms inside virtualized networks fronted by router", true, ConfigKey.Scope.Zone, null); - ConfigKey<Integer> NetworkThrottlingRate = new ConfigKey<Integer>("Network", Integer.class, NetworkThrottlingRateCK, "200", - "Default data transfer rate in megabits per second allowed in network.", true, ConfigKey.Scope.Zone); + ConfigKey<Integer> NetworkThrottlingRate = new ConfigKey<>("Network", Integer.class, NetworkThrottlingRateCK, "200", + "Default data transfer rate in megabits per second allowed in network.", true, ConfigKey.Scope.Zone); - ConfigKey<Boolean> PromiscuousMode = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.promiscuous.mode", "false", + ConfigKey<Boolean> PromiscuousMode = new ConfigKey<>("Advanced", Boolean.class, "network.promiscuous.mode", "false", "Whether to allow or deny promiscuous mode on NICs for applicable network elements such as for vswitch/dvswitch portgroups.", true); - ConfigKey<Boolean> MacAddressChanges = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.mac.address.changes", "true", + ConfigKey<Boolean> MacAddressChanges = new ConfigKey<>("Advanced", Boolean.class, "network.mac.address.changes", "true", "Whether to allow or deny mac address changes on NICs for applicable network elements such as for vswitch/dvswitch porgroups.", true); - ConfigKey<Boolean> ForgedTransmits = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.forged.transmits", "true", + ConfigKey<Boolean> ForgedTransmits = new ConfigKey<>("Advanced", Boolean.class, "network.forged.transmits", "true", "Whether to allow or deny forged transmits on NICs for applicable network elements such as for vswitch/dvswitch portgroups.", true); - ConfigKey<Boolean> MacLearning = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.mac.learning", "false", + ConfigKey<Boolean> MacLearning = new ConfigKey<>("Advanced", Boolean.class, "network.mac.learning", "false", "Whether to allow or deny MAC learning on nics for applicable network elements such as for dvswitch portgroups.", true); - ConfigKey<Boolean> RollingRestartEnabled = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.rolling.restart", "true", + ConfigKey<Boolean> RollingRestartEnabled = new ConfigKey<>("Advanced", Boolean.class, "network.rolling.restart", "true", "Whether to allow or deny rolling restart of network routers.", true); - static final ConfigKey<Boolean> TUNGSTEN_ENABLED = new ConfigKey<>(Boolean.class, "tungsten.plugin.enable", "Advanced", "false", + ConfigKey<Boolean> TUNGSTEN_ENABLED = new ConfigKey<>(Boolean.class, "tungsten.plugin.enable", "Advanced", "false", "Indicates whether to enable the Tungsten plugin", false, ConfigKey.Scope.Zone, null); - static final ConfigKey<Boolean> NSX_ENABLED = new ConfigKey<>(Boolean.class, "nsx.plugin.enable", "Advanced", "false", + ConfigKey<Boolean> NSX_ENABLED = new ConfigKey<>(Boolean.class, "nsx.plugin.enable", "Advanced", "false", "Indicates whether to enable the NSX plugin", false, ConfigKey.Scope.Zone, null); + ConfigKey<Boolean> NETRIS_ENABLED = new ConfigKey<>(Boolean.class, "netris.plugin.enable", "Advanced", "false", + "Indicates whether to enable the Netris plugin", false, ConfigKey.Scope.Zone, null); + ConfigKey<Integer> NETWORK_LB_HAPROXY_MAX_CONN = new ConfigKey<>( + "Network", + Integer.class, + "network.loadbalancer.haproxy.max.conn", + "4096", + "Load Balancer(haproxy) maximum number of concurrent connections(global max)", + true, + Scope.Global); + ConfigKey<Long> NETWORK_LB_HAPROXY_IDLE_TIMEOUT = new ConfigKey<>( + "Network", + Long.class, + "network.loadbalancer.haproxy.idle.timeout", + "50000", + "Load Balancer(haproxy) idle timeout in milliseconds. Use 0 for infinite.", + true, + Scope.Global); + + ConfigKey<Integer> VmNetworkThrottlingRate = new ConfigKey<Integer>("Network", Integer.class, "vm.network.throttling.rate", "200", + "Default data transfer rate in megabits per second allowed in User vm's default network.", true, ConfigKey.Scope.Zone); + List<? extends Network> setupNetwork(Account owner, NetworkOffering offering, DeploymentPlan plan, String name, String displayText, boolean isDefault) throws ConcurrentOperationException; diff --cc engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 6fc673cc2c9,f7aa957abb9..55079173dc9 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@@ -4937,9 -4905,8 +4937,9 @@@ public class NetworkOrchestrator extend @Override public ConfigKey<?>[] getConfigKeys() { return new ConfigKey<?>[]{NetworkGcWait, NetworkGcInterval, NetworkLockTimeout, DeniedRoutes, - GuestDomainSuffix, NetworkThrottlingRate, MinVRVersion, + GuestDomainSuffix, NetworkThrottlingRate, VmNetworkThrottlingRate, MinVRVersion, PromiscuousMode, MacAddressChanges, ForgedTransmits, MacLearning, RollingRestartEnabled, - TUNGSTEN_ENABLED, NSX_ENABLED }; + TUNGSTEN_ENABLED, NSX_ENABLED, NETRIS_ENABLED, NETWORK_LB_HAPROXY_MAX_CONN, + NETWORK_LB_HAPROXY_IDLE_TIMEOUT}; } } diff --cc engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java index 296f80f4b5e,0d9807dcb2d..170a12f9374 --- a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java +++ b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java @@@ -89,9 -89,8 +89,11 @@@ import com.cloud.upgrade.dao.Upgrade418 import com.cloud.upgrade.dao.Upgrade41900to41910; import com.cloud.upgrade.dao.Upgrade41910to42000; import com.cloud.upgrade.dao.Upgrade42000to42010; +import com.cloud.upgrade.dao.Upgrade42010to42100; - import com.cloud.upgrade.dao.Upgrade42100to42200; +import com.cloud.upgrade.dao.Upgrade42200to42210; + import com.cloud.upgrade.dao.Upgrade42020to42030; + import com.cloud.upgrade.dao.Upgrade42030to42040; ++import com.cloud.upgrade.dao.Upgrade42100to42200; import com.cloud.upgrade.dao.Upgrade420to421; import com.cloud.upgrade.dao.Upgrade421to430; import com.cloud.upgrade.dao.Upgrade430to440; @@@ -239,9 -238,8 +241,11 @@@ public class DatabaseUpgradeChecker imp .next("4.19.0.0", new Upgrade41900to41910()) .next("4.19.1.0", new Upgrade41910to42000()) .next("4.20.0.0", new Upgrade42000to42010()) + .next("4.20.1.0", new Upgrade42010to42100()) + .next("4.20.2.0", new Upgrade42020to42030()) + .next("4.20.3.0", new Upgrade42030to42040()) + .next("4.21.0.0", new Upgrade42100to42200()) + .next("4.22.0.0", new Upgrade42200to42210()) .build(); } diff --cc engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java index eafaed182ab,74c4f7bcfe0..8f376a71f66 --- a/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java @@@ -21,9 -22,9 +22,10 @@@ import java.util.List import java.util.Map; import java.util.stream.Collectors; + import com.cloud.utils.StringUtils; import org.apache.commons.collections.CollectionUtils; +import com.cloud.utils.Pair; import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; diff --cc plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImg.java index 1fec561dc89,48423b7b60b..80e44d8059a --- a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImg.java +++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImg.java @@@ -61,9 -55,8 +61,9 @@@ public class QemuImg /* The qemu-img binary. We expect this to be in $PATH */ public String _qemuImgPath = "qemu-img"; private String cloudQemuImgPath = "cloud-qemu-img"; - private int timeout; + private long timeout; private boolean skipZero = false; + private boolean skipTargetVolumeCreation = false; private boolean noCache = false; private long version; diff --cc server/src/main/java/com/cloud/api/ApiServlet.java index 93d8e09520a,64308cc9e6b..3ac5bbb01a7 --- a/server/src/main/java/com/cloud/api/ApiServlet.java +++ b/server/src/main/java/com/cloud/api/ApiServlet.java @@@ -368,19 -318,6 +368,19 @@@ public class ApiServlet extends HttpSer } } + if (apiServer.isPostRequestsAndTimestampsEnforced() && !isStateChangingCommandUsingPOST(command, req.getMethod(), params)) { + String errorText = String.format("State changing command %s needs to be sent using POST request", command); + if (command.equalsIgnoreCase("updateConfiguration") && params.containsKey("name")) { + errorText = String.format("Changes for configuration %s needs to be sent using POST request", params.get("name")[0]); + } + auditTrailSb.append(" " + HttpServletResponse.SC_BAD_REQUEST + " " + errorText); + final String serializedResponse = + apiServer.getSerializedApiError(new ServerApiException(ApiErrorCode.BAD_REQUEST, errorText), params, + responseType); - HttpUtils.writeHttpResponse(resp, serializedResponse, HttpServletResponse.SC_BAD_REQUEST, responseType, ApiServer.JSONcontentType.value()); ++ HttpUtils.writeHttpResponse(resp, serializedResponse, HttpServletResponse.SC_BAD_REQUEST, responseType, ApiServer.JSONContentType.value()); + return; + } + Long userId = null; if (!isNew) { userId = (Long)session.getAttribute("userid"); diff --cc server/src/main/java/org/apache/cloudstack/cluster/ClusterDrsServiceImpl.java index 7e1011ff931,fbfed03aa1e..62075aae596 --- a/server/src/main/java/org/apache/cloudstack/cluster/ClusterDrsServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/cluster/ClusterDrsServiceImpl.java @@@ -51,11 -51,13 +51,13 @@@ import com.cloud.utils.db.GlobalLock import com.cloud.utils.db.Transaction; import com.cloud.utils.db.TransactionCallback; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.UserVmDetailVO; ++import com.cloud.vm.VMInstanceDetailVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfileImpl; import com.cloud.vm.VmDetailConstants; -import com.cloud.vm.dao.UserVmDetailsDao; ++import com.cloud.vm.dao.VMInstanceDetailsDao; import com.cloud.vm.dao.VMInstanceDao; import org.apache.cloudstack.api.ApiCommandResourceType; import org.apache.cloudstack.api.ApiConstants; @@@ -134,6 -135,9 +135,9 @@@ public class ClusterDrsServiceImpl exte @Inject ServiceOfferingDao serviceOfferingDao; + @Inject - UserVmDetailsDao userVmDetailsDao; ++ VMInstanceDetailsDao vmInstanceDetailsDao; + @Inject ManagementServer managementServer; @@@ -475,12 -479,16 +479,16 @@@ Map<Long, List<? extends Host>> vmToCompatibleHostsCache = new HashMap<>(); Map<Long, Map<Host, Boolean>> vmToStorageMotionCache = new HashMap<>(); + List<Long> vmIds = vmList.stream().map(VirtualMachine::getId).collect(Collectors.toList()); - Set<Long> skipDrsVmIds = userVmDetailsDao.listDetailsForResourceIdsAndKey(vmIds, VmDetailConstants.SKIP_DRS) ++ Set<Long> skipDrsVmIds = vmInstanceDetailsDao.listDetailsForResourceIdsAndKey(vmIds, VmDetailConstants.SKIP_DRS) + .stream().filter(d -> "true".equalsIgnoreCase(d.getValue())) - .map(UserVmDetailVO::getResourceId) ++ .map(VMInstanceDetailVO::getResourceId) + .collect(Collectors.toSet()); + for (VirtualMachine vm : vmList) { // Skip ineligible VMs - if (vm.getType().isUsedBySystem() || - vm.getState() != VirtualMachine.State.Running || - (MapUtils.isNotEmpty(vm.getDetails()) && - "true".equalsIgnoreCase(vm.getDetails().get(VmDetailConstants.SKIP_DRS)))) { + if (shouldSkipVMForDRS(vm, skipDrsVmIds)) { + logger.debug("Skipping VM {} for DRS as it is ineligible.", vm); continue; } diff --cc server/src/test/java/org/apache/cloudstack/cluster/ClusterDrsServiceImplTest.java index 98b18c66305,6dc73b7a630..6390b29097b --- a/server/src/test/java/org/apache/cloudstack/cluster/ClusterDrsServiceImplTest.java +++ b/server/src/test/java/org/apache/cloudstack/cluster/ClusterDrsServiceImplTest.java @@@ -40,9 -40,11 +40,11 @@@ import com.cloud.utils.Pair import com.cloud.utils.Ternary; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.UserVmDetailVO; ++import com.cloud.vm.VMInstanceDetailVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VmDetailConstants; -import com.cloud.vm.dao.UserVmDetailsDao; ++import com.cloud.vm.dao.VMInstanceDetailsDao; import com.cloud.vm.dao.VMInstanceDao; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.api.command.admin.cluster.GenerateClusterDrsPlanCmd; @@@ -121,6 -123,9 +123,9 @@@ public class ClusterDrsServiceImplTest @Mock private AffinityGroupVMMapDao affinityGroupVMMapDao; + @Mock - private UserVmDetailsDao userVmDetailsDao; ++ private VMInstanceDetailsDao vmInstanceDetailsDao; + @Spy @InjectMocks private ClusterDrsServiceImpl clusterDrsService = new ClusterDrsServiceImpl(); @@@ -370,6 -376,11 +376,11 @@@ Mockito.when(hostJoin1.getMemReservedCapacity()).thenReturn(0L); Mockito.when(hostJoin1.getTotalMemory()).thenReturn(8192L); + // Return the SKIP_DRS detail for skippedVm so the flag is actually honoured - UserVmDetailVO skipDrsDetail = new UserVmDetailVO(1L, VmDetailConstants.SKIP_DRS, "true", true); - Mockito.when(userVmDetailsDao.listDetailsForResourceIdsAndKey(Mockito.anyList(), ++ VMInstanceDetailVO skipDrsDetail = new VMInstanceDetailVO(1L, VmDetailConstants.SKIP_DRS, "true", true); ++ Mockito.when(vmInstanceDetailsDao.listDetailsForResourceIdsAndKey(Mockito.anyList(), + Mockito.eq(VmDetailConstants.SKIP_DRS))).thenReturn(List.of(skipDrsDetail)); + Mockito.when(hostDao.findByClusterId(1L)).thenReturn(hostList); Mockito.when(vmInstanceDao.listByClusterId(1L)).thenReturn(vmList); Mockito.when(balancedAlgorithm.needsDrs(Mockito.any(), Mockito.anyList(), Mockito.anyList())).thenReturn(true); diff --cc ui/src/views/image/RegisterOrUploadIso.vue index e8ce5add61b,1984a6a6144..eb19379dc8e --- a/ui/src/views/image/RegisterOrUploadIso.vue +++ b/ui/src/views/image/RegisterOrUploadIso.vue @@@ -583,9 -617,8 +617,8 @@@ export default } params.format = 'ISO' this.loading = true - getAPI('getUploadParamsForIso', params).then(json => { - api('getUploadParamsForIso', params).then(async json => { ++ getAPI('getUploadParamsForIso', params).then(async json => { this.uploadParams = (json.postuploadisoresponse && json.postuploadisoresponse.getuploadparams) ? json.postuploadisoresponse.getuploadparams : '' - const response = this.handleUpload() if (this.userdataid !== null) { this.linkUserdataToTemplate(this.userdataid, json.postuploadisoresponse.iso[0].id) } diff --cc ui/src/views/image/RegisterOrUploadTemplate.vue index 00b06072793,1267e5d45c1..13e6b50dcc7 --- a/ui/src/views/image/RegisterOrUploadTemplate.vue +++ b/ui/src/views/image/RegisterOrUploadTemplate.vue @@@ -505,9 -488,9 +521,10 @@@ import { getAPI, postAPI } from '@/api import store from '@/store' import { axios } from '../../utils/request' import { mixinForm } from '@/utils/mixin' + import { probeSsvmCert } from '@/utils/ssvmProbe' import ResourceIcon from '@/components/view/ResourceIcon' import TooltipLabel from '@/components/widgets/TooltipLabel' +import DetailsInput from '@/components/widgets/DetailsInput' export default { name: 'RegisterOrUploadTemplate', @@@ -1175,9 -1157,8 +1208,8 @@@ duration: 0 }) } - getAPI('getUploadParamsForTemplate', params).then(json => { - api('getUploadParamsForTemplate', params).then(async json => { ++ getAPI('getUploadParamsForTemplate', params).then(async json => { this.uploadParams = (json.postuploadtemplateresponse && json.postuploadtemplateresponse.getuploadparams) ? json.postuploadtemplateresponse.getuploadparams : '' - this.handleUpload() if (this.userdataid !== null) { this.linkUserdataToTemplate(this.userdataid, json.postuploadtemplateresponse.template[0].id) } diff --cc ui/src/views/storage/UploadLocalVolume.vue index 5e6a5b4fc27,b7303117e5a..b936ebdfac7 --- a/ui/src/views/storage/UploadLocalVolume.vue +++ b/ui/src/views/storage/UploadLocalVolume.vue @@@ -153,9 -169,10 +169,10 @@@ <script> import { ref, reactive, toRaw } from 'vue' -import { api } from '@/api' +import { getAPI } from '@/api' import { axios } from '../../utils/request' import { mixinForm } from '@/utils/mixin' + import { probeSsvmCert } from '@/utils/ssvmProbe' import ResourceIcon from '@/components/view/ResourceIcon' import TooltipLabel from '@/components/widgets/TooltipLabel' import InfiniteScrollSelect from '@/components/widgets/InfiniteScrollSelect.vue' @@@ -286,49 -363,15 +363,15 @@@ export default } params.domainId = this.domainId this.loading = true - getAPI('getUploadParamsForVolume', params).then(json => { - api('getUploadParamsForVolume', params).then(async json => { ++ getAPI('getUploadParamsForVolume', params).then(async json => { this.uploadParams = json.postuploadvolumeresponse?.getuploadparams || '' - const { fileList } = this - if (this.fileList.length > 1) { - this.$notification.error({ - message: this.$t('message.upload.volume.failed'), - description: this.$t('message.upload.file.limit'), - duration: 0 - }) + this.ssvmOrigin = new URL(this.uploadParams.postURL).origin + const trusted = await probeSsvmCert(this.ssvmOrigin) + if (!trusted) { + this.ssvmCertUntrusted = true + return } - const formData = new FormData() - fileList.forEach(file => { - formData.append('files[]', file) - }) - this.uploadPercentage = 0 - axios.post(this.uploadParams.postURL, - formData, - { - headers: { - 'content-type': 'multipart/form-data', - 'x-signature': this.uploadParams.signature, - 'x-expires': this.uploadParams.expires, - 'x-metadata': this.uploadParams.metadata - }, - onUploadProgress: (progressEvent) => { - this.uploadPercentage = Number(parseFloat(100 * progressEvent.loaded / progressEvent.total).toFixed(1)) - }, - timeout: 86400000 - }).then((json) => { - this.$notification.success({ - message: this.$t('message.success.upload'), - description: this.$t('message.success.upload.volume.description') - }) - this.closeAction() - }).catch(e => { - this.$notification.error({ - message: this.$t('message.upload.failed'), - description: `${this.$t('message.upload.volume.failed')} - ${e}`, - duration: 0 - }) - }).finally(() => { - this.loading = false - }) + this.handleUpload() }).catch(e => { this.$notification.error({ message: this.$t('message.upload.failed'),
