diff --git a/api/src/main/java/com/cloud/network/NetworkModel.java b/api/src/main/java/com/cloud/network/NetworkModel.java index d7de9df5325..a4cd87af008 100644 --- a/api/src/main/java/com/cloud/network/NetworkModel.java +++ b/api/src/main/java/com/cloud/network/NetworkModel.java @@ -149,7 +149,7 @@ public interface NetworkModel { boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services); - Network getNetworkWithSGWithFreeIPs(Long zoneId); + Network getNetworkWithSGWithFreeIPs(Account account, Long zoneId); Network getNetworkWithSecurityGroupEnabled(Long zoneId); @@ -360,6 +360,6 @@ public interface NetworkModel { boolean isSecurityGroupSupportedForZone(Long zoneId); - boolean checkSecurityGroupSupportForNetwork(DataCenter zone, List networkIds, + boolean checkSecurityGroupSupportForNetwork(Account account, DataCenter zone, List networkIds, List securityGroupsIds); } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ChangeSharedFSServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ChangeSharedFSServiceOfferingCmd.java index 58269a5bd33..70fb543d64c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ChangeSharedFSServiceOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ChangeSharedFSServiceOfferingCmd.java @@ -70,7 +70,7 @@ public class ChangeSharedFSServiceOfferingCmd extends BaseAsyncCmd implements Us type = CommandType.UUID, entityType = ServiceOfferingResponse.class, required = true, - description = "the offering to use for the shared filesystem vm") + description = "the offering to use for the shared filesystem instance") private Long serviceOfferingId; ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/CreateSharedFSCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/CreateSharedFSCmd.java index 1be55fdab1c..ddaa31612a8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/CreateSharedFSCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/CreateSharedFSCmd.java @@ -130,7 +130,7 @@ public class CreateSharedFSCmd extends BaseAsyncCreateCmd implements UserCmd { type = CommandType.UUID, required = true, entityType = ServiceOfferingResponse.class, - description = "the service offering to use for the shared filesystem VM hosting the data. The offering should be HA enabled and the cpu count and memory size should be greater than equal to sharedfsvm.min.cpu.count and sharedfsvm.min.ram.size respectively") + description = "the service offering to use for the shared filesystem instance hosting the data. The offering should be HA enabled and the cpu count and memory size should be greater than equal to sharedfsvm.min.cpu.count and sharedfsvm.min.ram.size respectively") private Long serviceOfferingId; @Parameter(name = ApiConstants.FILESYSTEM, diff --git a/api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java index 26dc4bcffd2..3861ac455ed 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java @@ -129,11 +129,11 @@ public class CapabilitiesResponse extends BaseResponse { private Integer instancesDisksStatsRetentionTime; @SerializedName(ApiConstants.SHAREDFSVM_MIN_CPU_COUNT) - @Param(description = "the min CPU count for the service offering used by the shared filesystem VM", since = "4.20.0") + @Param(description = "the min CPU count for the service offering used by the shared filesystem instance", since = "4.20.0") private Integer sharedFsVmMinCpuCount; @SerializedName(ApiConstants.SHAREDFSVM_MIN_RAM_SIZE) - @Param(description = "the min Ram size for the service offering used by the shared filesystem VM", since = "4.20.0") + @Param(description = "the min Ram size for the service offering used by the shared filesystem instance", since = "4.20.0") private Integer sharedFsVmMinRamSize; public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) { diff --git a/api/src/main/java/org/apache/cloudstack/storage/sharedfs/SharedFS.java b/api/src/main/java/org/apache/cloudstack/storage/sharedfs/SharedFS.java index 12ce5eb387b..bcba425abbf 100644 --- a/api/src/main/java/org/apache/cloudstack/storage/sharedfs/SharedFS.java +++ b/api/src/main/java/org/apache/cloudstack/storage/sharedfs/SharedFS.java @@ -64,7 +64,7 @@ public interface SharedFS extends ControlledEntity, Identity, InternalIdentity, null, SharedFSFeatureEnabled.key()); - String SharedFSVmNamePrefix = "fsvm"; + String SharedFSVmNamePrefix = "sharedfs"; String SharedFSPath = "/export"; enum FileSystemType { diff --git a/client/pom.xml b/client/pom.xml index 8266e8e68a5..e99b8c71406 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -27,18 +27,7 @@ cloudstack 4.20.0.0-SNAPSHOT - - - juniper-tungsten-api - https://github.com/radu-todirica/tungsten-api/raw/master - - - - net.juniper.tungsten - juniper-tungsten-api - 2.0 - javax.servlet javax.servlet-api @@ -282,11 +271,6 @@ cloud-plugin-network-ovs ${project.version} - - org.apache.cloudstack - cloud-plugin-network-tungsten - ${project.version} - org.apache.cloudstack cloud-plugin-network-elb @@ -1118,6 +1102,11 @@ cloud-plugin-network-nsx ${project.version} + + org.apache.cloudstack + cloud-plugin-network-tungsten + ${project.version} + org.apache.cloudstack cloud-plugin-api-vmware-sioc diff --git a/core/src/main/java/com/cloud/network/HAProxyConfigurator.java b/core/src/main/java/com/cloud/network/HAProxyConfigurator.java index 9d07fc95c2f..e4b0a7ffff4 100644 --- a/core/src/main/java/com/cloud/network/HAProxyConfigurator.java +++ b/core/src/main/java/com/cloud/network/HAProxyConfigurator.java @@ -485,7 +485,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { sb.append("\tbind ").append(publicIP).append(":").append(publicPort); result.add(sb.toString()); sb = new StringBuilder(); - sb.append("\t").append("balance ").append(algorithm); + sb.append("\t").append("balance ").append(algorithm.toLowerCase()); result.add(sb.toString()); int i = 0; diff --git a/debian/control b/debian/control index 8a098e97165..ed4f95d8e49 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: libs Priority: extra Maintainer: Wido den Hollander Build-Depends: debhelper (>= 9), openjdk-17-jdk | java17-sdk | java17-jdk | zulu-17 | openjdk-11-jdk | java11-sdk | java11-jdk | zulu-11, genisoimage, - python-mysql.connector | python3-mysql.connector, maven (>= 3) | maven3, + python-mysql.connector | python3-mysql.connector | mysql-connector-python-py3, maven (>= 3) | maven3, python (>= 2.7) | python2 (>= 2.7), python3 (>= 3), python-setuptools, python3-setuptools, nodejs (>= 12), lsb-release, dh-systemd | debhelper (>= 13) Standards-Version: 3.8.1 @@ -17,7 +17,7 @@ Description: A common package which contains files which are shared by several C Package: cloudstack-management Architecture: all -Depends: ${python3:Depends}, openjdk-17-jre-headless | java17-runtime-headless | java17-runtime | zulu-17, cloudstack-common (= ${source:Version}), net-tools, sudo, python3-mysql.connector, augeas-tools, mysql-client | mariadb-client, adduser, bzip2, ipmitool, file, gawk, iproute2, qemu-utils, rng-tools, python3-dnspython, lsb-release, init-system-helpers (>= 1.14~), python3-setuptools +Depends: ${python3:Depends}, openjdk-17-jre-headless | java17-runtime-headless | java17-runtime | zulu-17, cloudstack-common (= ${source:Version}), net-tools, sudo, python3-mysql.connector | mysql-connector-python-py3, augeas-tools, mysql-client | mariadb-client, adduser, bzip2, ipmitool, file, gawk, iproute2, qemu-utils, rng-tools, python3-dnspython, lsb-release, init-system-helpers (>= 1.14~), python3-setuptools Conflicts: cloud-server, cloud-client, cloud-client-ui Description: CloudStack server library The CloudStack management server diff --git a/engine/schema/src/main/java/com/cloud/upgrade/SystemVmTemplateRegistration.java b/engine/schema/src/main/java/com/cloud/upgrade/SystemVmTemplateRegistration.java index 9575cfaf863..7314937ff5b 100644 --- a/engine/schema/src/main/java/com/cloud/upgrade/SystemVmTemplateRegistration.java +++ b/engine/schema/src/main/java/com/cloud/upgrade/SystemVmTemplateRegistration.java @@ -49,8 +49,11 @@ import com.cloud.vm.dao.VMInstanceDaoImpl; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.config.dao.ConfigurationDaoImpl; +import org.apache.cloudstack.framework.config.impl.ConfigurationVO; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; @@ -117,6 +120,8 @@ public class SystemVmTemplateRegistration { @Inject ImageStoreDao imageStoreDao; @Inject + ImageStoreDetailsDao imageStoreDetailsDao; + @Inject ClusterDao clusterDao; @Inject ConfigurationDao configurationDao; @@ -130,6 +135,7 @@ public class SystemVmTemplateRegistration { templateDataStoreDao = new BasicTemplateDataStoreDaoImpl(); vmInstanceDao = new VMInstanceDaoImpl(); imageStoreDao = new ImageStoreDaoImpl(); + imageStoreDetailsDao = new ImageStoreDetailsDaoImpl(); clusterDao = new ClusterDaoImpl(); configurationDao = new ConfigurationDaoImpl(); } @@ -142,6 +148,14 @@ public class SystemVmTemplateRegistration { this.systemVmTemplateVersion = systemVmTemplateVersion; } + public static String getMountCommand(String nfsVersion, String device, String dir) { + String cmd = "sudo mount -t nfs"; + if (StringUtils.isNotBlank(nfsVersion)) { + cmd = String.format("%s -o vers=%s", cmd, nfsVersion); + } + return String.format("%s %s %s", cmd, device, dir); + } + public String getSystemVmTemplateVersion() { if (StringUtils.isEmpty(systemVmTemplateVersion)) { return String.format("%s.%s", CS_MAJOR_VERSION, CS_TINY_VERSION); @@ -320,14 +334,14 @@ public class SystemVmTemplateRegistration { } }; - public static boolean validateIfSeeded(String url, String path) { + public static boolean validateIfSeeded(String url, String path, String nfsVersion) { String filePath = null; try { filePath = Files.createTempDirectory(TEMPORARY_SECONDARY_STORE).toString(); if (filePath == null) { throw new CloudRuntimeException("Failed to create temporary directory to mount secondary store"); } - mountStore(url, filePath); + mountStore(url, filePath, nfsVersion); int lastIdx = path.lastIndexOf(File.separator); String partialDirPath = path.substring(0, lastIdx); String templatePath = filePath + File.separator + partialDirPath; @@ -427,14 +441,13 @@ public class SystemVmTemplateRegistration { return new Pair<>(url, storeId); } - public static void mountStore(String storeUrl, String path) { + public static void mountStore(String storeUrl, String path, String nfsVersion) { try { if (storeUrl != null) { URI uri = new URI(UriUtils.encodeURIComponent(storeUrl)); String host = uri.getHost(); String mountPath = uri.getPath(); - String mount = String.format(MOUNT_COMMAND, host + ":" + mountPath, path); - Script.runSimpleBashScript(mount); + Script.runSimpleBashScript(getMountCommand(nfsVersion, host + ":" + mountPath, path)); } } catch (Exception e) { String msg = "NFS Store URL is not in the correct format"; @@ -773,7 +786,8 @@ public class SystemVmTemplateRegistration { throw new CloudRuntimeException("Failed to create temporary file path to mount the store"); } Pair storeUrlAndId = getNfsStoreInZone(zoneId); - mountStore(storeUrlAndId.first(), filePath); + String nfsVersion = getNfsVersion(storeUrlAndId.second()); + mountStore(storeUrlAndId.first(), filePath, nfsVersion); List hypervisorList = fetchAllHypervisors(zoneId); for (String hypervisor : hypervisorList) { Hypervisor.HypervisorType name = Hypervisor.HypervisorType.getType(hypervisor); @@ -784,7 +798,7 @@ public class SystemVmTemplateRegistration { VMTemplateVO templateVO = vmTemplateDao.findById(templateId); TemplateDataStoreVO templateDataStoreVO = templateDataStoreDao.findByTemplate(templateId, DataStoreRole.Image); String installPath = templateDataStoreVO.getInstallPath(); - if (validateIfSeeded(storeUrlAndId.first(), installPath)) { + if (validateIfSeeded(storeUrlAndId.first(), installPath, nfsVersion)) { continue; } else if (templateVO != null) { registerTemplate(hypervisorAndTemplateName, storeUrlAndId, templateVO, templateDataStoreVO, filePath); @@ -889,4 +903,17 @@ public class SystemVmTemplateRegistration { } }); } + + public String getNfsVersion(long storeId) { + final String configKey = "secstorage.nfs.version"; + final Map storeDetails = imageStoreDetailsDao.getDetails(storeId); + if (storeDetails != null && storeDetails.containsKey(configKey)) { + return storeDetails.get(configKey); + } + ConfigurationVO globalNfsVersion = configurationDao.findByName(configKey); + if (globalNfsVersion != null) { + return globalNfsVersion.getValue(); + } + return null; + } } diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41910to42000.sql b/engine/schema/src/main/resources/META-INF/db/schema-41910to42000.sql index 8f0076ad46b..c36b71c2f25 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41910to42000.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41910to42000.sql @@ -193,8 +193,8 @@ CREATE TABLE `cloud`.`ip4_guest_subnet_network_map` ( CONSTRAINT `uc_ip4_guest_subnet_network_map__uuid` UNIQUE (`uuid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -ALTER TABLE `cloud`.`network_offerings` RENAME COLUMN `nsx_mode` TO `network_mode`; -ALTER TABLE `cloud`.`vpc_offerings` RENAME COLUMN `nsx_mode` TO `network_mode`; +CALL `cloud`.`IDEMPOTENT_CHANGE_COLUMN`('network_offerings', 'nsx_mode', 'network_mode', 'varchar(32) COMMENT "mode in which the network would route traffic"'); +CALL `cloud`.`IDEMPOTENT_CHANGE_COLUMN`('vpc_offerings', 'nsx_mode', 'network_mode', 'varchar(32) COMMENT "mode in which the network would route traffic"'); ALTER TABLE `cloud`.`event` MODIFY COLUMN `type` varchar(50) NOT NULL; -- Add tables for AS Numbers and range @@ -307,204 +307,6 @@ CREATE TABLE `cloud`.`shared_filesystem`( INDEX `i_shared_filesystem__domain_id`(`domain_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -DROP VIEW IF EXISTS `cloud`.`user_vm_view`; -CREATE VIEW `user_vm_view` AS -SELECT - `vm_instance`.`id` AS `id`, - `vm_instance`.`name` AS `name`, - `user_vm`.`display_name` AS `display_name`, - `user_vm`.`user_data` AS `user_data`, - `user_vm`.`user_vm_type` AS `user_vm_type`, - `account`.`id` AS `account_id`, - `account`.`uuid` AS `account_uuid`, - `account`.`account_name` AS `account_name`, - `account`.`type` AS `account_type`, - `domain`.`id` AS `domain_id`, - `domain`.`uuid` AS `domain_uuid`, - `domain`.`name` AS `domain_name`, - `domain`.`path` AS `domain_path`, - `projects`.`id` AS `project_id`, - `projects`.`uuid` AS `project_uuid`, - `projects`.`name` AS `project_name`, - `instance_group`.`id` AS `instance_group_id`, - `instance_group`.`uuid` AS `instance_group_uuid`, - `instance_group`.`name` AS `instance_group_name`, - `vm_instance`.`uuid` AS `uuid`, - `vm_instance`.`user_id` AS `user_id`, - `vm_instance`.`last_host_id` AS `last_host_id`, - `vm_instance`.`vm_type` AS `type`, - `vm_instance`.`limit_cpu_use` AS `limit_cpu_use`, - `vm_instance`.`created` AS `created`, - `vm_instance`.`state` AS `state`, - `vm_instance`.`update_time` AS `update_time`, - `vm_instance`.`removed` AS `removed`, - `vm_instance`.`ha_enabled` AS `ha_enabled`, - `vm_instance`.`hypervisor_type` AS `hypervisor_type`, - `vm_instance`.`instance_name` AS `instance_name`, - `vm_instance`.`guest_os_id` AS `guest_os_id`, - `vm_instance`.`display_vm` AS `display_vm`, - `guest_os`.`uuid` AS `guest_os_uuid`, - `vm_instance`.`pod_id` AS `pod_id`, - `host_pod_ref`.`uuid` AS `pod_uuid`, - `vm_instance`.`private_ip_address` AS `private_ip_address`, - `vm_instance`.`private_mac_address` AS `private_mac_address`, - `vm_instance`.`vm_type` AS `vm_type`, - `data_center`.`id` AS `data_center_id`, - `data_center`.`uuid` AS `data_center_uuid`, - `data_center`.`name` AS `data_center_name`, - `data_center`.`is_security_group_enabled` AS `security_group_enabled`, - `data_center`.`networktype` AS `data_center_network_type`, - `host`.`id` AS `host_id`, - `host`.`uuid` AS `host_uuid`, - `host`.`name` AS `host_name`, - `host`.`cluster_id` AS `cluster_id`, - `host`.`status` AS `host_status`, - `host`.`resource_state` AS `host_resource_state`, - `vm_template`.`id` AS `template_id`, - `vm_template`.`uuid` AS `template_uuid`, - `vm_template`.`name` AS `template_name`, - `vm_template`.`type` AS `template_type`, - `vm_template`.`format` AS `template_format`, - `vm_template`.`display_text` AS `template_display_text`, - `vm_template`.`enable_password` AS `password_enabled`, - `iso`.`id` AS `iso_id`, - `iso`.`uuid` AS `iso_uuid`, - `iso`.`name` AS `iso_name`, - `iso`.`display_text` AS `iso_display_text`, - `service_offering`.`id` AS `service_offering_id`, - `service_offering`.`uuid` AS `service_offering_uuid`, - `disk_offering`.`uuid` AS `disk_offering_uuid`, - `disk_offering`.`id` AS `disk_offering_id`, - (CASE - WHEN ISNULL(`service_offering`.`cpu`) THEN `custom_cpu`.`value` - ELSE `service_offering`.`cpu` - END) AS `cpu`, - (CASE - WHEN ISNULL(`service_offering`.`speed`) THEN `custom_speed`.`value` - ELSE `service_offering`.`speed` - END) AS `speed`, - (CASE - WHEN ISNULL(`service_offering`.`ram_size`) THEN `custom_ram_size`.`value` - ELSE `service_offering`.`ram_size` - END) AS `ram_size`, - `backup_offering`.`uuid` AS `backup_offering_uuid`, - `backup_offering`.`id` AS `backup_offering_id`, - `service_offering`.`name` AS `service_offering_name`, - `disk_offering`.`name` AS `disk_offering_name`, - `backup_offering`.`name` AS `backup_offering_name`, - `storage_pool`.`id` AS `pool_id`, - `storage_pool`.`uuid` AS `pool_uuid`, - `storage_pool`.`pool_type` AS `pool_type`, - `volumes`.`id` AS `volume_id`, - `volumes`.`uuid` AS `volume_uuid`, - `volumes`.`device_id` AS `volume_device_id`, - `volumes`.`volume_type` AS `volume_type`, - `security_group`.`id` AS `security_group_id`, - `security_group`.`uuid` AS `security_group_uuid`, - `security_group`.`name` AS `security_group_name`, - `security_group`.`description` AS `security_group_description`, - `nics`.`id` AS `nic_id`, - `nics`.`uuid` AS `nic_uuid`, - `nics`.`device_id` AS `nic_device_id`, - `nics`.`network_id` AS `network_id`, - `nics`.`ip4_address` AS `ip_address`, - `nics`.`ip6_address` AS `ip6_address`, - `nics`.`ip6_gateway` AS `ip6_gateway`, - `nics`.`ip6_cidr` AS `ip6_cidr`, - `nics`.`default_nic` AS `is_default_nic`, - `nics`.`gateway` AS `gateway`, - `nics`.`netmask` AS `netmask`, - `nics`.`mac_address` AS `mac_address`, - `nics`.`broadcast_uri` AS `broadcast_uri`, - `nics`.`isolation_uri` AS `isolation_uri`, - `vpc`.`id` AS `vpc_id`, - `vpc`.`uuid` AS `vpc_uuid`, - `networks`.`uuid` AS `network_uuid`, - `networks`.`name` AS `network_name`, - `networks`.`traffic_type` AS `traffic_type`, - `networks`.`guest_type` AS `guest_type`, - `user_ip_address`.`id` AS `public_ip_id`, - `user_ip_address`.`uuid` AS `public_ip_uuid`, - `user_ip_address`.`public_ip_address` AS `public_ip_address`, - `ssh_details`.`value` AS `keypair_names`, - `resource_tags`.`id` AS `tag_id`, - `resource_tags`.`uuid` AS `tag_uuid`, - `resource_tags`.`key` AS `tag_key`, - `resource_tags`.`value` AS `tag_value`, - `resource_tags`.`domain_id` AS `tag_domain_id`, - `domain`.`uuid` AS `tag_domain_uuid`, - `domain`.`name` AS `tag_domain_name`, - `resource_tags`.`account_id` AS `tag_account_id`, - `account`.`account_name` AS `tag_account_name`, - `resource_tags`.`resource_id` AS `tag_resource_id`, - `resource_tags`.`resource_uuid` AS `tag_resource_uuid`, - `resource_tags`.`resource_type` AS `tag_resource_type`, - `resource_tags`.`customer` AS `tag_customer`, - `async_job`.`id` AS `job_id`, - `async_job`.`uuid` AS `job_uuid`, - `async_job`.`job_status` AS `job_status`, - `async_job`.`account_id` AS `job_account_id`, - `affinity_group`.`id` AS `affinity_group_id`, - `affinity_group`.`uuid` AS `affinity_group_uuid`, - `affinity_group`.`name` AS `affinity_group_name`, - `affinity_group`.`description` AS `affinity_group_description`, - `autoscale_vmgroups`.`id` AS `autoscale_vmgroup_id`, - `autoscale_vmgroups`.`uuid` AS `autoscale_vmgroup_uuid`, - `autoscale_vmgroups`.`name` AS `autoscale_vmgroup_name`, - `vm_instance`.`dynamically_scalable` AS `dynamically_scalable`, - `user_data`.`id` AS `user_data_id`, - `user_data`.`uuid` AS `user_data_uuid`, - `user_data`.`name` AS `user_data_name`, - `user_vm`.`user_data_details` AS `user_data_details`, - `vm_template`.`user_data_link_policy` AS `user_data_policy` -FROM - (((((((((((((((((((((((((((((((((((`user_vm` - JOIN `vm_instance` ON (((`vm_instance`.`id` = `user_vm`.`id`) - AND ISNULL(`vm_instance`.`removed`)))) - JOIN `account` ON ((`vm_instance`.`account_id` = `account`.`id`))) - JOIN `domain` ON ((`vm_instance`.`domain_id` = `domain`.`id`))) - LEFT JOIN `guest_os` ON ((`vm_instance`.`guest_os_id` = `guest_os`.`id`))) - LEFT JOIN `host_pod_ref` ON ((`vm_instance`.`pod_id` = `host_pod_ref`.`id`))) - LEFT JOIN `projects` ON ((`projects`.`project_account_id` = `account`.`id`))) - LEFT JOIN `instance_group_vm_map` ON ((`vm_instance`.`id` = `instance_group_vm_map`.`instance_id`))) - LEFT JOIN `instance_group` ON ((`instance_group_vm_map`.`group_id` = `instance_group`.`id`))) - LEFT JOIN `data_center` ON ((`vm_instance`.`data_center_id` = `data_center`.`id`))) - LEFT JOIN `host` ON ((`vm_instance`.`host_id` = `host`.`id`))) - LEFT JOIN `vm_template` ON ((`vm_instance`.`vm_template_id` = `vm_template`.`id`))) - LEFT JOIN `vm_template` `iso` ON ((`iso`.`id` = `user_vm`.`iso_id`))) - LEFT JOIN `volumes` ON ((`vm_instance`.`id` = `volumes`.`instance_id`))) - LEFT JOIN `service_offering` ON ((`vm_instance`.`service_offering_id` = `service_offering`.`id`))) - LEFT JOIN `disk_offering` `svc_disk_offering` ON ((`volumes`.`disk_offering_id` = `svc_disk_offering`.`id`))) - LEFT JOIN `disk_offering` ON ((`volumes`.`disk_offering_id` = `disk_offering`.`id`))) - LEFT JOIN `backup_offering` ON ((`vm_instance`.`backup_offering_id` = `backup_offering`.`id`))) - LEFT JOIN `storage_pool` ON ((`volumes`.`pool_id` = `storage_pool`.`id`))) - LEFT JOIN `security_group_vm_map` ON ((`vm_instance`.`id` = `security_group_vm_map`.`instance_id`))) - LEFT JOIN `security_group` ON ((`security_group_vm_map`.`security_group_id` = `security_group`.`id`))) - LEFT JOIN `user_data` ON ((`user_data`.`id` = `user_vm`.`user_data_id`))) - LEFT JOIN `nics` ON (((`vm_instance`.`id` = `nics`.`instance_id`) - AND ISNULL(`nics`.`removed`)))) - LEFT JOIN `networks` ON ((`nics`.`network_id` = `networks`.`id`))) - LEFT JOIN `vpc` ON (((`networks`.`vpc_id` = `vpc`.`id`) - AND ISNULL(`vpc`.`removed`)))) - LEFT JOIN `user_ip_address` FORCE INDEX(`fk_user_ip_address__vm_id`) ON ((`user_ip_address`.`vm_id` = `vm_instance`.`id`))) - LEFT JOIN `user_vm_details` `ssh_details` ON (((`ssh_details`.`vm_id` = `vm_instance`.`id`) - AND (`ssh_details`.`name` = 'SSH.KeyPairNames')))) - LEFT JOIN `resource_tags` ON (((`resource_tags`.`resource_id` = `vm_instance`.`id`) - AND (`resource_tags`.`resource_type` = 'UserVm')))) - LEFT JOIN `async_job` ON (((`async_job`.`instance_id` = `vm_instance`.`id`) - AND (`async_job`.`instance_type` = 'VirtualMachine') - AND (`async_job`.`job_status` = 0)))) - LEFT JOIN `affinity_group_vm_map` ON ((`vm_instance`.`id` = `affinity_group_vm_map`.`instance_id`))) - LEFT JOIN `affinity_group` ON ((`affinity_group_vm_map`.`affinity_group_id` = `affinity_group`.`id`))) - LEFT JOIN `autoscale_vmgroup_vm_map` ON ((`autoscale_vmgroup_vm_map`.`instance_id` = `vm_instance`.`id`))) - LEFT JOIN `autoscale_vmgroups` ON ((`autoscale_vmgroup_vm_map`.`vmgroup_id` = `autoscale_vmgroups`.`id`))) - LEFT JOIN `user_vm_details` `custom_cpu` ON (((`custom_cpu`.`vm_id` = `vm_instance`.`id`) - AND (`custom_cpu`.`name` = 'CpuNumber')))) - LEFT JOIN `user_vm_details` `custom_speed` ON (((`custom_speed`.`vm_id` = `vm_instance`.`id`) - AND (`custom_speed`.`name` = 'CpuSpeed')))) - LEFT JOIN `user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `vm_instance`.`id`) - AND (`custom_ram_size`.`name` = 'memory')))); - -- Quota inject tariff result into subsequent ones CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.quota_tariff', 'position', 'bigint(20) NOT NULL DEFAULT 1 COMMENT "Position in the execution sequence for tariffs of the same type"'); diff --git a/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java index 050c2a7a1aa..32fdf782696 100644 --- a/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java +++ b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java @@ -294,7 +294,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C } } } catch (final Throwable e) { - logger.error("Unexcpeted exception: ", e); + logger.error("Unexpected exception: ", e); } } } @@ -346,7 +346,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C } }); } catch (final Throwable e) { - logger.error("Unexcpeted exception: ", e); + logger.error("Unexpected exception: ", e); } } } @@ -384,7 +384,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C } executeAsync(peerName, agentId, cmds, true); } catch (final Exception e) { - logger.warn("Caught exception while talkign to " + peer.getMsid()); + logger.warn("Caught exception while talking to " + peer.getMsid()); } } } diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycle.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycle.java index 15c1ccac5d9..b913033259c 100644 --- a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycle.java +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycle.java @@ -69,7 +69,12 @@ public class CloudStackExtendedLifeCycle extends AbstractBeanCollector { with(new WithComponentLifeCycle() { @Override public void with(ComponentLifecycle lifecycle) { - lifecycle.start(); + logger.info("starting bean {}.", lifecycle.getName()); + try { + lifecycle.start(); + } catch (Exception e) { + logger.error("Error on starting bean {} - {}", lifecycle.getName(), e.getMessage(), e); + } if (lifecycle instanceof ManagementBean) { ManagementBean mbean = (ManagementBean)lifecycle; @@ -93,13 +98,21 @@ public class CloudStackExtendedLifeCycle extends AbstractBeanCollector { } public void stopBeans() { + logger.info("Stopping CloudStack Components"); + with(new WithComponentLifeCycle() { @Override public void with(ComponentLifecycle lifecycle) { - logger.info("stopping bean " + lifecycle.getName()); - lifecycle.stop(); + logger.info("stopping bean {}.", lifecycle.getName()); + try { + lifecycle.stop(); + } catch (Exception e) { + logger.error("Error on stopping bean {} - {}", lifecycle.getName(), e.getMessage(), e); + } } }); + + logger.info("Done Stopping CloudStack Components"); } private void configure() { @@ -109,10 +122,13 @@ public class CloudStackExtendedLifeCycle extends AbstractBeanCollector { @Override public void with(ComponentLifecycle lifecycle) { try { + logger.info("configuring bean {}.", lifecycle.getName()); lifecycle.configure(lifecycle.getName(), lifecycle.getConfigParams()); } catch (ConfigurationException e) { logger.error("Failed to configure " + lifecycle.getName(), e); throw new CloudRuntimeException(e); + } catch (Exception e) { + logger.error("Error on configuring bean {} - {}", lifecycle.getName(), e.getMessage(), e); } } }); diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycleStart.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycleStart.java index 0dc72f93195..85d25ffd9a4 100644 --- a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycleStart.java +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycleStart.java @@ -45,5 +45,4 @@ public class CloudStackExtendedLifeCycleStart extends AbstractSmartLifeCycle imp public void run() { lifeCycle.startBeans(); } - } diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/CloudStackSpringContext.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/CloudStackSpringContext.java index 8bbbc35f7e5..361a66fe1ba 100644 --- a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/CloudStackSpringContext.java +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/CloudStackSpringContext.java @@ -77,8 +77,10 @@ public class CloudStackSpringContext { for (String appName : contextMap.keySet()) { ApplicationContext contex = contextMap.get(appName); if (contex instanceof ConfigurableApplicationContext) { - logger.trace("registering shutdown hook for bean "+ appName); + logger.trace("Registering shutdown hook for bean {}.", appName); ((ConfigurableApplicationContext)contex).registerShutdownHook(); + } else { + logger.warn("Shutdown hook not registered for bean {}.", appName); } } } diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml index eec93d33da5..f1eb4ea8c4f 100644 --- a/plugins/hypervisors/kvm/pom.xml +++ b/plugins/hypervisors/kvm/pom.xml @@ -83,11 +83,6 @@ ${project.version} compile - - org.apache.cloudstack - cloud-plugin-network-tungsten - ${project.version} - diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index e51f8fc8152..04662604382 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -2511,7 +2511,9 @@ public class KVMStorageProcessor implements StorageProcessor { destPool = storagePoolMgr.getStoragePool(destPrimaryStore.getPoolType(), destPrimaryStore.getUuid()); try { - if (srcVol.getPassphrase() != null && srcVol.getVolumeType().equals(Volume.Type.ROOT)) { + Volume.Type volumeType = srcVol.getVolumeType(); + + if (srcVol.getPassphrase() != null && (Volume.Type.ROOT.equals(volumeType) || Volume.Type.DATADISK.equals(volumeType))) { volume.setQemuEncryptFormat(QemuObject.EncryptFormat.LUKS); storagePoolMgr.copyPhysicalDisk(volume, destVolumeName, destPool, cmd.getWaitInMillSeconds(), srcVol.getPassphrase(), destVol.getPassphrase(), srcVol.getProvisioningType()); } else { diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTfRouteCommand.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTfRouteCommand.java new file mode 100644 index 00000000000..8ccbff96d79 --- /dev/null +++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTfRouteCommand.java @@ -0,0 +1,64 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.network.tungsten.agent.api; + +import com.cloud.agent.api.Command; + +import java.util.Objects; + +public class SetupTfRouteCommand extends Command { + private final String privateIp; + private final String publicIp; + private final String srcNetwork; + + public SetupTfRouteCommand(final String privateIp, final String publicIp, final String srcNetwork) { + this.privateIp = privateIp; + this.publicIp = publicIp; + this.srcNetwork = srcNetwork; + } + + public String getPrivateIp() { + return privateIp; + } + + public String getPublicIp() { + return publicIp; + } + + public String getSrcNetwork() { + return srcNetwork; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + SetupTfRouteCommand that = (SetupTfRouteCommand) o; + return Objects.equals(privateIp, that.privateIp) && Objects.equals(publicIp, that.publicIp) && Objects.equals(srcNetwork, that.srcNetwork); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), privateIp, publicIp, srcNetwork); + } + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTungstenVRouterCommand.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTungstenVRouterCommand.java new file mode 100644 index 00000000000..00fc522363d --- /dev/null +++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTungstenVRouterCommand.java @@ -0,0 +1,77 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.network.tungsten.agent.api; + +import com.cloud.agent.api.Command; + +import java.util.Objects; + +public class SetupTungstenVRouterCommand extends Command { + private final String oper; + private final String inf; + private final String subnet; + private final String route; + private final String vrf; + + public SetupTungstenVRouterCommand(final String oper, final String inf, final String subnet, final String route, + final String vrf) { + this.oper = oper; + this.inf = inf; + this.subnet = subnet; + this.route = route; + this.vrf = vrf; + } + + public String getOper() { + return oper; + } + + public String getInf() { + return inf; + } + + public String getSubnet() { + return subnet; + } + + public String getRoute() { + return route; + } + + public String getVrf() { + return vrf; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + SetupTungstenVRouterCommand that = (SetupTungstenVRouterCommand) o; + return Objects.equals(oper, that.oper) && Objects.equals(inf, that.inf) && Objects.equals(subnet, that.subnet) && Objects.equals(route, that.route) && Objects.equals(vrf, that.vrf); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), oper, inf, subnet, route, vrf); + } + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerSslCommand.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerSslCommand.java new file mode 100644 index 00000000000..5ab24c18aa0 --- /dev/null +++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerSslCommand.java @@ -0,0 +1,83 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.network.tungsten.agent.api; + +import com.cloud.agent.api.Command; + +import java.util.Objects; + +public class UpdateTungstenLoadbalancerSslCommand extends Command { + private final String lbUuid; + private final String sslCertName; + private final String certificateKey; + private final String privateKey; + private final String privateIp; + private final String port; + + public UpdateTungstenLoadbalancerSslCommand(final String lbUuid, final String sslCertName, + final String certificateKey, final String privateKey, final String privateIp, final String port) { + this.lbUuid = lbUuid; + this.sslCertName = sslCertName; + this.certificateKey = certificateKey; + this.privateKey = privateKey; + this.privateIp = privateIp; + this.port = port; + } + + public String getLbUuid() { + return lbUuid; + } + + public String getSslCertName() { + return sslCertName; + } + + public String getCertificateKey() { + return certificateKey; + } + + public String getPrivateKey() { + return privateKey; + } + + public String getPrivateIp() { + return privateIp; + } + + public String getPort() { + return port; + } + + @Override + public boolean executeInSequence() { + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + UpdateTungstenLoadbalancerSslCommand that = (UpdateTungstenLoadbalancerSslCommand) o; + return Objects.equals(lbUuid, that.lbUuid) && Objects.equals(sslCertName, that.sslCertName) && Objects.equals(certificateKey, that.certificateKey) && Objects.equals(privateKey, that.privateKey) && Objects.equals(privateIp, that.privateIp) && Objects.equals(port, that.port); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), lbUuid, sslCertName, certificateKey, privateKey, privateIp, port); + } +} diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerStatsCommand.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerStatsCommand.java new file mode 100644 index 00000000000..d7b2088bcd7 --- /dev/null +++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerStatsCommand.java @@ -0,0 +1,71 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.network.tungsten.agent.api; + +import com.cloud.agent.api.Command; + +import java.util.Objects; + +public class UpdateTungstenLoadbalancerStatsCommand extends Command { + private final String lbUuid; + private final String lbStatsPort; + private final String lbStatsUri; + private final String lbStatsAuth; + + public UpdateTungstenLoadbalancerStatsCommand(final String lbUuid, final String lbStatsPort, + final String lbStatsUri, final String lbStatsAuth) { + this.lbUuid = lbUuid; + this.lbStatsPort = lbStatsPort; + this.lbStatsUri = lbStatsUri; + this.lbStatsAuth = lbStatsAuth; + } + + public String getLbUuid() { + return lbUuid; + } + + public String getLbStatsPort() { + return lbStatsPort; + } + + public String getLbStatsUri() { + return lbStatsUri; + } + + public String getLbStatsAuth() { + return lbStatsAuth; + } + + @Override + public boolean executeInSequence() { + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + UpdateTungstenLoadbalancerStatsCommand that = (UpdateTungstenLoadbalancerStatsCommand) o; + return Objects.equals(lbUuid, that.lbUuid) && Objects.equals(lbStatsPort, that.lbStatsPort) && Objects.equals(lbStatsUri, that.lbStatsUri) && Objects.equals(lbStatsAuth, that.lbStatsAuth); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), lbUuid, lbStatsPort, lbStatsUri, lbStatsAuth); + } +} diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 987c7d198d7..512715988bb 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1973,16 +1973,8 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes return; } - String msg; - String rootDiskController = controllerInfo.first(); - String dataDiskController = controllerInfo.second(); - String scsiDiskController; - String recommendedDiskController = null; - - if (VmwareHelper.isControllerOsRecommended(dataDiskController) || VmwareHelper.isControllerOsRecommended(rootDiskController)) { - recommendedDiskController = vmMo.getRecommendedDiskController(null); - } - scsiDiskController = HypervisorHostHelper.getScsiController(new Pair(rootDiskController, dataDiskController), recommendedDiskController); + Pair chosenDiskControllers = VmwareHelper.chooseRequiredDiskControllers(controllerInfo, vmMo, null, null); + String scsiDiskController = HypervisorHostHelper.getScsiController(chosenDiskControllers); if (scsiDiskController == null) { return; } @@ -2335,6 +2327,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes } int controllerKey; + Pair chosenDiskControllers = VmwareHelper.chooseRequiredDiskControllers(controllerInfo,vmMo, null, null); // // Setup ROOT/DATA disk devices @@ -2359,10 +2352,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes } VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context); - String diskController = getDiskController(vmMo, matchingExistingDisk, vol, controllerInfo, deployAsIs); - if (DiskControllerType.getType(diskController) == DiskControllerType.osdefault) { - diskController = vmMo.getRecommendedDiskController(null); - } + String diskController = getDiskController(vmMo, matchingExistingDisk, vol, chosenDiskControllers, deployAsIs); if (DiskControllerType.getType(diskController) == DiskControllerType.ide) { controllerKey = vmMo.getIDEControllerKey(ideUnitNumber); if (vol.getType() == Volume.Type.DATADISK) { @@ -2846,27 +2836,10 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes } private Pair getControllerInfoFromVmSpec(VirtualMachineTO vmSpec) throws CloudRuntimeException { - String dataDiskController = vmSpec.getDetails().get(VmDetailConstants.DATA_DISK_CONTROLLER); - String rootDiskController = vmSpec.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER); - - // If root disk controller is scsi, then data disk controller would also be scsi instead of using 'osdefault' - // This helps avoid mix of different scsi subtype controllers in instance. - if (DiskControllerType.osdefault == DiskControllerType.getType(dataDiskController) && DiskControllerType.lsilogic == DiskControllerType.getType(rootDiskController)) { - dataDiskController = DiskControllerType.scsi.toString(); - } - - // Validate the controller types - dataDiskController = DiskControllerType.getType(dataDiskController).toString(); - rootDiskController = DiskControllerType.getType(rootDiskController).toString(); - - if (DiskControllerType.getType(rootDiskController) == DiskControllerType.none) { - throw new CloudRuntimeException("Invalid root disk controller detected : " + rootDiskController); - } - if (DiskControllerType.getType(dataDiskController) == DiskControllerType.none) { - throw new CloudRuntimeException("Invalid data disk controller detected : " + dataDiskController); - } - - return new Pair<>(rootDiskController, dataDiskController); + String rootDiskControllerDetail = vmSpec.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER); + String dataDiskControllerDetail = vmSpec.getDetails().get(VmDetailConstants.DATA_DISK_CONTROLLER); + VmwareHelper.validateDiskControllerDetails(rootDiskControllerDetail, dataDiskControllerDetail); + return new Pair<>(rootDiskControllerDetail, dataDiskControllerDetail); } private String getBootModeFromVmSpec(VirtualMachineTO vmSpec, boolean deployAsIs) { @@ -3614,15 +3587,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes return controllerType.toString(); } - if (vol.getType() == Volume.Type.ROOT) { - logger.info("Chose disk controller for vol " + vol.getType() + " -> " + controllerInfo.first() - + ", based on root disk controller settings at global configuration setting."); - return controllerInfo.first(); - } else { - logger.info("Chose disk controller for vol " + vol.getType() + " -> " + controllerInfo.second() - + ", based on default data disk controller setting i.e. Operating system recommended."); // Need to bring in global configuration setting & template level setting. - return controllerInfo.second(); - } + return VmwareHelper.getControllerBasedOnDiskType(controllerInfo, vol); } private void postDiskConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO[] sortedDisks, int ideControllerKey, diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java index 7be0dd5862f..1e260b4f99b 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -2101,15 +2101,18 @@ public class VmwareStorageProcessor implements StorageProcessor { AttachAnswer answer = new AttachAnswer(disk); if (isAttach) { - String diskController = getLegacyVmDataDiskController(); - + String rootDiskControllerDetail = DiskControllerType.ide.toString(); + if (controllerInfo != null && StringUtils.isNotEmpty(controllerInfo.get(VmDetailConstants.ROOT_DISK_CONTROLLER))) { + rootDiskControllerDetail = controllerInfo.get(VmDetailConstants.ROOT_DISK_CONTROLLER); + } + String dataDiskControllerDetail = getLegacyVmDataDiskController(); if (controllerInfo != null && StringUtils.isNotEmpty(controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER))) { - diskController = controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER); + dataDiskControllerDetail = controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER); } - if (DiskControllerType.getType(diskController) == DiskControllerType.osdefault) { - diskController = vmMo.getRecommendedDiskController(null); - } + VmwareHelper.validateDiskControllerDetails(rootDiskControllerDetail, dataDiskControllerDetail); + Pair chosenDiskControllers = VmwareHelper.chooseRequiredDiskControllers(new Pair<>(rootDiskControllerDetail, dataDiskControllerDetail), vmMo, null, null); + String diskController = VmwareHelper.getControllerBasedOnDiskType(chosenDiskControllers, disk); vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs, diskController, storagePolicyId, volumeTO.getIopsReadRate() + volumeTO.getIopsWriteRate()); VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder(); diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java index 39e4bbf935f..71be8b1a475 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java @@ -836,9 +836,8 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne if (network == null) { throw new InvalidParameterValueException(String.format("%s parameter must be specified along with %s parameter", ApiConstants.EXTERNAL_LOAD_BALANCER_IP_ADDRESS, ApiConstants.NETWORK_ID)); } - if (isDirectAccess(network)) { - throw new InvalidParameterValueException(String.format("%s parameter must be specified along with %s network or %s network", - ApiConstants.EXTERNAL_LOAD_BALANCER_IP_ADDRESS, Network.GuestType.Shared, NetworkOffering.NetworkMode.ROUTED)); + if (!Network.GuestType.Shared.equals(network.getGuestType()) || routedIpv4Manager.isRoutedNetwork(network)) { + throw new InvalidParameterValueException(String.format("%s parameter must be specified when network type is not %s or is %s network", ApiConstants.EXTERNAL_LOAD_BALANCER_IP_ADDRESS, Network.GuestType.Shared, NetworkOffering.NetworkMode.ROUTED)); } } diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java index ec461610e32..2a001c4aa94 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java @@ -406,7 +406,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu if (StringUtils.isNotBlank(kubernetesCluster.getKeyPair())) { keypairs.add(kubernetesCluster.getKeyPair()); } - if (kubernetesCluster.getSecurityGroupId() != null && networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds, List.of(kubernetesCluster.getSecurityGroupId()))) { + if (kubernetesCluster.getSecurityGroupId() != null && networkModel.checkSecurityGroupSupportForNetwork(owner, zone, networkIds, List.of(kubernetesCluster.getSecurityGroupId()))) { List securityGroupIds = new ArrayList<>(); securityGroupIds.add(kubernetesCluster.getSecurityGroupId()); nodeVm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, securityGroupIds, owner, diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java index c3b81a6ee1f..028ea1c7992 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java @@ -217,7 +217,7 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif keypairs.add(kubernetesCluster.getKeyPair()); } if (kubernetesCluster.getSecurityGroupId() != null && - networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds, + networkModel.checkSecurityGroupSupportForNetwork(owner, zone, networkIds, List.of(kubernetesCluster.getSecurityGroupId()))) { List securityGroupIds = new ArrayList<>(); securityGroupIds.add(kubernetesCluster.getSecurityGroupId()); @@ -294,7 +294,8 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif keypairs.add(kubernetesCluster.getKeyPair()); } if (kubernetesCluster.getSecurityGroupId() != null && - networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds, List.of(kubernetesCluster.getSecurityGroupId()))) { + networkModel.checkSecurityGroupSupportForNetwork(owner, zone, networkIds, + List.of(kubernetesCluster.getSecurityGroupId()))) { List securityGroupIds = new ArrayList<>(); securityGroupIds.add(kubernetesCluster.getSecurityGroupId()); additionalControlVm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, securityGroupIds, owner, diff --git a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml index 429e2eff098..6819723b3f0 100644 --- a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml +++ b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml @@ -66,7 +66,7 @@ write_files: break fi set +e - output=`blkid -o device -t TYPE=iso9660` + output=`blkid -o device -t LABEL=CDROM` set -e if [ "$output" != "" ]; then while read -r line; do diff --git a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml index 4bc2c2c6d3e..90be8957d44 100644 --- a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml +++ b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml @@ -86,7 +86,7 @@ write_files: break fi set +e - output=`blkid -o device -t TYPE=iso9660` + output=`blkid -o device -t LABEL=CDROM` set -e if [ "$output" != "" ]; then while read -r line; do diff --git a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml index ad5bb9d19a6..ac80e8576ff 100644 --- a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml +++ b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml @@ -66,7 +66,7 @@ write_files: break fi set +e - output=`blkid -o device -t TYPE=iso9660` + output=`blkid -o device -t LABEL=CDROM` set -e if [ "$output" != "" ]; then while read -r line; do diff --git a/plugins/integrations/kubernetes-service/src/main/resources/script/upgrade-kubernetes.sh b/plugins/integrations/kubernetes-service/src/main/resources/script/upgrade-kubernetes.sh index c092f53359d..480b002ef17 100755 --- a/plugins/integrations/kubernetes-service/src/main/resources/script/upgrade-kubernetes.sh +++ b/plugins/integrations/kubernetes-service/src/main/resources/script/upgrade-kubernetes.sh @@ -54,7 +54,7 @@ while true; do break fi set +e - output=`blkid -o device -t TYPE=iso9660` + output=`blkid -o device -t LABEL=CDROM` set -e if [ "$output" != "" ]; then while read -r line; do diff --git a/plugins/network-elements/tungsten/pom.xml b/plugins/network-elements/tungsten/pom.xml index 1345268d313..1cd1ae2d823 100644 --- a/plugins/network-elements/tungsten/pom.xml +++ b/plugins/network-elements/tungsten/pom.xml @@ -30,13 +30,6 @@ ../../pom.xml - - - juniper-tungsten-api - https://github.com/radu-todirica/tungsten-api/raw/master - - - net.juniper.tungsten diff --git a/plugins/pom.xml b/plugins/pom.xml index 2adf57d6f30..88172320503 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -114,7 +114,6 @@ network-elements/stratosphere-ssp network-elements/brocade-vcs network-elements/vxlan - network-elements/tungsten outofbandmanagement-drivers/ipmitool outofbandmanagement-drivers/nested-cloudstack @@ -237,6 +236,7 @@ network-elements/cisco-vnmc network-elements/nsx network-elements/juniper-contrail + network-elements/tungsten diff --git a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/manager/ScaleIOSDCManagerImpl.java b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/manager/ScaleIOSDCManagerImpl.java index 92fe1d83761..4d3a78f6875 100644 --- a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/manager/ScaleIOSDCManagerImpl.java +++ b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/manager/ScaleIOSDCManagerImpl.java @@ -24,6 +24,8 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.storage.datastore.client.ScaleIOGatewayClient; import org.apache.cloudstack.storage.datastore.client.ScaleIOGatewayClientConnectionPool; @@ -51,9 +53,18 @@ import com.cloud.utils.db.GlobalLock; import com.cloud.utils.exception.CloudRuntimeException; @Component -public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { +public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager, Configurable { private Logger logger = LogManager.getLogger(getClass()); + static ConfigKey ConnectOnDemand = new ConfigKey<>("Storage", + Boolean.class, + "powerflex.connect.on.demand", + Boolean.FALSE.toString(), + "Connect PowerFlex client on Host when first Volume is mapped to SDC and disconnect when last Volume is unmapped from SDC," + + " otherwise no action (that is connection remains in the same state whichever it is, connected or disconnected).", + Boolean.TRUE, + ConfigKey.Scope.Zone); + @Inject AgentManager agentManager; @Inject @@ -94,6 +105,11 @@ public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { @Override public String prepareSDC(Host host, DataStore dataStore) { + if (Boolean.FALSE.equals(ConnectOnDemand.valueIn(host.getDataCenterId()))) { + logger.debug(String.format("On-demand connect/disconnect config %s disabled in the zone %d, no need to prepare SDC (check for connected SDC)", ConnectOnDemand.key(), host.getDataCenterId())); + return getConnectedSdc(host, dataStore); + } + String systemId = storagePoolDetailsDao.findDetail(dataStore.getId(), ScaleIOGatewayClient.STORAGE_POOL_SYSTEM_ID).getValue(); if (systemId == null) { throw new CloudRuntimeException("Unable to prepare SDC, failed to get the system id for PowerFlex storage pool: " + dataStore.getName()); @@ -116,7 +132,7 @@ public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { long poolId = dataStore.getId(); long hostId = host.getId(); - String sdcId = getConnectedSdc(poolId, hostId); + String sdcId = getConnectedSdc(host, dataStore); if (StringUtils.isNotBlank(sdcId)) { logger.debug(String.format("SDC %s already connected for the pool: %d on host: %d, no need to prepare/start it", sdcId, poolId, hostId)); return sdcId; @@ -227,6 +243,11 @@ public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { @Override public boolean stopSDC(Host host, DataStore dataStore) { + if (Boolean.FALSE.equals(ConnectOnDemand.valueIn(host.getDataCenterId()))) { + logger.debug(String.format("On-demand connect/disconnect config %s disabled in the zone %d, no need to unprepare SDC", ConnectOnDemand.key(), host.getDataCenterId())); + return true; + } + String systemId = storagePoolDetailsDao.findDetail(dataStore.getId(), ScaleIOGatewayClient.STORAGE_POOL_SYSTEM_ID).getValue(); if (systemId == null) { throw new CloudRuntimeException("Unable to unprepare SDC, failed to get the system id for PowerFlex storage pool: " + dataStore.getName()); @@ -248,7 +269,7 @@ public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { long poolId = dataStore.getId(); long hostId = host.getId(); - String sdcId = getConnectedSdc(poolId, hostId); + String sdcId = getConnectedSdc(host, dataStore); if (StringUtils.isBlank(sdcId)) { logger.debug("SDC not connected, no need to unprepare it"); return true; @@ -297,7 +318,10 @@ public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { } } - private String getConnectedSdc(long poolId, long hostId) { + private String getConnectedSdc(Host host, DataStore dataStore) { + long poolId = dataStore.getId(); + long hostId = host.getId(); + try { StoragePoolHostVO poolHostVO = storagePoolHostDao.findByPoolHost(poolId, hostId); if (poolHostVO == null) { @@ -344,4 +368,14 @@ public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { private ScaleIOGatewayClient getScaleIOClient(final Long storagePoolId) throws Exception { return ScaleIOGatewayClientConnectionPool.getInstance().getClient(storagePoolId, storagePoolDetailsDao); } + + @Override + public String getConfigComponentName() { + return ScaleIOSDCManager.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[]{ConnectOnDemand}; + } } diff --git a/server/pom.xml b/server/pom.xml index 6b027b2c7c7..8f7f5e85f86 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -26,12 +26,6 @@ cloudstack 4.20.0.0-SNAPSHOT - - - juniper-tungsten-api - https://github.com/radu-todirica/tungsten-api/raw/master - - @@ -197,11 +191,6 @@ metrics-jvm 3.0.2 - - net.juniper.tungsten - juniper-tungsten-api - 2.0 - diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java index f4c9b19c192..4063cfe7a18 100644 --- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java @@ -818,8 +818,14 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q Integer count = eventIdPage.second(); Long[] idArray = eventIdPage.first().toArray(new Long[0]); - if (count == 0) { - return new Pair<>(new ArrayList<>(), count); + /** + * Need to check array empty, because {@link com.cloud.utils.db.GenericDaoBase#searchAndCount(SearchCriteria, Filter, boolean)} + * makes two calls: first to get objects and second to get count. + * List events has start date filter, there is highly possible cause where no objects loaded + * and next millisecond new event added and finally we ended up with count = 1 and no ids. + */ + if (count == 0 || idArray.length < 1) { + count = 0; } List events = _eventJoinDao.searchByIds(idArray); diff --git a/server/src/main/java/com/cloud/event/dao/EventJoinDaoImpl.java b/server/src/main/java/com/cloud/event/dao/EventJoinDaoImpl.java index f51df27a741..b4316051e43 100644 --- a/server/src/main/java/com/cloud/event/dao/EventJoinDaoImpl.java +++ b/server/src/main/java/com/cloud/event/dao/EventJoinDaoImpl.java @@ -131,6 +131,10 @@ public class EventJoinDaoImpl extends GenericDaoBase implemen @Override public List searchByIds(Long... ids) { + // return empty collection if there are no ids. + if (ids.length == 0) { + return List.of(); + } SearchCriteria sc = vrSearch.create(); sc.setParameters("idIN", ids); return searchIncludingRemoved(sc, null, null, false); diff --git a/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java b/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java index f5e053cc830..e6be174abcd 100644 --- a/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java +++ b/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java @@ -35,6 +35,7 @@ import javax.inject.Inject; import com.cloud.network.dao.PublicIpQuarantineDao; import com.cloud.network.vo.PublicIpQuarantineVO; +import com.cloud.resourcelimit.CheckedReservation; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.annotation.AnnotationService; @@ -53,6 +54,7 @@ import org.apache.cloudstack.region.PortableIp; import org.apache.cloudstack.region.PortableIpDao; import org.apache.cloudstack.region.PortableIpVO; import org.apache.cloudstack.region.Region; +import org.apache.cloudstack.reservation.dao.ReservationDao; import org.apache.commons.collections.CollectionUtils; import com.cloud.agent.AgentManager; @@ -259,6 +261,8 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Inject ResourceLimitService _resourceLimitMgr; + @Inject + ReservationDao reservationDao; @Inject NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao; @Inject @@ -1548,14 +1552,15 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage logger.debug("Associating ip " + ipToAssoc + " to network " + network); - IPAddressVO ip = _ipAddressDao.findById(ipId); - //update ip address with networkId - ip.setAssociatedWithNetworkId(networkId); - ip.setSourceNat(isSourceNat); - _ipAddressDao.update(ipId, ip); - boolean success = false; - try { + IPAddressVO ip = null; + try (CheckedReservation publicIpReservation = new CheckedReservation(owner, ResourceType.public_ip, 1l, reservationDao, _resourceLimitMgr)) { + ip = _ipAddressDao.findById(ipId); + //update ip address with networkId + ip.setAssociatedWithNetworkId(networkId); + ip.setSourceNat(isSourceNat); + _ipAddressDao.update(ipId, ip); + success = applyIpAssociations(network, false); if (success) { logger.debug("Successfully associated ip address " + ip.getAddress().addr() + " to network " + network); @@ -1563,6 +1568,9 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage logger.warn("Failed to associate ip address " + ip.getAddress().addr() + " to network " + network); } return _ipAddressDao.findById(ipId); + } catch (Exception e) { + logger.error(String.format("Failed to associate ip address %s to network %s", ipToAssoc, network), e); + throw new CloudRuntimeException(String.format("Failed to associate ip address %s to network %s", ipToAssoc, network), e); } finally { if (!success && releaseOnFailure) { if (ip != null) { diff --git a/server/src/main/java/com/cloud/network/NetworkModelImpl.java b/server/src/main/java/com/cloud/network/NetworkModelImpl.java index 3eeee8d5ae3..1276ec22067 100644 --- a/server/src/main/java/com/cloud/network/NetworkModelImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkModelImpl.java @@ -788,13 +788,19 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi } @Override - public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) { + public NetworkVO getNetworkWithSGWithFreeIPs(Account account, Long zoneId) { List networks = _networksDao.listByZoneSecurityGroup(zoneId); if (networks == null || networks.isEmpty()) { return null; } NetworkVO ret_network = null; for (NetworkVO nw : networks) { + try { + checkAccountNetworkPermissions(account, nw); + } catch (PermissionDeniedException e) { + continue; + } + List vlans = _vlanDao.listVlansByNetworkId(nw.getId()); for (VlanVO vlan : vlans) { if (_ipAddressDao.countFreeIpsInVlan(vlan.getId()) > 0) { @@ -2775,7 +2781,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi } @Override - public boolean checkSecurityGroupSupportForNetwork(DataCenter zone, List networkIds, + public boolean checkSecurityGroupSupportForNetwork(Account account, DataCenter zone, + List networkIds, List securityGroupsIds) { if (zone.isSecurityGroupEnabled()) { return true; @@ -2791,7 +2798,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi } } } else if (CollectionUtils.isNotEmpty(securityGroupsIds)) { - Network networkWithSecurityGroup = getNetworkWithSGWithFreeIPs(zone.getId()); + Network networkWithSecurityGroup = getNetworkWithSGWithFreeIPs(account, zone.getId()); return networkWithSecurityGroup != null; } return false; diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index a77540ddcc3..2ccd5fdd820 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -4220,7 +4220,11 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C addDefaultInternalLbProviderToPhysicalNetwork(pNetwork.getId()); //Add tungsten network service provider - addDefaultTungstenProviderToPhysicalNetwork(pNetwork.getId()); + try { + addDefaultTungstenProviderToPhysicalNetwork(pNetwork.getId()); + } catch (Exception ex) { + logger.warn("Failed to add Tungsten provider to physical network due to:" + ex.getMessage()); + } // Add the config drive provider addConfigDriveToPhysicalNetwork(pNetwork.getId()); diff --git a/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java index 05dba6802cb..5e7a4a0c4ef 100644 --- a/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java @@ -1812,7 +1812,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage null, null, true, null, affinityGroupIdList, customParameters, null, null, null, null, true, overrideDiskOfferingId); } else { - if (networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds, + if (networkModel.checkSecurityGroupSupportForNetwork(owner, zone, networkIds, Collections.emptyList())) { vm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, null, owner, vmHostName,vmHostName, diskOfferingId, dataDiskSize, null, diff --git a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java index d21e2bf8ca4..b956ccc16ed 100644 --- a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java @@ -43,13 +43,14 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import com.cloud.configuration.ConfigurationManager; +import com.cloud.configuration.ConfigurationManagerImpl; +import com.cloud.bgp.BGPService; +import com.cloud.dc.ASNumberVO; +import com.cloud.dc.dao.ASNumberDao; import com.cloud.dc.Vlan; import com.cloud.network.dao.NsxProviderDao; import com.cloud.network.element.NsxProviderVO; -import com.cloud.configuration.ConfigurationManagerImpl; -import com.cloud.dc.ASNumberVO; -import com.cloud.bgp.BGPService; -import com.cloud.dc.dao.ASNumberDao; +import com.cloud.resourcelimit.CheckedReservation; import com.google.common.collect.Sets; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.alert.AlertService; @@ -75,6 +76,7 @@ import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.network.Ipv4GuestSubnetNetworkMap; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.apache.cloudstack.query.QueryService; +import org.apache.cloudstack.reservation.dao.ReservationDao; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.ObjectUtils; @@ -250,6 +252,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @Inject ResourceLimitService _resourceLimitMgr; @Inject + ReservationDao reservationDao; + @Inject VpcServiceMapDao _vpcSrvcDao; @Inject DataCenterDao _dcDao; @@ -3175,9 +3179,10 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis logger.debug("Associating ip " + ipToAssoc + " to vpc " + vpc); final boolean isSourceNatFinal = isSrcNatIpRequired(vpc.getVpcOfferingId()) && getExistingSourceNatInVpc(vpc.getAccountId(), vpcId, false) == null; - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(final TransactionStatus status) { + try (CheckedReservation publicIpReservation = new CheckedReservation(owner, ResourceType.public_ip, 1l, reservationDao, _resourceLimitMgr)) { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(final TransactionStatus status) { final IPAddressVO ip = _ipAddressDao.findById(ipId); // update ip address with networkId ip.setVpcId(vpcId); @@ -3187,8 +3192,12 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis // mark ip as allocated _ipAddrMgr.markPublicIpAsAllocated(ip); - } - }); + } + }); + } catch (Exception e) { + logger.error("Failed to associate ip " + ipToAssoc + " to vpc " + vpc, e); + throw new CloudRuntimeException("Failed to associate ip " + ipToAssoc + " to vpc " + vpc, e); + } logger.debug("Successfully assigned ip " + ipToAssoc + " to vpc " + vpc); CallContext.current().putContextParameter(IpAddress.class, ipToAssoc.getUuid()); diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java index 5a2f4e690fa..2ed6be39b54 100644 --- a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java @@ -389,6 +389,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C ConfigDepot configDepot; @Inject ConfigurationDao configurationDao; + @Inject + private ImageStoreDetailsUtil imageStoreDetailsUtil; protected List _discoverers; @@ -3488,6 +3490,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C throw new CloudRuntimeException("Failed to create temporary file path to mount the store"); } Pair storeUrlAndId = new Pair<>(url, store.getId()); + String nfsVersion = imageStoreDetailsUtil.getNfsVersion(store.getId()); for (HypervisorType hypervisorType : hypSet) { try { if (HypervisorType.Simulator == hypervisorType) { @@ -3504,7 +3507,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C templateVO = _templateStoreDao.findByTemplate(templateId, DataStoreRole.Image); if (templateVO != null) { try { - if (SystemVmTemplateRegistration.validateIfSeeded(url, templateVO.getInstallPath())) { + if (SystemVmTemplateRegistration.validateIfSeeded( + url, templateVO.getInstallPath(), nfsVersion)) { continue; } } catch (Exception e) { @@ -3512,7 +3516,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } } } - SystemVmTemplateRegistration.mountStore(storeUrlAndId.first(), filePath); + SystemVmTemplateRegistration.mountStore(storeUrlAndId.first(), filePath, nfsVersion); if (templateVO != null && vmTemplateVO != null) { systemVmTemplateRegistration.registerTemplate(hypervisorAndTemplateName, storeUrlAndId, vmTemplateVO, templateVO, filePath); } else { diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index 6caa95a4b63..cb859f2dde9 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -2356,7 +2356,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic if (vm != null && vm.getType().equals(VirtualMachine.Type.User)) { UserVmVO userVm = _userVmDao.findById(volume.getInstanceId()); if (userVm != null && UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Shrink volume cannot be done on a Shared FileSystem VM"); + throw new InvalidParameterValueException("Shrink volume cannot be done on a Shared FileSystem Instance"); } } } @@ -2497,7 +2497,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic UserVmVO vm = getAndCheckUserVmVO(vmId, volumeToAttach); if (!allowAttachForSharedFS && UserVmManager.SHAREDFSVM.equals(vm.getUserVmType())) { - throw new InvalidParameterValueException("Can't attach a volume to a Shared FileSystem VM"); + throw new InvalidParameterValueException("Can't attach a volume to a Shared FileSystem Instance"); } checkDeviceId(deviceId, volumeToAttach, vm); @@ -2923,7 +2923,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic UserVmVO vm = _userVmDao.findById(vmId); if (UserVmManager.SHAREDFSVM.equals(vm.getUserVmType())) { - throw new InvalidParameterValueException("Can't detach a volume from a Shared FileSystem VM"); + throw new InvalidParameterValueException("Can't detach a volume from a Shared FileSystem Instance"); } if (vm.getState() != State.Running && vm.getState() != State.Stopped && vm.getState() != State.Destroyed) { diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index f58e5bf9aab..41e0b6f93ff 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1188,7 +1188,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId); } if (UserVmManager.SHAREDFSVM.equals(vm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); + throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); } VMTemplateVO iso = _tmpltDao.findById(isoId); diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index cf81a78070f..219feeef5a9 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -958,7 +958,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir throw new InvalidParameterValueException("unable to find a virtual machine by id" + cmd.getId()); } if (UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); + throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); } _accountMgr.checkAccess(caller, null, true, userVm); @@ -1005,7 +1005,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir throw new InvalidParameterValueException("unable to find a virtual machine by id" + cmd.getId()); } if (UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); + throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); } VMTemplateVO template = _templateDao.findByIdIncludingRemoved(userVm.getTemplateId()); @@ -1450,7 +1450,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if ((network.getAclType() != ControlledEntity.ACLType.Account) || (network.getDomainId() != vmInstance.getDomainId()) || (network.getAccountId() != vmInstance.getAccountId())) { - throw new InvalidParameterValueException("Shared network which is not Account scoped and not belonging to the same account can not be added to a Shared FileSystem VM"); + throw new InvalidParameterValueException("Shared network which is not Account scoped and not belonging to the same account can not be added to a Shared FileSystem Instance"); } } @@ -2292,7 +2292,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); } if (UserVmManager.SHAREDFSVM.equals(vm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); + throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); } // When trying to expunge, permission is denied when the caller is not an admin and the AllowUserExpungeRecoverVm is false for the caller. @@ -2831,7 +2831,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } UserVmVO userVm = _vmDao.findById(cmd.getId()); if (userVm != null && UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); + throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); } String userData = cmd.getUserData(); @@ -3126,11 +3126,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir Network defaultNetwork = null; try { DataCenterVO zone = _dcDao.findById(vm.getDataCenterId()); - if (zone.getNetworkType() == NetworkType.Basic) { // Get default guest network in Basic zone defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId()); - } else if (_networkModel.checkSecurityGroupSupportForNetwork(zone, Collections.emptyList(), securityGroupIdList)) { + } else if (_networkModel.checkSecurityGroupSupportForNetwork(_accountMgr.getActiveAccountById(vm.getAccountId()), zone, Collections.emptyList(), securityGroupIdList)) { NicVO defaultNic = _nicDao.findDefaultNicForVM(vm.getId()); if (defaultNic != null) { defaultNetwork = _networkDao.findById(defaultNic.getNetworkId()); @@ -3417,7 +3416,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); } if (UserVmManager.SHAREDFSVM.equals(vm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); + throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); } if (Arrays.asList(State.Destroyed, State.Expunging).contains(vm.getState()) && !expunge) { @@ -3759,7 +3758,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir // If no network is specified, find system security group enabled network if (networkIdList == null || networkIdList.isEmpty()) { - Network networkWithSecurityGroup = _networkModel.getNetworkWithSGWithFreeIPs(zone.getId()); + Network networkWithSecurityGroup = _networkModel.getNetworkWithSGWithFreeIPs(owner, zone.getId()); if (networkWithSecurityGroup == null) { throw new InvalidParameterValueException("No network with security enabled is found in zone id=" + zone.getUuid()); } @@ -5958,7 +5957,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir throw ex; } if (UserVmManager.SHAREDFSVM.equals(vm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); + throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); } if (vm.getRemoved() != null) { @@ -6205,7 +6204,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled, overrideDiskOfferingId); } } else { - if (_networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds, + if (_networkModel.checkSecurityGroupSupportForNetwork(owner, zone, networkIds, cmd.getSecurityGroupIdList())) { vm = createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, getSecurityGroupIdList(cmd, zone, template, owner), owner, name, displayName, diskOfferingId, size, group, cmd.getHypervisor(), cmd.getHttpMethod(), userData, userDataId, userDataDetails, sshKeyPairNames, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard, @@ -7420,7 +7419,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir throw ex; } if (UserVmManager.SHAREDFSVM.equals(vm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); + throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); } final Account oldAccount = _accountService.getActiveAccountById(vm.getAccountId()); @@ -7629,7 +7628,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir Set applicableNetworks = new LinkedHashSet<>(); Map requestedIPv4ForNics = new HashMap<>(); Map requestedIPv6ForNics = new HashMap<>(); - if (_networkModel.checkSecurityGroupSupportForNetwork(zone, networkIdList, securityGroupIdList)) { // advanced zone with security groups + if (_networkModel.checkSecurityGroupSupportForNetwork(newAccount, zone, networkIdList, securityGroupIdList)) { // advanced zone with security groups // cleanup the old security groups _securityGroupMgr.removeInstanceFromGroups(cmd.getVmId()); // if networkIdList is null and the first network of vm is shared network, then keep it if possible @@ -7943,7 +7942,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir throw ex; } if (UserVmManager.SHAREDFSVM.equals(vm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); + throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); } _accountMgr.checkAccess(caller, null, true, vm); @@ -8859,7 +8858,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir private Network getNetworkForOvfNetworkMapping(DataCenter zone, Account owner) throws InsufficientCapacityException, ResourceAllocationException { Network network = null; if (zone.isSecurityGroupEnabled() || _networkModel.isSecurityGroupSupportedForZone(zone.getId())) { - network = _networkModel.getNetworkWithSGWithFreeIPs(zone.getId()); + network = _networkModel.getNetworkWithSGWithFreeIPs(owner, zone.getId()); if (network == null) { throw new InvalidParameterValueException("No network with security enabled is found in zone ID: " + zone.getUuid()); } diff --git a/server/src/main/java/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/main/java/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index 408a27c64fc..cd67c720b49 100644 --- a/server/src/main/java/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -509,7 +509,7 @@ public class VMSnapshotManagerImpl extends MutualExclusiveIdsManagerBase impleme throw new InvalidParameterValueException("Create vm to snapshot failed due to vm: " + vmId + " is not found"); } if (UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); + throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); } VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId); if (vmSnapshot == null) { diff --git a/server/src/main/java/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java b/server/src/main/java/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java index 77974d23491..0ec16f1e748 100644 --- a/server/src/main/java/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java @@ -432,7 +432,7 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId); } if (UserVmManager.SHAREDFSVM.equals(vmInstance.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); + throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); } // Check that the VM is stopped diff --git a/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java b/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java index b86b65bd465..6e13ba135df 100644 --- a/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java @@ -31,8 +31,6 @@ import java.util.stream.Collectors; import com.amazonaws.util.CollectionUtils; import com.cloud.storage.VolumeApiService; import com.cloud.utils.fsm.NoTransitionException; -import com.cloud.vm.UserVmManager; -import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachineManager; import javax.inject.Inject; import javax.naming.ConfigurationException; @@ -296,13 +294,6 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager { throw new CloudRuntimeException("VM is not in running or stopped state"); } - if (vm.getType().equals(VirtualMachine.Type.User)) { - UserVmVO userVm = userVmDao.findById(vmId); - if (userVm != null && UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); - } - } - validateForZone(vm.getDataCenterId()); accountManager.checkAccess(CallContext.current().getCallingAccount(), null, true, vm); @@ -431,12 +422,6 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager { } final VMInstanceVO vm = findVmById(vmId); - if (vm.getType().equals(VirtualMachine.Type.User)) { - UserVmVO userVm = userVmDao.findById(vmId); - if (userVm != null && UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); - } - } validateForZone(vm.getDataCenterId()); accountManager.checkAccess(CallContext.current().getCallingAccount(), null, true, vm); @@ -504,13 +489,6 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager { validateForZone(vm.getDataCenterId()); accountManager.checkAccess(CallContext.current().getCallingAccount(), null, true, vm); - if (vm.getType().equals(VirtualMachine.Type.User)) { - UserVmVO userVm = userVmDao.findById(vmId); - if (userVm != null && UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); - } - } - if (vm.getBackupOfferingId() == null) { throw new CloudRuntimeException("VM has not backup offering configured, cannot create backup before assigning it to a backup offering"); } @@ -784,12 +762,6 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager { validateForZone(backup.getZoneId()); final VMInstanceVO vm = findVmById(vmId); - if (vm.getType().equals(VirtualMachine.Type.User)) { - UserVmVO userVm = userVmDao.findById(vmId); - if (userVm != null && UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); - } - } accountManager.checkAccess(CallContext.current().getCallingAccount(), null, true, vm); if (vm.getBackupOfferingId() != null && !BackupEnableAttachDetachVolumes.value()) { diff --git a/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java b/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java index 62bc50889f1..3e6c460a169 100644 --- a/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java @@ -478,7 +478,8 @@ public class DiagnosticsServiceImpl extends ManagerBase implements PluggableServ private void cleanupOldDiagnosticFiles(DataStore store) { String mountPoint = null; - mountPoint = serviceImpl.mountManager.getMountPoint(store.getUri(), null); + mountPoint = serviceImpl.mountManager.getMountPoint(store.getUri(), + serviceImpl.imageStoreDetailsUtil.getNfsVersion(store.getId())); if (StringUtils.isNotBlank(mountPoint)) { File directory = new File(mountPoint + File.separator + DIAGNOSTICS_DIRECTORY); if (directory.isDirectory()) { diff --git a/server/src/main/java/org/apache/cloudstack/resource/ResourceCleanupServiceImpl.java b/server/src/main/java/org/apache/cloudstack/resource/ResourceCleanupServiceImpl.java index c4abbb04514..50c4de36b7f 100644 --- a/server/src/main/java/org/apache/cloudstack/resource/ResourceCleanupServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/resource/ResourceCleanupServiceImpl.java @@ -579,7 +579,9 @@ public class ResourceCleanupServiceImpl extends ManagerBase implements ResourceC @Override public boolean stop() { purgeExpungedResourcesJobExecutor.shutdown(); - expungedResourcesCleanupExecutor.shutdownNow(); + if (expungedResourcesCleanupExecutor != null) { + expungedResourcesCleanupExecutor.shutdownNow(); + } return true; } diff --git a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java index 2504cabf809..fc982668e73 100644 --- a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java @@ -2110,7 +2110,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager { if (vmVO.getType().equals(VirtualMachine.Type.User)) { UserVmVO userVm = userVmDao.findById(vmId); if (UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem VM"); + throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); } } diff --git a/server/src/test/java/com/cloud/network/MockNetworkModelImpl.java b/server/src/test/java/com/cloud/network/MockNetworkModelImpl.java index d125291657a..ea9a0340eaa 100644 --- a/server/src/test/java/com/cloud/network/MockNetworkModelImpl.java +++ b/server/src/test/java/com/cloud/network/MockNetworkModelImpl.java @@ -237,7 +237,7 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { * @see com.cloud.network.NetworkModel#getNetworkWithSGWithFreeIPs(java.lang.Long) */ @Override - public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) { + public NetworkVO getNetworkWithSGWithFreeIPs(Account account, Long zoneId) { // TODO Auto-generated method stub return null; } @@ -950,7 +950,7 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { } @Override - public boolean checkSecurityGroupSupportForNetwork(DataCenter zone, List networkIds, List securityGroupsIds) { + public boolean checkSecurityGroupSupportForNetwork(Account account, DataCenter zone, List networkIds, List securityGroupsIds) { return false; } } diff --git a/server/src/test/java/com/cloud/network/as/AutoScaleManagerImplTest.java b/server/src/test/java/com/cloud/network/as/AutoScaleManagerImplTest.java index 386cf65aed3..b391aeb9f07 100644 --- a/server/src/test/java/com/cloud/network/as/AutoScaleManagerImplTest.java +++ b/server/src/test/java/com/cloud/network/as/AutoScaleManagerImplTest.java @@ -1318,7 +1318,8 @@ public class AutoScaleManagerImplTest { when(userVmService.createAdvancedSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), eq(true), any(), any())).thenReturn(userVmMock); - when(networkModel.checkSecurityGroupSupportForNetwork(zoneMock, List.of(networkId), Collections.emptyList())).thenReturn(true); + when(networkModel.checkSecurityGroupSupportForNetwork(account, zoneMock, + List.of(networkId), Collections.emptyList())).thenReturn(true); long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock); @@ -1367,7 +1368,8 @@ public class AutoScaleManagerImplTest { when(userVmService.createAdvancedVirtualMachine(any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), eq(true), any(), any(), any(), any(), any(), any(), any(), eq(true), any(), any())).thenReturn(userVmMock); - when(networkModel.checkSecurityGroupSupportForNetwork(zoneMock, List.of(networkId), Collections.emptyList())).thenReturn(false); + when(networkModel.checkSecurityGroupSupportForNetwork(account, zoneMock, + List.of(networkId), Collections.emptyList())).thenReturn(false); long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock); diff --git a/server/src/test/java/com/cloud/vpc/MockNetworkModelImpl.java b/server/src/test/java/com/cloud/vpc/MockNetworkModelImpl.java index 7f94405ffdc..3b41a56dc0f 100644 --- a/server/src/test/java/com/cloud/vpc/MockNetworkModelImpl.java +++ b/server/src/test/java/com/cloud/vpc/MockNetworkModelImpl.java @@ -248,7 +248,7 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { * @see com.cloud.network.NetworkModel#getNetworkWithSGWithFreeIPs(java.lang.Long) */ @Override - public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) { + public NetworkVO getNetworkWithSGWithFreeIPs(Account account, Long zoneId) { // TODO Auto-generated method stub return null; } @@ -966,7 +966,8 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { } @Override - public boolean checkSecurityGroupSupportForNetwork(DataCenter zone, List networkIds, List securityGroupsIds) { + public boolean checkSecurityGroupSupportForNetwork(Account account, DataCenter zone, + List networkIds, List securityGroupsIds) { return false; } } diff --git a/setup/bindir/cloud-sysvmadm.in b/setup/bindir/cloud-sysvmadm.in index a5bb9b37ac1..a262f6b710e 100755 --- a/setup/bindir/cloud-sysvmadm.in +++ b/setup/bindir/cloud-sysvmadm.in @@ -18,13 +18,11 @@ # under the License. -. /etc/rc.d/init.d/functions - #set -x usage() { usage_content=" - The tool for stopping/starting running system vms and domain routers + The tool for stopping/starting running system vms and domain routers. It requires integration API port to be enabled. Usage: %s: [-d] [-u] [-p] [-m] [-s] [-r] [-a] [-n] [-t] [-l] [-z] [-v] [-i] [-j] @@ -63,6 +61,7 @@ vmids="" vmidsclause="" withids="" vmtable="vm_instance" +integrationport=0 @@ -104,6 +103,12 @@ do done +integrationport=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "SELECT value FROM configuration WHERE name='integration.api.port'"`) +if [ $integrationport -le 0 ]; then + echo "Integration port is not enabled!" + exit +fi + prepare_ids_clause() { if [[ ! -z "$vmidsclause" ]]; then return @@ -117,168 +122,167 @@ prepare_ids_clause() { stop_start_system() { prepare_ids_clause -secondary=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select id from $vmtable where state=\"Running\" and type=\"SecondaryStorageVm\"$zone$vmidsclause"`) -console=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select id from $vmtable where state=\"Running\" and type=\"ConsoleProxy\"$zone$vmidsclause"`) -length_secondary=(${#secondary[@]}) -length_console=(${#console[@]}) + secondary=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select uuid from $vmtable where state=\"Running\" and type=\"SecondaryStorageVm\"$zone$vmidsclause"`) + console=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select uuid from $vmtable where state=\"Running\" and type=\"ConsoleProxy\"$zone$vmidsclause"`) + length_secondary=(${#secondary[@]}) + length_console=(${#console[@]}) -echo -e "\nStopping and starting $length_secondary secondary storage vm(s)$inzone$withids..." -echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Stopping and starting $length_secondary secondary storage vm(s)$inzone$withids..." >>$LOGFILE + echo -e "\nStopping and starting $length_secondary secondary storage vm(s)$inzone$withids..." + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Stopping and starting $length_secondary secondary storage vm(s)$inzone$withids..." >>$LOGFILE -for d in "${secondary[@]}"; do - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Stopping secondary storage vm with id $d" >>$LOGFILE - jobresult=$(send_request stopSystemVm $d) - if [ "$jobresult" != "1" ]; then - echo -e "ERROR: Failed to stop secondary storage vm with id $d \n" - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to stop secondary storage vm with id $d" >>$LOGFILE - else - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Starting secondary storage vm with id $d" >>$LOGFILE - jobresult=$(send_request startSystemVm $d SSVM) - if [ "$jobresult" != "1" ]; then - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to start secondary storage vm with id $d" >>$LOGFILE - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to start secondary storage vm with id $d" >>$LOGFILE - fi - fi -done + for d in "${secondary[@]}"; do + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Stopping secondary storage vm with id $d" >>$LOGFILE + jobresult=$(send_request stopSystemVm $d) + if [ "$jobresult" != "1" ]; then + echo -e "ERROR: Failed to stop secondary storage vm with id $d \n" + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to stop secondary storage vm with id $d" >>$LOGFILE + else + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Starting secondary storage vm with id $d" >>$LOGFILE + jobresult=$(send_request startSystemVm $d SSVM) + if [ "$jobresult" != "1" ]; then + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to start secondary storage vm with id $d" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to start secondary storage vm with id $d" >>$LOGFILE + fi + fi + done -if [ "$length_secondary" == "0" ];then - echo -e "No running secondary storage vms found \n" -else - echo -e "Done stopping and starting secondary storage vm(s)$inzone$withids" - echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Done stopping and starting secondary storage vm(s)$inzone$withids." >>$LOGFILE -fi - -echo -e "\nStopping and starting $length_console console proxy vm(s)$inzone$withids..." -echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Stopping and starting $length_console console proxy vm(s)$inzone$withids..." >>$LOGFILE - -for d in "${console[@]}"; do - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Stopping console proxy with id $d" >>$LOGFILE - jobresult=$(send_request stopSystemVm $d) - if [ "$jobresult" != "1" ]; then - echo -e "ERROR: Failed to stop console proxy vm with id $d \n" - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to stop console proxy vm with id $d" >>$LOGFILE + if [ "$length_secondary" == "0" ];then + echo -e "No running secondary storage vms found \n" else - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Starting console proxy vm with id $d" >>$LOGFILE - jobresult=$(send_request startSystemVm $d consoleProxy) - if [ "$jobresult" != "1" ]; then - echo -e "ERROR: Failed to start console proxy vm with id $d \n" - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to start console proxy vm with id $d" >>$LOGFILE - fi + echo -e "Done stopping and starting secondary storage vm(s)$inzone$withids" + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Done stopping and starting secondary storage vm(s)$inzone$withids." >>$LOGFILE fi -done -if [ "$length_console" == "0" ];then - echo -e "No running console proxy vms found \n" -else - echo "Done stopping and starting console proxy vm(s) $inzone$withids." - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] Done stopping and starting console proxy vm(s) $inzone$withids." >>$LOGFILE -fi + echo -e "\nStopping and starting $length_console console proxy vm(s)$inzone$withids..." + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Stopping and starting $length_console console proxy vm(s)$inzone$withids..." >>$LOGFILE + + for d in "${console[@]}"; do + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Stopping console proxy with id $d" >>$LOGFILE + jobresult=$(send_request stopSystemVm $d) + if [ "$jobresult" != "1" ]; then + echo -e "ERROR: Failed to stop console proxy vm with id $d \n" + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to stop console proxy vm with id $d" >>$LOGFILE + else + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Starting console proxy vm with id $d" >>$LOGFILE + jobresult=$(send_request startSystemVm $d consoleProxy) + if [ "$jobresult" != "1" ]; then + echo -e "ERROR: Failed to start console proxy vm with id $d \n" + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to start console proxy vm with id $d" >>$LOGFILE + fi + fi + done + + if [ "$length_console" == "0" ];then + echo -e "No running console proxy vms found \n" + else + echo "Done stopping and starting console proxy vm(s) $inzone$withids." + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] Done stopping and starting console proxy vm(s) $inzone$withids." >>$LOGFILE + fi } stop_start_router() { prepare_ids_clause - router=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select id from vm_instance where state=\"Running\" and type=\"DomainRouter\"$zone$vmidsclause"`) - length_router=(${#router[@]}) + router=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select uuid from vm_instance where state=\"Running\" and type=\"DomainRouter\"$zone$vmidsclause"`) + length_router=(${#router[@]}) - echo -e "\nStopping and starting $length_router running routing vm(s)$inzone$withids... " - echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Stopping and starting $length_router running routing vm(s)$inzone$withids... " >>$LOGFILE + echo -e "\nStopping and starting $length_router running routing vm(s)$inzone$withids... " + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Stopping and starting $length_router running routing vm(s)$inzone$withids... " >>$LOGFILE - #Spawn reboot router in parallel - run commands in chunks - number of threads is configurable + #Spawn reboot router in parallel - run commands in chunks - number of threads is configurable - pids=() - for d in "${router[@]}"; do + pids=() + for d in "${router[@]}"; do - reboot_router $d & + reboot_router $d & - pids=( "${pids[@]}" $! ) + pids=( "${pids[@]}" $! ) - length_pids=(${#pids[@]}) - unfinishedPids=(${#pids[@]}) + length_pids=(${#pids[@]}) + unfinishedPids=(${#pids[@]}) - if [ $maxthreads -gt $length_router ]; then - maxthreads=$length_router - fi + if [ $maxthreads -gt $length_router ]; then + maxthreads=$length_router + fi - if [ $length_pids -ge $maxthreads ]; then - while [ $unfinishedPids -gt 0 ]; do - sleep 10 - count=0 - for (( i = 0 ; i < $length_pids; i++ )); do - if ! ps ax | grep -v grep | grep ${pids[$i]} > /dev/null; then - count=`expr $count + 1` - fi - done + if [ $length_pids -ge $maxthreads ]; then + while [ $unfinishedPids -gt 0 ]; do + sleep 10 + count=0 + for (( i = 0 ; i < $length_pids; i++ )); do + if ! ps ax | grep -v grep | grep ${pids[$i]} > /dev/null; then + count=`expr $count + 1` + fi + done - if [ $count -eq $unfinishedPids ]; then - unfinishedPids=0 - fi + if [ $count -eq $unfinishedPids ]; then + unfinishedPids=0 + fi - done + done - #remove all elements from pids - if [ $unfinishedPids -eq 0 ]; then - pids=() - length_pids=(${#pids[@]}) - fi + #remove all elements from pids + if [ $unfinishedPids -eq 0 ]; then + pids=() + length_pids=(${#pids[@]}) + fi - fi + fi - done + done - if [ "$length_router" == "0" ];then - echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] No running router vms found \n" >>$LOGFILE - else - while [ $unfinishedPids -gt 0 ]; do - sleep 10 - done + if [ "$length_router" == "0" ];then + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] No running router vms found \n" >>$LOGFILE + else + while [ $unfinishedPids -gt 0 ]; do + sleep 10 + done - echo -e "Done restarting router(s)$inzone$withids. \n" - echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Done restarting router(s)$inzone$withids. \n" >>$LOGFILE + echo -e "Done restarting router(s)$inzone$withids. \n" + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Done restarting router(s)$inzone$withids. \n" >>$LOGFILE - fi + fi } stop_start_all() { -stop_start_system -stop_start_router + stop_start_system + stop_start_router } send_request(){ - jobid=`curl -sS "http://$ms:8096/?command=$1&id=$2&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}` - if [ "$jobid" == "" ]; then - echo 2 - return - fi - jobresult=$(query_async_job_result $jobid) + jobid=`curl -sS "http://$ms:$integrationport/?command=$1&id=$2&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}` + if [ "$jobid" == "" ]; then + echo 2 + return + fi + jobresult=$(query_async_job_result $jobid) if [ "$jobresult" != "1" ]; then echo -e "ERROR: Failed to $1 id=$2; jobId is $jobid \n" echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to $1 id=$2; jobId is $jobid" >>$LOGFILE fi - echo $jobresult + echo $jobresult } reboot_router(){ - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Restarting router with id $1" >>$LOGFILE - jobid=`curl -sS "http://$ms:8096/?command=rebootRouter&id=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}` - if [ "$jobid" == "" ]; then - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart domainRouter with id $1; unable to submit the job" >>$LOGFILE - echo 2 - return - fi + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Restarting router with id $1" >>$LOGFILE + jobid=`curl -sS "http://$ms:$integrationport/?command=rebootRouter&id=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}` + if [ "$jobid" == "" ]; then + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart domainRouter with id $1; unable to submit the job" >>$LOGFILE + echo 2 + return + fi - jobresult=$(query_async_job_result $jobid) - - if [ "$jobresult" != "1" ]; then - echo -e "ERROR: Failed to restart domainRouter with id $1 \n" - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart domainRouter with id $1; jobId $jobid" >>$LOGFILE - exit 0 - else - echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Successfully restarted domainRouter with id $1; jobId $jobid" >>$LOGFILE - exit 0 - fi + jobresult=$(query_async_job_result $jobid) + if [ "$jobresult" != "1" ]; then + echo -e "ERROR: Failed to restart domainRouter with id $1 \n" + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart domainRouter with id $1; jobId $jobid" >>$LOGFILE + exit 0 + else + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Successfully restarted domainRouter with id $1; jobId $jobid" >>$LOGFILE + exit 0 + fi } restart_networks(){ @@ -346,7 +350,7 @@ restart_networks(){ } restart_network(){ - jobid=`curl -sS "http://$ms:8096/?command=restartNetwork&id=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}` + jobid=`curl -sS "http://$ms:$integrationport/?command=restartNetwork&id=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}` if [ "$jobid" == "" ]; then echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart network with id $1; unable to submit the job" >>$LOGFILE echo 2 @@ -367,7 +371,7 @@ restart_network(){ restart_vpc(){ echo -e "INFO: Restarting vpc with id $1" echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Restarting vpc with id $1" >>$LOGFILE - jobid=`curl -sS "http://$ms:8096/?command=restartVPC&id=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}` + jobid=`curl -sS "http://$ms:$integrationport/?command=restartVPC&id=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}` if [ "$jobid" == "" ]; then echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart vpc with id $1; unable to submit the job" >>$LOGFILE echo 2 @@ -387,7 +391,7 @@ restart_vpc(){ restart_vpcs(){ - vpcs=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select id from vpc WHERE removed is null$zone"`) + vpcs=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select uuid from vpc WHERE removed is null$zone"`) length_vpcs=(${#vpcs[@]}) echo -e "\nRestarting $length_vpcs vpcs... " @@ -450,21 +454,21 @@ restart_vpcs(){ } query_async_job_result() { -while [ 1 ] -do - jobstatus=`curl -sS "http://$ms:8096/?command=queryAsyncJobResult&jobId=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F, {'print $4'} | awk -F: {'print $2'}` - if [ "$jobstatus" != "0" ]; then - echo $jobstatus - break - fi -sleep 5 -done + while [ 1 ] + do + jobstatus=`curl -sS "http://$ms:$integrationport/?command=queryAsyncJobResult&jobId=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F, {'print $7'} | awk -F: {'print $2'}` + if [ "$jobstatus" != "0" ]; then + echo $jobstatus + break + fi + sleep 5 + done } if [ "$system$router$all$help$redundant$vpc" == "" ] then - usage - exit + usage + exit fi if [ "$help" == "1" ] diff --git a/systemvm/agent/noVNC/app/ui.js b/systemvm/agent/noVNC/app/ui.js index 3a85648bb84..e99d763d60c 100644 --- a/systemvm/agent/noVNC/app/ui.js +++ b/systemvm/agent/noVNC/app/ui.js @@ -1000,6 +1000,7 @@ const UI = { clipboardClear() { document.getElementById('noVNC_clipboard_text').value = ""; + document.getElementById('noVNC_clipboard_text').focus(); }, clipboardSend() { diff --git a/systemvm/debian/opt/cloud/bin/passwd_server_ip.py b/systemvm/debian/opt/cloud/bin/passwd_server_ip.py index 7df4ec27763..8051951a18f 100755 --- a/systemvm/debian/opt/cloud/bin/passwd_server_ip.py +++ b/systemvm/debian/opt/cloud/bin/passwd_server_ip.py @@ -114,7 +114,7 @@ class PasswordRequestHandler(BaseHTTPRequestHandler): if requestType == 'send_my_password': password = getPassword(clientAddress) if not password: - self.wfile.write('saved_password') + self.wfile.write('saved_password'.encode()) syslog.syslog('serve_password: requested password not found for %s' % clientAddress) else: self.wfile.write(password.encode()) @@ -122,11 +122,11 @@ class PasswordRequestHandler(BaseHTTPRequestHandler): elif requestType == 'saved_password': removePassword(clientAddress) savePasswordFile() - self.wfile.write('saved_password') + self.wfile.write('saved_password'.encode()) syslog.syslog('serve_password: saved_password ack received from %s' % clientAddress) else: self.send_response(400) - self.wfile.write('bad_request') + self.wfile.write('bad_request'.encode()) syslog.syslog('serve_password: bad_request from IP %s' % clientAddress) return diff --git a/systemvm/debian/opt/cloud/bin/setup/cksnode.sh b/systemvm/debian/opt/cloud/bin/setup/cksnode.sh index aa5d466c96a..e1541f6d0bd 100755 --- a/systemvm/debian/opt/cloud/bin/setup/cksnode.sh +++ b/systemvm/debian/opt/cloud/bin/setup/cksnode.sh @@ -59,6 +59,12 @@ setup_k8s_node() { rm -f /etc/logrotate.d/cloud + # Enable cloud-init without any aid from ds-identify + echo "policy: enabled" > /etc/cloud/ds-identify.cfg + + # Add ConfigDrive to datasource_list + sed -i "s/datasource_list: .*/datasource_list: ['ConfigDrive', 'CloudStack']/g" /etc/cloud/cloud.cfg.d/cloudstack.cfg + log_it "Starting cloud-init services" systemctl enable --now --no-block containerd if [ -f /home/cloud/success ]; then diff --git a/test/integration/smoke/test_usage.py b/test/integration/smoke/test_usage.py index 2100859ba52..1a6ff37cedb 100644 --- a/test/integration/smoke/test_usage.py +++ b/test/integration/smoke/test_usage.py @@ -95,7 +95,7 @@ class Services: "iso": { "displaytext": "Test ISO", "name": "Test ISO", - "url": "http://people.apache.org/~tsp/dummy.iso", + "url": "http://download.cloudstack.org/testing/marvin/dummy.iso", # Source URL where ISO is located "isextractable": True, "isfeatured": True, diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index aea803035ce..8d28749a637 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -16,11 +16,11 @@ # specific language governing permissions and limitations # under the License. -import os import os.path import sys from xml.dom import minidom from xml.parsers.expat import ExpatError +import difflib ROOT_ADMIN = 'r' @@ -51,7 +51,9 @@ known_categories = { 'VirtualMachine': 'Virtual Machine', 'VM': 'Virtual Machine', 'Vnf': 'Virtual Network Functions', + 'VnfTemplate': 'Virtual Network Functions', 'GuestSubnet': 'Routing', + 'HypervisorGuestOsNames': 'Guest OS', 'Domain': 'Domain', 'Template': 'Template', 'Iso': 'ISO', @@ -63,83 +65,46 @@ known_categories = { 'StaticNat': 'NAT', 'IpForwarding': 'NAT', 'Host': 'Host', - 'OutOfBand': 'Out-of-band Management', + 'HostTags': 'Host', + 'OutOfBandManagement': 'Out-of-band Management', 'Cluster': 'Cluster', 'Account': 'Account', 'Role': 'Role', 'Snapshot': 'Snapshot', 'User': 'User', + 'UserData': 'User Data', 'Os': 'Guest OS', 'ServiceOffering': 'Service Offering', 'DiskOffering': 'Disk Offering', 'LoadBalancer': 'Load Balancer', - 'SslCert': 'Load Balancer', + 'SslCert': 'SSL Certificates', 'Router': 'Router', - 'SystemVm': 'System VM', 'Configuration': 'Configuration', 'Capabilities': 'Configuration', 'Pod': 'Pod', + 'ManagementNetworkIpRange': 'Pod', 'PublicIpRange': 'Network', 'Zone': 'Zone', 'Vmware' : 'Zone', 'NetworkOffering': 'Network Offering', 'NetworkACL': 'Network ACL', + 'NetworkAclItem': 'Network ACL', 'Network': 'Network', 'CiscoNexus': 'Network', 'OpenDaylight': 'Network', 'createServiceInstance': 'Network', 'addGloboDnsHost': 'Network', - 'createTungstenFabricProvider': 'Tungsten', - 'listTungstenFabricProviders': 'Tungsten', - 'configTungstenFabricService': 'Tungsten', - 'createTungstenFabricPublicNetwork': 'Tungsten', - 'synchronizeTungstenFabricData': 'Tungsten', - 'addTungstenFabricPolicyRule': 'Tungsten', - 'createTungstenFabricPolicy': 'Tungsten', - 'deleteTungstenFabricPolicy': 'Tungsten', - 'removeTungstenFabricPolicyRule': 'Tungsten', - 'listTungstenFabricTag': 'Tungsten', - 'listTungstenFabricTagType': 'Tungsten', - 'listTungstenFabricPolicy': 'Tungsten', - 'listTungstenFabricPolicyRule': 'Tungsten', - 'listTungstenFabricNetwork': 'Tungsten', - 'listTungstenFabricVm': 'Tungsten', - 'listTungstenFabricNic': 'Tungsten', - 'createTungstenFabricTag': 'Tungsten', - 'createTungstenFabricTagType': 'Tungsten', - 'deleteTungstenFabricTag': 'Tungsten', - 'deleteTungstenFabricTagType': 'Tungsten', - 'applyTungstenFabricPolicy': 'Tungsten', - 'applyTungstenFabricTag': 'Tungsten', - 'removeTungstenFabricTag': 'Tungsten', - 'removeTungstenFabricPolicy': 'Tungsten', - 'createTungstenFabricApplicationPolicySet': 'Tungsten', - 'createTungstenFabricFirewallPolicy': 'Tungsten', - 'createTungstenFabricFirewallRule': 'Tungsten', - 'createTungstenFabricServiceGroup': 'Tungsten', - 'createTungstenFabricAddressGroup': 'Tungsten', - 'createTungstenFabricLogicalRouter': 'Tungsten', - 'addTungstenFabricNetworkGatewayToLogicalRouter': 'Tungsten', - 'listTungstenFabricApplicationPolicySet': 'Tungsten', - 'listTungstenFabricFirewallPolicy': 'Tungsten', - 'listTungstenFabricFirewallRule': 'Tungsten', - 'listTungstenFabricServiceGroup': 'Tungsten', - 'listTungstenFabricAddressGroup': 'Tungsten', - 'listTungstenFabricLogicalRouter': 'Tungsten', - 'deleteTungstenFabricApplicationPolicySet': 'Tungsten', - 'deleteTungstenFabricFirewallPolicy': 'Tungsten', - 'deleteTungstenFabricFirewallRule': 'Tungsten', - 'deleteTungstenFabricAddressGroup': 'Tungsten', - 'deleteTungstenFabricServiceGroup': 'Tungsten', - 'deleteTungstenFabricLogicalRouter': 'Tungsten', - 'removeTungstenFabricNetworkGatewayFromLogicalRouter': 'Tungsten', - 'updateTungstenFabricLBHealthMonitor': 'Tungsten', - 'listTungstenFabricLBHealthMonitor': 'Tungsten', + 'TungstenFabric': 'Tungsten', 'listNsxControllers': 'NSX', 'addNsxController': 'NSX', 'deleteNsxController': 'NSX', 'Vpn': 'VPN', - 'Limit': 'Limit', + 'Limit': 'Resource Limit', + 'Netscaler': 'Netscaler', + 'NetscalerControlCenter': 'Netscaler', + 'NetscalerLoadBalancer': 'Netscaler', + 'SolidFire': 'SolidFire', + 'PaloAlto': 'Palo Alto', 'ResourceCount': 'Limit', 'CloudIdentifier': 'Cloud Identifier', 'InstanceGroup': 'VM Group', @@ -150,10 +115,9 @@ known_categories = { 'updateStorageCapabilities' : 'Storage Pool', 'SecurityGroup': 'Security Group', 'SSH': 'SSH', - 'register': 'Registration', 'AsyncJob': 'Async job', 'Certificate': 'Certificate', - 'Hypervisor': 'Hypervisor', + 'Hypervisor': 'Configuration', 'Alert': 'Alert', 'Event': 'Event', 'login': 'Authentication', @@ -175,19 +139,20 @@ known_categories = { 'ExternalLoadBalancer': 'Ext Load Balancer', 'ExternalFirewall': 'Ext Firewall', 'Usage': 'Usage', - 'TrafficMonitor': 'Usage', - 'TrafficType': 'Usage', + 'TrafficMonitor': 'Network', + 'TrafficType': 'Network', 'Product': 'Product', 'LB': 'Load Balancer', 'ldap': 'LDAP', 'Ldap': 'LDAP', - 'Swift': 'Swift', + 'Swift': 'Image Store', 'S3' : 'S3', - 'SecondaryStorage': 'Host', + 'SecondaryStorage': 'Image Store', 'Project': 'Project', 'Lun': 'Storage', 'Pool': 'Pool', 'VPC': 'VPC', + 'VPCOffering': 'VPC Offering', 'PrivateGateway': 'VPC', 'migrateVpc': 'VPC', 'Simulator': 'simulator', @@ -201,13 +166,15 @@ known_categories = { 'Counter': 'AutoScale', 'Condition': 'AutoScale', 'Api': 'API Discovery', + 'ApiLimit': 'Configuration', 'Region': 'Region', 'Detail': 'Resource metadata', 'addIpToNic': 'Nic', 'removeIpFromNic': 'Nic', 'updateVmNicIp': 'Nic', 'listNics':'Nic', - 'AffinityGroup': 'Affinity Group', + 'AffinityGroup': 'Affinity Group', + 'ImageStore': 'Image Store', 'addImageStore': 'Image Store', 'listImageStore': 'Image Store', 'deleteImageStore': 'Image Store', @@ -228,15 +195,16 @@ known_categories = { 'CacheStores' : 'Cache Stores', 'CacheStore' : 'Cache Store', 'OvsElement' : 'Ovs Element', - 'StratosphereSsp' : ' Stratosphere SSP', + 'StratosphereSsp' : 'Misc Network Service Providers', 'Metrics' : 'Metrics', + 'listClustersMetrics': 'Cluster', + 'VpnUser': 'VPN', + 'listZonesMetrics': 'Metrics', 'Infrastructure' : 'Metrics', - 'listNetscalerControlCenter' : 'Load Balancer', 'listRegisteredServicePackages': 'Load Balancer', 'listNsVpx' : 'Load Balancer', 'destroyNsVPx': 'Load Balancer', 'deployNetscalerVpx' : 'Load Balancer', - 'deleteNetscalerControlCenter' : 'Load Balancer', 'stopNetScalerVpx' : 'Load Balancer', 'deleteServicePackageOffering' : 'Load Balancer', 'destroyNsVpx' : 'Load Balancer', @@ -256,17 +224,16 @@ known_categories = { 'UnmanagedInstance': 'Virtual Machine', 'KubernetesSupportedVersion': 'Kubernetes Service', 'KubernetesCluster': 'Kubernetes Service', - 'UnmanagedInstance': 'Virtual Machine', 'Rolling': 'Rolling Maintenance', 'importVsphereStoragePolicies' : 'vSphere storage policies', 'listVsphereStoragePolicies' : 'vSphere storage policies', 'ConsoleEndpoint': 'Console Endpoint', - 'Shutdown': 'Shutdown', 'importVm': 'Virtual Machine', + 'revertToVMSnapshot': 'Virtual Machine', 'listQuarantinedIp': 'IP Quarantine', 'updateQuarantinedIp': 'IP Quarantine', 'removeQuarantinedIp': 'IP Quarantine', - 'Shutdown': 'Shutdown', + 'Shutdown': 'Management', 'addObjectStoragePool': 'Object Store', 'listObjectStoragePools': 'Object Store', 'deleteObjectStoragePool': 'Object Store', @@ -276,7 +243,6 @@ known_categories = { 'deleteBucket': 'Object Store', 'listBuckets': 'Object Store', 'listVmsForImport': 'Virtual Machine', - 'importVm': 'Virtual Machine', 'SharedFS': 'Shared FileSystem', 'SharedFileSystem': 'Shared FileSystem', 'Webhook': 'Webhook', @@ -297,12 +263,19 @@ categories = {} def choose_category(fn): + possible_known_categories = [] for k, v in known_categories.items(): if k in fn: - return v + possible_known_categories.append(k) + + if len(possible_known_categories) > 0: + close_matches = difflib.get_close_matches(fn, possible_known_categories, n=1, cutoff=0.1) + if len(close_matches) > 0: + return known_categories[close_matches[0]] + else: + return known_categories[possible_known_categories[0]] raise Exception('Need to add a category for %s to %s:known_categories' % (fn, __file__)) - sys.exit(1) for f in sys.argv: @@ -353,7 +326,6 @@ def xml_for(command): def write_xml(out, user): with open(out, 'w') as f: cat_strings = [] - for category in categories.keys(): strings = [] for command in categories[category]: diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 995eca784ce..0494e9ae0da 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -19,8 +19,7 @@ FROM ubuntu:22.04 -MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.20.0.0-SNAPSHOT" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.20.0.0-SNAPSHOT" Author="Apache CloudStack " ARG DEBIAN_FRONTEND=noninteractive diff --git a/tools/docker/Dockerfile.marvin b/tools/docker/Dockerfile.marvin index 7ce0b629f96..b227e92e608 100644 --- a/tools/docker/Dockerfile.marvin +++ b/tools/docker/Dockerfile.marvin @@ -19,8 +19,7 @@ # build for cloudstack_home_dir not this folder FROM python:2 -MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.20.0.0-SNAPSHOT" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.20.0.0-SNAPSHOT" Author="Apache CloudStack " ENV WORK_DIR=/marvin diff --git a/tools/docker/Dockerfile.smokedev b/tools/docker/Dockerfile.smokedev index 4476f6a3d5f..f929294c2ce 100644 --- a/tools/docker/Dockerfile.smokedev +++ b/tools/docker/Dockerfile.smokedev @@ -19,8 +19,7 @@ FROM ubuntu:16.04 -MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.12.0-SNAPSHOT" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.20.0-SNAPSHOT" Author="Apache CloudStack " RUN apt-get -y update && apt-get install -y \ genisoimage \ diff --git a/ui/Dockerfile b/ui/Dockerfile index d636ae5657e..f5556234e19 100644 --- a/ui/Dockerfile +++ b/ui/Dockerfile @@ -19,11 +19,11 @@ FROM node:14-bullseye AS build -MAINTAINER "Apache CloudStack" LABEL Description="Apache CloudStack UI; Modern role-base progressive UI for Apache CloudStack" LABEL Vendor="Apache.org" LABEL License=ApacheV2 LABEL Version=0.5.0 +LABEL Author="Apache CloudStack " WORKDIR /build diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index f709c73e51a..eb1be420b2e 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -532,7 +532,7 @@ "label.complete": "Complete", "label.compute": "Compute", "label.compute.offerings": "Compute offerings", -"label.compute.offering.for.vm": "Compute offering for VM", +"label.compute.offering.for.sharedfs.instance": "Compute offering for Instance", "label.computeonly.offering": "Compute only disk offering", "label.computeonly.offering.tooltip": "Option to specify root disk related information in the compute offering or to directly link a disk offering to the compute offering", "label.conditions": "Conditions", @@ -978,7 +978,7 @@ "label.filename": "File Name", "label.fetched": "Fetched", "label.files": "Alternate files to retrieve", -"label.sharedfs": "Shared FileSystem", +"label.shared.filesystems": "Shared FileSystems", "label.filesystem": "Filesystem", "label.filter": "Filter", "label.filter.annotations.all": "All comments", @@ -2691,7 +2691,7 @@ "message.action.remove.routing.policy": "Please confirm that you want to remove Routing Policy from this Network", "message.action.release.reserved.ip": "Please confirm that you want to release this reserved IP.", "message.action.reserve.ip": "Please confirm that you want to reserve this IP.", -"message.action.restart.sharedfs": "Please confirm that you want to restart this Shared FileSystem. This will cause a downtime to the user.
Restart with cleanup will re-initialize the Shared FileSystem VM without affecting the installed file system.", +"message.action.restart.sharedfs": "Please confirm that you want to restart this Shared FileSystem. This will cause a downtime to the user.
Restart with cleanup will re-initialize the Shared FileSystem Instance without affecting the installed file system.", "message.action.revert.snapshot": "Please confirm that you want to revert the owning volume to this Snapshot.", "message.action.router.health.checks": "Health checks result will be fetched from router.", "message.action.router.health.checks.disabled.warning": "Please enable router health checks.", diff --git a/ui/src/components/header/ProjectMenu.vue b/ui/src/components/header/ProjectMenu.vue index e2f365344d9..6fb0c3af350 100644 --- a/ui/src/components/header/ProjectMenu.vue +++ b/ui/src/components/header/ProjectMenu.vue @@ -81,7 +81,7 @@ export default { const projects = [] const getNextPage = () => { this.loading = true - api('listProjects', { listAll: true, page: page, pageSize: 500, showIcon: true }).then(json => { + api('listProjects', { listAll: true, page: page, pageSize: 500, details: 'min', showIcon: true }).then(json => { if (json?.listprojectsresponse?.project) { projects.push(...json.listprojectsresponse.project) } diff --git a/ui/src/components/page/GlobalHeader.vue b/ui/src/components/page/GlobalHeader.vue index dd51278b483..47a79613776 100644 --- a/ui/src/components/page/GlobalHeader.vue +++ b/ui/src/components/page/GlobalHeader.vue @@ -26,7 +26,7 @@ - + @@ -45,7 +45,7 @@ - + diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index c6d16d6ea78..5a82c1ce48a 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -222,7 +222,7 @@ export default { docHelp: 'adminguide/virtual_machines.html#backup-offerings', dataView: true, args: ['virtualmachineid', 'backupofferingid'], - show: (record) => { return !record.backupofferingid && record.vmtype !== 'sharedfsvm' }, + show: (record) => { return !record.backupofferingid }, mapping: { virtualmachineid: { value: (record, params) => { return record.id } @@ -237,7 +237,7 @@ export default { docHelp: 'adminguide/virtual_machines.html#creating-vm-backups', dataView: true, args: ['virtualmachineid'], - show: (record) => { return record.backupofferingid && record.vmtype !== 'sharedfsvm' }, + show: (record) => { return record.backupofferingid }, mapping: { virtualmachineid: { value: (record, params) => { return record.id } @@ -251,7 +251,7 @@ export default { docHelp: 'adminguide/virtual_machines.html#creating-vm-backups', dataView: true, popup: true, - show: (record) => { return record.backupofferingid && record.vmtype !== 'sharedfsvm' }, + show: (record) => { return record.backupofferingid }, component: shallowRef(defineAsyncComponent(() => import('@/views/compute/BackupScheduleWizard.vue'))), mapping: { virtualmachineid: { @@ -270,7 +270,7 @@ export default { docHelp: 'adminguide/virtual_machines.html#restoring-vm-backups', dataView: true, args: ['virtualmachineid', 'forced'], - show: (record) => { return record.backupofferingid && record.vmtype !== 'sharedfsvm' }, + show: (record) => { return record.backupofferingid }, mapping: { virtualmachineid: { value: (record, params) => { return record.id } diff --git a/ui/src/config/section/storage.js b/ui/src/config/section/storage.js index d979e7395e0..5a50cb0b1dd 100644 --- a/ui/src/config/section/storage.js +++ b/ui/src/config/section/storage.js @@ -546,7 +546,7 @@ export default { }, { name: 'sharedfs', - title: 'label.sharedfs', + title: 'label.shared.filesystems', icon: 'file-text-outlined', permission: ['listSharedFileSystems'], resourceType: 'SharedFS', diff --git a/ui/src/style/objects/form.scss b/ui/src/style/objects/form.scss index ba56694ed38..1789e03717b 100644 --- a/ui/src/style/objects/form.scss +++ b/ui/src/style/objects/form.scss @@ -18,11 +18,19 @@ .form { width: 80vw; - .full-width-input { - width: 100%; - } - @media (min-width: 500px) { - width: 400px; + width: fit-content; + min-width: 20vw; } } + +.form textarea { + resize: both; + min-width: 20vw; + max-width: 80vw; +} + +.ant-input-number, +.ant-calendar-picker { + width: 100%; +} diff --git a/ui/src/views/iam/DomainActionForm.vue b/ui/src/views/iam/DomainActionForm.vue index 4d7c727d49e..ab53a5974e4 100644 --- a/ui/src/views/iam/DomainActionForm.vue +++ b/ui/src/views/iam/DomainActionForm.vue @@ -237,6 +237,11 @@ export default { const resourceName = params.displayname || params.displaytext || params.name || this.resource.name let hasJobId = false + Object.keys(params).forEach(key => { + if (params[key] === '') { + delete params[key] + } + }) api(this.action.api, params).then(json => { for (const obj in json) { if (obj.includes('response')) { diff --git a/ui/src/views/network/VpcTiersTab.vue b/ui/src/views/network/VpcTiersTab.vue index c2bbfe53e38..e9eaddf149e 100644 --- a/ui/src/views/network/VpcTiersTab.vue +++ b/ui/src/views/network/VpcTiersTab.vue @@ -591,7 +591,7 @@ export default { }).then(async json => { var lbNetworks = json.listnetworksresponse.network || [] if (lbNetworks.length > 0) { - this.publicLBExists = true + this.publicLBExists = false for (var idx = 0; idx < lbNetworks.length; idx++) { const lbNetworkOffering = await this.getNetworkOffering(lbNetworks[idx].networkofferingid) const index = lbNetworkOffering.service.map(svc => { return svc.name }).indexOf('Lb') @@ -618,16 +618,23 @@ export default { api('listNetworkOfferings', params).then(json => { this.networkOfferings = json.listnetworkofferingsresponse.networkoffering || [] var filteredOfferings = [] - if (this.publicLBExists) { - for (var index in this.networkOfferings) { - const offering = this.networkOfferings[index] - const idx = offering.service.map(svc => { return svc.name }).indexOf('Lb') - if (idx === -1 || this.lbProviderMap.publicLb.vpc.indexOf(offering.service.map(svc => { return svc.provider[0].name })[idx]) === -1) { + const vpcLbServiceIndex = this.resource.service.map(svc => { return svc.name }).indexOf('Lb') + for (var index in this.networkOfferings) { + const offering = this.networkOfferings[index] + const idx = offering.service.map(svc => { return svc.name }).indexOf('Lb') + if (this.publicLBExists && (idx === -1 || this.lbProviderMap.publicLb.vpc.indexOf(offering.service.map(svc => { return svc.provider[0].name })[idx]) === -1)) { + filteredOfferings.push(offering) + } else if (!this.publicLBExists && vpcLbServiceIndex > -1) { + const vpcLbServiceProvider = vpcLbServiceIndex === -1 ? undefined : this.resource.service[vpcLbServiceIndex].provider[0].name + const offeringLbServiceProvider = idx === -1 ? undefined : offering.service[idx].provider[0].name + if (vpcLbServiceProvider && (!offeringLbServiceProvider || (offeringLbServiceProvider && vpcLbServiceProvider === offeringLbServiceProvider))) { filteredOfferings.push(offering) } + } else { + filteredOfferings.push(offering) } - this.networkOfferings = filteredOfferings } + this.networkOfferings = filteredOfferings if (this.isNsxEnabled) { this.networkOfferings = this.networkOfferings.filter(offering => offering.networkmode === (this.isOfferingNatMode ? 'NATTED' : 'ROUTED')) } diff --git a/ui/src/views/storage/CreateSharedFS.vue b/ui/src/views/storage/CreateSharedFS.vue index 6cfc8f7a6bd..4f5b1d9da68 100644 --- a/ui/src/views/storage/CreateSharedFS.vue +++ b/ui/src/views/storage/CreateSharedFS.vue @@ -151,7 +151,7 @@ updatedControllerInfo = new Pair(newRootDiskController, newDataDiskController); - String scsiDiskController = HypervisorHostHelper.getScsiController(updatedControllerInfo, recommendedController); + Pair chosenDiskControllers = VmwareHelper.chooseRequiredDiskControllers(controllerInfo, null, host, guestOsIdentifier); + String scsiDiskController = HypervisorHostHelper.getScsiController(chosenDiskControllers); // If there is requirement for a SCSI controller, ensure to create those. if (scsiDiskController != null) { int busNum = 0; @@ -2256,19 +2249,11 @@ public class HypervisorHostHelper { return morHyperHost; } - public static String getScsiController(Pair controllerInfo, String recommendedController) { + public static String getScsiController(Pair controllerInfo) { String rootDiskController = controllerInfo.first(); String dataDiskController = controllerInfo.second(); - // If "osdefault" is specified as controller type, then translate to actual recommended controller. - if (VmwareHelper.isControllerOsRecommended(rootDiskController)) { - rootDiskController = recommendedController; - } - if (VmwareHelper.isControllerOsRecommended(dataDiskController)) { - dataDiskController = recommendedController; - } - - String scsiDiskController = null; //If any of the controller provided is SCSI then return it's sub-type. + String scsiDiskController; //If any of the controller provided is SCSI then return it's sub-type. if (isIdeController(rootDiskController) && isIdeController(dataDiskController)) { //Default controllers would exist return null; diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java index 962469c9535..9a6457017d7 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java @@ -40,11 +40,14 @@ import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; +import com.cloud.agent.api.to.DiskTO; import com.cloud.hypervisor.vmware.mo.ClusterMO; import com.cloud.hypervisor.vmware.mo.DatastoreFile; import com.cloud.hypervisor.vmware.mo.DistributedVirtualSwitchMO; import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper; import com.cloud.serializer.GsonHelper; +import com.cloud.storage.Volume; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.vmware.vim25.DatastoreInfo; import com.vmware.vim25.DistributedVirtualPort; @@ -1064,4 +1067,76 @@ public class VmwareHelper { } return vmdkAbsFile; } + + /** + * Validates an instance's rootDiskController and dataDiskController details. Throws a + * CloudRuntimeException if they are invalid. + */ + public static void validateDiskControllerDetails(String rootDiskControllerDetail, String dataDiskControllerDetail) { + rootDiskControllerDetail = DiskControllerType.getType(rootDiskControllerDetail).toString(); + if (DiskControllerType.getType(rootDiskControllerDetail) == DiskControllerType.none) { + throw new CloudRuntimeException(String.format("[%s] is not a valid root disk controller", rootDiskControllerDetail)); + } + dataDiskControllerDetail = DiskControllerType.getType(dataDiskControllerDetail).toString(); + if (DiskControllerType.getType(dataDiskControllerDetail) == DiskControllerType.none) { + throw new CloudRuntimeException(String.format("[%s] is not a valid data disk controller", dataDiskControllerDetail)); + } + } + + /** + * Based on an instance's rootDiskController and dataDiskController details, returns a pair + * containing the disk controllers that should be used for root disk and the data disks, respectively. + * + * @param controllerInfo pair containing the root disk and data disk controllers, respectively. + * @param vmMo virtual machine to derive the recommended disk controllers from. If not null, host and guestOsIdentifier will be ignored. + * @param host host to derive the recommended disk controllers from. Must be provided with guestOsIdentifier. + * @param guestOsIdentifier used to derive the recommended disk controllers from the host. + */ + public static Pair chooseRequiredDiskControllers(Pair controllerInfo, VirtualMachineMO vmMo, + VmwareHypervisorHost host, String guestOsIdentifier) throws Exception { + String recommendedDiskControllerClassName = vmMo != null ? vmMo.getRecommendedDiskController(null) : host.getRecommendedDiskController(guestOsIdentifier); + String recommendedDiskController = DiskControllerType.getType(recommendedDiskControllerClassName).toString(); + + String convertedRootDiskController = controllerInfo.first(); + if (isControllerOsRecommended(convertedRootDiskController)) { + convertedRootDiskController = recommendedDiskController; + } + + String convertedDataDiskController = controllerInfo.second(); + if (isControllerOsRecommended(convertedDataDiskController)) { + convertedDataDiskController = recommendedDiskController; + } + + if (diskControllersShareTheSameBusType(convertedRootDiskController, convertedDataDiskController)) { + LOGGER.debug("Root and data disk controllers share the same bus type; therefore, we will only use the controllers specified for the root disk."); + return new Pair<>(convertedRootDiskController, convertedRootDiskController); + } + + return new Pair<>(convertedRootDiskController, convertedDataDiskController); + } + + protected static boolean diskControllersShareTheSameBusType(String rootDiskController, String dataDiskController) { + DiskControllerType rootDiskControllerType = DiskControllerType.getType(rootDiskController); + DiskControllerType dataDiskControllerType = DiskControllerType.getType(dataDiskController); + if (rootDiskControllerType.equals(dataDiskControllerType)) { + return true; + } + List scsiDiskControllers = List.of(DiskControllerType.scsi, DiskControllerType.lsilogic, DiskControllerType.lsisas1068, + DiskControllerType.buslogic ,DiskControllerType.pvscsi); + return scsiDiskControllers.contains(rootDiskControllerType) && scsiDiskControllers.contains(dataDiskControllerType); + } + + /** + * Identifies whether the disk is a root or data disk, and returns the controller from the provided pair that should + * be used for the disk. + * @param controllerInfo pair containing the root disk and data disk controllers, respectively. + */ + public static String getControllerBasedOnDiskType(Pair controllerInfo, DiskTO disk) { + if (disk.getType() == Volume.Type.ROOT || disk.getDiskSeq() == 0) { + LOGGER.debug(String.format("Choosing disk controller [%s] for the root disk.", controllerInfo.first())); + return controllerInfo.first(); + } + LOGGER.debug(String.format("Choosing disk controller [%s] for the data disks.", controllerInfo.second())); + return controllerInfo.second(); + } }