Eldan Shachar has uploaded a new change for review. Change subject: core: Editing of template version for stateless VMs and pools ......................................................................
core: Editing of template version for stateless VMs and pools This patch will allow a user to change a template version for an existing stateless VM / Pool. The main issues handled are: - VM \ Pool object - added support for changing of the template field. - Frontend - Added support for editing of this field and introduced some limitations to avoid non-supported behaviors. - UpdateVmVersion Command - added support for any template versions. - Pools - Until now pools haven't supported changes affecting the actual VMs and some logic that depended on this assumption needed change. - Running VMs - Changes were required in the next-run logic on multiple locations. Change-Id: Ib106016955c702bc28f9347d828c4602e47bd233 Bug-Url: https://bugzilla.redhat.com/1140569 Signed-off-by: Eldan Shachar <[email protected]> --- A backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/EditableOnStatelessVmField.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmPool.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmStatic.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java M backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDAO.java M backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDAODbFacadeImpl.java M backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmPoolDAODbFacadeImpl.java M backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties M backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmPoolDAOTest.java M backend/manager/modules/dal/src/test/resources/fixtures.xml M backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ObjectIdentityChecker.java M backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/ObjectIdentityCheckerTest.java M frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java M frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties M frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties M packaging/dbscripts/create_views.sql A packaging/dbscripts/upgrade/03_06_0700_add_template_id_to_pool.sql M packaging/dbscripts/vm_pools_sp.sql M packaging/dbscripts/vm_templates_sp.sql M packaging/dbscripts/vms_sp.sql 20 files changed, 168 insertions(+), 34 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/07/36507/1 diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/EditableOnStatelessVmField.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/EditableOnStatelessVmField.java new file mode 100644 index 0000000..42030bf --- /dev/null +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/EditableOnStatelessVmField.java @@ -0,0 +1,12 @@ +package org.ovirt.engine.core.common.businessentities; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface EditableOnStatelessVmField { + +} diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmPool.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmPool.java index 5b11cdd..65dfd20 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmPool.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmPool.java @@ -38,6 +38,10 @@ private Guid vdsGroupId; + private Guid vmtGuid; + + private boolean useLatestVersion; + private int prestartedVms; private int defaultTimeInDays; @@ -89,6 +93,8 @@ result = prime * result + vmPoolRunningCount; result = prime * result + ((type == null) ? 0 : type.hashCode()); result = prime * result + maxAssignedVmsPerUser; + result = prime * result + ((vmtGuid == null) ? 0 : vmtGuid.hashCode()); + result = prime * result + (useLatestVersion ? 1249 : 1259); return result; } @@ -113,7 +119,9 @@ && ObjectUtils.objectsEqual(description, other.description) && ObjectUtils.objectsEqual(name, other.name) && ObjectUtils.objectsEqual(type, other.type) - && maxAssignedVmsPerUser == other.maxAssignedVmsPerUser); + && maxAssignedVmsPerUser == other.maxAssignedVmsPerUser + && ObjectUtils.objectsEqual(vmtGuid, other.vmtGuid)) + && useLatestVersion == other.useLatestVersion; } public String getParameters() { @@ -249,4 +257,20 @@ public String getSpiceProxy() { return spiceProxy; } + + public Guid getVmtGuid() { + return vmtGuid; + } + + public void setVmtGuid(Guid vmtGuid) { + this.vmtGuid = vmtGuid; + } + + public boolean isUseLatestVersion() { + return useLatestVersion; + } + + public void setUseLatestVersion(boolean useLatestVersion) { + this.useLatestVersion = useLatestVersion; + } } diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmStatic.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmStatic.java index 0f04626..3ce326a 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmStatic.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmStatic.java @@ -14,6 +14,7 @@ public class VmStatic extends VmBase { private static final long serialVersionUID = -2753306386502558044L; + @EditableOnStatelessVmField private Guid vmtGuid; private boolean initialized; diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java index 297e153..dcada98 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java @@ -227,6 +227,7 @@ ACTION_TYPE_FAILED_CANNOT_REMOVE_IMAGE_TEMPLATE(ErrorType.CONFLICT), ACTION_TYPE_FAILED_CPU_NOT_FOUND(ErrorType.BAD_PARAMETERS), ACTION_TYPE_FAILED_TEMPLATE_DOES_NOT_EXIST(ErrorType.BAD_PARAMETERS), + ACTION_TYPE_FAILED_TEMPLATE_IS_ON_DIFFERENT_CHAIN(ErrorType.BAD_PARAMETERS), ACTION_TYPE_FAILED_CLUSTER_CAN_NOT_BE_EMPTY(ErrorType.BAD_PARAMETERS), ACTION_TYPE_FAILED_TEMPLATE_VERSION_CANNOT_BE_BASE_TEMPLATE(ErrorType.BAD_PARAMETERS), ACTION_TYPE_FAILED_TEMPLATE_CANNOT_BE_CREATED_WITH_EMPTY_DISK_ALIAS(ErrorType.BAD_PARAMETERS), diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDAO.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDAO.java index 1caca5ff..d73f815 100644 --- a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDAO.java +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDAO.java @@ -221,6 +221,13 @@ List<VM> getAll(); /** + * Retrieves the list of all VMS from a given pool. + * + * @return the list of all VMs in the pool + */ + List<VM> getPoolVms(Guid poolId); + + /** * Saves the is_initialized property of the VM. * * @param vmid diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDAODbFacadeImpl.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDAODbFacadeImpl.java index d9e4cfa..1acba05 100644 --- a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDAODbFacadeImpl.java +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDAODbFacadeImpl.java @@ -196,6 +196,14 @@ return getAll(null, false); } + @Override public List<VM> getPoolVms(Guid poolId) { + return getCallsHandler().executeReadList("GetPoolVmsFromVms", + VMRowMapper.instance, + getCustomMapSqlParameterSource().addValue("user_id", null) + .addValue("is_filtered", false) + .addValue("pool_id", poolId)); + } + @Override public List<VM> getAll(Guid userID, boolean isFiltered) { return getCallsHandler().executeReadList("GetAllFromVms", @@ -328,6 +336,20 @@ } } + static final class VMPoolRowMapper implements RowMapper<VM> { + public static final VMPoolRowMapper instance = new VMPoolRowMapper(); + + @Override + public VM mapRow(ResultSet rs, int rowNum) throws SQLException { + VM entity = VMRowMapper.instance.mapRow(rs, rowNum); + if (entity != null) { + entity.setVmtGuid(getGuidDefaultEmpty(rs, "vm_pool_vmt_guid")); + entity.setUseLatestVersion(rs.getBoolean("vm_pool_is_latest")); + } + return entity; + } + } + private static final class VMWithPlugInfoRowMapper implements RowMapper<Pair<VM, VmDevice>> { public static final VMWithPlugInfoRowMapper instance = new VMWithPlugInfoRowMapper(); diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmPoolDAODbFacadeImpl.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmPoolDAODbFacadeImpl.java index b02f583..f08ede2 100644 --- a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmPoolDAODbFacadeImpl.java +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmPoolDAODbFacadeImpl.java @@ -10,7 +10,7 @@ import org.ovirt.engine.core.common.businessentities.VmPoolMap; import org.ovirt.engine.core.common.businessentities.VmPoolType; import org.ovirt.engine.core.compat.Guid; -import org.ovirt.engine.core.dao.VmDAODbFacadeImpl.VMRowMapper; +import org.ovirt.engine.core.dao.VmDAODbFacadeImpl.VMPoolRowMapper; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; @@ -85,7 +85,9 @@ .addValue("prestarted_vms", pool.getPrestartedVms()) .addValue("vds_group_id", pool.getVdsGroupId()) .addValue("max_assigned_vms_per_user", pool.getMaxAssignedVmsPerUser()) - .addValue("spice_proxy", pool.getSpiceProxy()); + .addValue("spice_proxy", pool.getSpiceProxy()) + .addValue("vm_pool_vmt_guid", pool.getVmtGuid()) + .addValue("vm_pool_is_latest", pool.isUseLatestVersion()); getCallsHandler().executeModification("InsertVm_pools", parameterSource); } @@ -102,7 +104,9 @@ .addValue("prestarted_vms", pool.getPrestartedVms()) .addValue("vds_group_id", pool.getVdsGroupId()) .addValue("max_assigned_vms_per_user", pool.getMaxAssignedVmsPerUser()) - .addValue("spice_proxy", pool.getSpiceProxy()); + .addValue("spice_proxy", pool.getSpiceProxy()) + .addValue("vm_pool_vmt_guid", pool.getVmtGuid()) + .addValue("vm_pool_is_latest", pool.isUseLatestVersion()); getCallsHandler().executeModification("UpdateVm_pools", parameterSource); } @@ -161,6 +165,8 @@ entity.setRunningVmsCount(rs.getInt("vm_running_count")); entity.setMaxAssignedVmsPerUser(rs.getInt("max_assigned_vms_per_user")); entity.setSpiceProxy(rs.getString("spice_proxy")); + entity.setVmtGuid(getGuidDefaultEmpty(rs, "vm_pool_vmt_guid")); + entity.setUseLatestVersion(rs.getBoolean("vm_pool_is_latest")); return entity; } } @@ -184,6 +190,8 @@ entity.setVdsGroupName(rs.getString("vds_group_name")); entity.setMaxAssignedVmsPerUser(rs.getInt("max_assigned_vms_per_user")); entity.setSpiceProxy(rs.getString("spice_proxy")); + entity.setVmtGuid(getGuidDefaultEmpty(rs, "vm_pool_vmt_guid")); + entity.setUseLatestVersion(rs.getBoolean("vm_pool_is_latest")); return entity; } } @@ -204,13 +212,13 @@ public VM getVmDataFromPoolByPoolGuid(Guid vmPoolId, Guid userID, boolean isFiltered) { MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource() .addValue("pool_id", vmPoolId).addValue("user_id", userID).addValue("is_filtered", isFiltered); - return getCallsHandler().executeRead("GetVmDataFromPoolByPoolId", VMRowMapper.instance, parameterSource); + return getCallsHandler().executeRead("GetVmDataFromPoolByPoolId", VMPoolRowMapper.instance, parameterSource); } @Override public VM getVmDataFromPoolByPoolName(String vmPoolName, Guid userId, boolean isFiltered) { MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource() .addValue("pool_name", vmPoolName).addValue("user_id", userId).addValue("is_filtered", isFiltered); - return getCallsHandler().executeRead("GetVmDataFromPoolByPoolName", VMRowMapper.instance, parameterSource); + return getCallsHandler().executeRead("GetVmDataFromPoolByPoolName", VMPoolRowMapper.instance, parameterSource); } } diff --git a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties index 43c2193..c48ce49 100644 --- a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties +++ b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties @@ -250,6 +250,7 @@ ACTION_TYPE_FAILED_PROBLEM_WITH_CANDIDATE_INFO=Cannot ${action} ${type}. Failed to get data for Import operation.\n\ - Check your Import Domain. ACTION_TYPE_FAILED_TEMPLATE_DOES_NOT_EXIST=Cannot ${action} ${type}. The relevant Template doesn't exist. +ACTION_TYPE_FAILED_TEMPLATE_IS_ON_DIFFERENT_CHAIN=Cannot ${action} ${type}. The requested template doesn't belong to the same base template as the original template. ACTION_TYPE_FAILED_CLUSTER_CAN_NOT_BE_EMPTY=Cannot ${action} ${type}. The relevant Cluster doesn't exist. ACTION_TYPE_FAILED_TEMPLATE_VERSION_CANNOT_BE_BASE_TEMPLATE=Cannot ${action} ${type}. Only the first template version can be selected as the base template. ACTION_TYPE_FAILED_INSTANCE_TYPE_DOES_NOT_EXIST=Cannot ${action} ${type}. The relevant Instance Type doesn't exist. diff --git a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmPoolDAOTest.java b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmPoolDAOTest.java index 28e6b6b..253138f 100644 --- a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmPoolDAOTest.java +++ b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmPoolDAOTest.java @@ -22,6 +22,7 @@ private static final Guid EXISTING_VM_POOL_ID = new Guid("103cfd1d-18b1-4790-8a0c-1e52621b0076"); private static final Guid FREE_VM_ID = new Guid("77296e00-0cad-4e5a-9299-008a7b6f4356"); private static final Guid EXISTING_VM_ID = new Guid("77296e00-0cad-4e5a-9299-008a7b6f4355"); + private static final Guid POOL_TEMPLATE_ID = new Guid("12346e00-0cad-4e5a-9299-008a7b6f4355"); private static final int VM_POOL_COUNT = 3; private VmPoolDAO dao; private VmPool existingVmPool; @@ -44,6 +45,7 @@ newVmPool.setName("New VM Pool"); newVmPool.setVmPoolDescription("This is a new VM pool."); newVmPool.setVdsGroupId(VDS_GROUP_ID); + newVmPool.setVmtGuid(POOL_TEMPLATE_ID); newVmPoolMap = new VmPoolMap(FREE_VM_ID, EXISTING_VM_POOL_ID); } diff --git a/backend/manager/modules/dal/src/test/resources/fixtures.xml b/backend/manager/modules/dal/src/test/resources/fixtures.xml index d54c080..fb5867a 100644 --- a/backend/manager/modules/dal/src/test/resources/fixtures.xml +++ b/backend/manager/modules/dal/src/test/resources/fixtures.xml @@ -1711,6 +1711,8 @@ <column>vds_group_id</column> <column>max_assigned_vms_per_user</column> <column>spice_proxy</column> + <column>vm_pool_vmt_guid</column> + <column>vm_pool_is_latest</column> <row> <value>103cfd1d-18b1-4790-8a0c-1e52621b0076</value> <value>fedora13-pool</value> @@ -1721,6 +1723,8 @@ <value>b399944a-81ab-4ec5-8266-e19ba7c3c9d1</value> <value>1</value> <null/> + <null/> + <value>false</value> </row> <row> <value>103cfd1d-18b1-4790-8a0c-1e52621b0077</value> @@ -1732,6 +1736,8 @@ <value>b399944a-81ab-4ec5-8266-e19ba7c3c9d1</value> <value>1</value> <null/> + <value>1b85420c-b84c-4f29-997e-0eb674b40b79</value> + <value>false</value> </row> <row> <value>103cfd1d-18b1-4790-8a0c-1e52621b0078</value> @@ -1743,6 +1749,8 @@ <value>b399944a-81ab-4ec5-8266-e19ba7c3c9d1</value> <value>1</value> <null/> + <value>1b85420c-b84c-4f29-997e-0eb674b40b79</value> + <value>true</value> </row> </table> <table name="vds_static"> diff --git a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ObjectIdentityChecker.java b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ObjectIdentityChecker.java index a9775da..3e031c2 100644 --- a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ObjectIdentityChecker.java +++ b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ObjectIdentityChecker.java @@ -27,6 +27,7 @@ new HashMap<Enum<?>, Set<String>>(); private Set<String> permitted = new HashSet<String>(); private Set<String> hotsetAllowedFields = new HashSet<String>(); + private Set<String> statelessAllowedFields = new HashSet<String>(); public ObjectIdentityChecker(Class<?> type) { identities.put(type, this); @@ -92,6 +93,12 @@ } } + public final void AddStatelessFields(String... fieldNames) { + for (String fieldName : fieldNames) { + statelessAllowedFields.add(fieldName); + } + } + public final boolean IsFieldUpdatable(String name) { return permitted.contains(name); } @@ -101,10 +108,10 @@ } public boolean IsFieldUpdatable(Enum<?> status, String name, Object fieldContainer) { - return IsFieldUpdatable(status, name, fieldContainer, false); + return IsFieldUpdatable(status, name, fieldContainer, false, false); } - public boolean IsFieldUpdatable(Enum<?> status, String name, Object fieldContainer, boolean hotsetEnabled) { + public boolean IsFieldUpdatable(Enum<?> status, String name, Object fieldContainer, boolean hotsetEnabled, boolean statelessEnabled) { boolean returnValue = true; if (!IsFieldUpdatable(name)) { if (fieldContainer != null && container != null @@ -114,9 +121,9 @@ Set<String> values = dictionary.get(status); returnValue = values != null ? values.contains(name) : false; - // if field is not updateable in this status, check if hotset request and its an hotset allowed field - if (!returnValue && hotsetEnabled) { - returnValue = isHotSetField(name); + // if field is not updateable in this status, check if it's a hotset \ stateless request + if (!returnValue && (hotsetEnabled || statelessEnabled)) { + returnValue = isHotSetField(name) || isStatelessField(name); } } if (!returnValue) { @@ -124,6 +131,10 @@ } } return returnValue; + } + + private boolean isStatelessField(String name) { + return hotsetAllowedFields.contains(name); } /** @@ -173,15 +184,15 @@ } public final boolean IsUpdateValid(Object source, Object destination, Enum<?> status) { - return IsUpdateValid(source, destination, status, false); + return IsUpdateValid(source, destination, status, false, false); } - public final boolean IsUpdateValid(Object source, Object destination, Enum<?> status, boolean hotsetEnabled) { + public final boolean IsUpdateValid(Object source, Object destination, Enum<?> status, boolean hotsetEnabled, boolean statelessEnabled) { if (source.getClass() != destination.getClass()) { return false; } for (String fieldName : GetChangedFields(source, destination)) { - if (!IsFieldUpdatable(status, fieldName, null, hotsetEnabled)) { + if (!IsFieldUpdatable(status, fieldName, null, hotsetEnabled, statelessEnabled)) { log.warn("ObjectIdentityChecker.IsUpdateValid:: Not updatable field '{}' was updated", fieldName); return false; @@ -196,7 +207,7 @@ return fields; } for (String fieldName : GetChangedFields(source, destination)) { - if (!IsFieldUpdatable(status, fieldName, null, false)) { + if (!IsFieldUpdatable(status, fieldName, null, false, false)) { fields.add(fieldName); } } diff --git a/backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/ObjectIdentityCheckerTest.java b/backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/ObjectIdentityCheckerTest.java index 0bb62a3..b75014a 100644 --- a/backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/ObjectIdentityCheckerTest.java +++ b/backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/ObjectIdentityCheckerTest.java @@ -54,7 +54,7 @@ public void testHotsetUpdateableWhenHotsetRequested() { ObjectIdentityChecker oic = new ObjectIdentityChecker(Jedi.class); oic.AddHotsetFields("name"); - assertTrue("hot set requested for hot set fields should be true", oic.IsFieldUpdatable(null, "name", null, true)); + assertTrue("hot set requested for hot set fields should be true", oic.IsFieldUpdatable(null, "name", null, true, false)); } @Test @@ -62,7 +62,7 @@ ObjectIdentityChecker oic = new ObjectIdentityChecker(Jedi.class); assertFalse("Should be false by default", oic.IsFieldUpdatable("name")); oic.AddHotsetFields("name"); - assertFalse("hot set not requested should return false even if field is hot set", oic.IsFieldUpdatable(null, "name", null, false)); + assertFalse("hot set not requested should return false even if field is hot set", oic.IsFieldUpdatable(null, "name", null, false, false)); } @Test @@ -70,7 +70,7 @@ ObjectIdentityChecker oic = new ObjectIdentityChecker(Jedi.class); oic.AddField(VMStatus.Down, "name"); oic.AddHotsetFields("name"); - assertTrue("hot set requested for hot set fields should be true", oic.IsFieldUpdatable(VMStatus.Down, "name", null, true)); + assertTrue("hot set requested for hot set fields should be true", oic.IsFieldUpdatable(VMStatus.Down, "name", null, true, false)); } @Test @@ -78,6 +78,6 @@ ObjectIdentityChecker oic = new ObjectIdentityChecker(Jedi.class); oic.AddField(VMStatus.Down, "name"); oic.AddHotsetFields("name"); - assertTrue("hot set not requested field should be updateable according to status", oic.IsFieldUpdatable(VMStatus.Down, "name", null, false)); + assertTrue("hot set not requested field should be updateable according to status", oic.IsFieldUpdatable(VMStatus.Down, "name", null, false, false)); } } diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java index 1ca5952..94d04f6 100644 --- a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java @@ -676,6 +676,9 @@ @DefaultStringValue("Cannot ${action} ${type}. The relevant Template doesn't exist.") String ACTION_TYPE_FAILED_TEMPLATE_DOES_NOT_EXIST(); + @DefaultStringValue("Cannot ${action} ${type}. The requested template doesn't belong to the same base template as the original template.") + String ACTION_TYPE_FAILED_TEMPLATE_IS_ON_DIFFERENT_CHAIN(); + @DefaultStringValue("Cannot ${action} ${type}. The relevant Cluster doesn't exist.") String ACTION_TYPE_FAILED_CLUSTER_CAN_NOT_BE_EMPTY(); diff --git a/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties b/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties index 23c3cde..d6418a3 100644 --- a/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties +++ b/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties @@ -232,6 +232,7 @@ ACTION_TYPE_FAILED_PROBLEM_WITH_CANDIDATE_INFO=Cannot ${action} ${type}. Failed to get data for Import operation.\n\ - Check your Import Domain. ACTION_TYPE_FAILED_TEMPLATE_DOES_NOT_EXIST=Cannot ${action} ${type}. The relevant Template doesn't exist. +ACTION_TYPE_FAILED_TEMPLATE_IS_ON_DIFFERENT_CHAIN=Cannot ${action} ${type}. The requested template doesn't belong to the same base template as the original template. ACTION_TYPE_FAILED_CLUSTER_CAN_NOT_BE_EMPTY=Cannot ${action} ${type}. The relevant Cluster doesn't exist. ACTION_TYPE_FAILED_TEMPLATE_VERSION_CANNOT_BE_BASE_TEMPLATE=Cannot ${action} ${type}. Only the first template version can be selected as the base template. ACTION_TYPE_FAILED_TEMPLATE_CANNOT_BE_CREATED_WITH_EMPTY_DISK_ALIAS=Cannot ${action} ${type} with an empty disk alias. diff --git a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties index a102ceb..08b7877 100644 --- a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties +++ b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties @@ -246,6 +246,7 @@ ACTION_TYPE_FAILED_PROBLEM_WITH_CANDIDATE_INFO=Cannot ${action} ${type}. Failed to get data for Import operation.\n\ - Check your Import Domain. ACTION_TYPE_FAILED_TEMPLATE_DOES_NOT_EXIST=Cannot ${action} ${type}. The relevant Template doesn't exist. +ACTION_TYPE_FAILED_TEMPLATE_IS_ON_DIFFERENT_CHAIN=Cannot ${action} ${type}. The requested template doesn't belong to the same base template as the original template. ACTION_TYPE_FAILED_CLUSTER_CAN_NOT_BE_EMPTY=Cannot ${action} ${type}. The relevant Cluster doesn't exist. ACTION_TYPE_FAILED_TEMPLATE_VERSION_CANNOT_BE_BASE_TEMPLATE=Cannot ${action} ${type}. Only the first template version can be selected as the base template. ACTION_TYPE_FAILED_TEMPLATE_CANNOT_BE_CREATED_WITH_EMPTY_DISK_ALIAS=Cannot ${action} ${type} with an empty disk alias. diff --git a/packaging/dbscripts/create_views.sql b/packaging/dbscripts/create_views.sql index 0224f22..aa7e43c 100644 --- a/packaging/dbscripts/create_views.sql +++ b/packaging/dbscripts/create_views.sql @@ -613,7 +613,9 @@ vm_pool_map.vm_guid as vm_guid, vm_pool_map.vm_pool_id as vm_pool_id, vm_pools.vm_pool_name as vm_pool_name, -vm_pools.spice_proxy as vm_pool_spice_proxy +vm_pools.spice_proxy as vm_pool_spice_proxy, +vm_pools.vm_pool_vmt_guid as vm_pool_vmt_guid, +vm_pools.vm_pool_is_latest as vm_pool_is_latest from vm_pool_map INNER JOIN vm_pools ON vm_pool_map.vm_pool_id = vm_pools.vm_pool_id; @@ -706,7 +708,7 @@ vm_dynamic.guest_last_login_time as guest_last_login_time, vm_dynamic.guest_last_logout_time as guest_last_logout_time, vm_dynamic.guest_os as guest_os, vm_dynamic.console_user_id as console_user_id, vm_dynamic.guest_agent_nics_hash as guest_agent_nics_hash, vm_dynamic.run_on_vds as run_on_vds, vm_dynamic.migrating_to_vds as migrating_to_vds, vm_dynamic.app_list as app_list, vm_dynamic.display as display, vm_dynamic.hibernation_vol_handle as hibernation_vol_handle, - vm_pool_map_view.vm_pool_name as vm_pool_name, vm_pool_map_view.vm_pool_id as vm_pool_id, vm_static.vm_guid as vm_guid, vm_static.num_of_monitors as num_of_monitors, vm_static.single_qxl_pci as single_qxl_pci, vm_static.allow_console_reconnect as allow_console_reconnect, vm_static.is_initialized as is_initialized, + vm_pool_map_view.vm_pool_name as vm_pool_name, vm_pool_map_view.vm_pool_id as vm_pool_id, vm_pool_map_view.vm_pool_vmt_guid as vm_pool_vmt_guid, vm_pool_map_view.vm_pool_is_latest as vm_pool_is_latest, vm_static.vm_guid as vm_guid, vm_static.num_of_monitors as num_of_monitors, vm_static.single_qxl_pci as single_qxl_pci, vm_static.allow_console_reconnect as allow_console_reconnect, vm_static.is_initialized as is_initialized, vm_static.num_of_sockets as num_of_sockets, vm_static.cpu_per_socket as cpu_per_socket, vm_static.usb_policy as usb_policy, vm_dynamic.acpi_enable as acpi_enable, vm_dynamic.session as session, vm_static.num_of_sockets*vm_static.cpu_per_socket as num_of_cpus, vm_static.quota_id as quota_id, quota.quota_name as quota_name, storage_pool.quota_enforcement_type as quota_enforcement_type, @@ -763,7 +765,7 @@ vms.vm_host, vms.vmt_num_of_sockets * vms.vmt_cpu_per_socket AS vmt_num_of_cpus, vms.vm_pid, vms.last_start_time, vms.last_stop_time, vms.guest_cur_user_name, vms.console_cur_user_name, vms.guest_last_login_time, vms.console_user_id, vms.guest_last_logout_time, vms.guest_os, vms.run_on_vds, vms.migrating_to_vds, vms.app_list, vms.display, - vms.hibernation_vol_handle, vms.vm_pool_name, vms.vm_pool_id, vms.vm_guid, vms.num_of_monitors, vms.single_qxl_pci, + vms.hibernation_vol_handle, vms.vm_pool_name, vms.vm_pool_id, vms.vm_pool_vmt_guid, vms.vm_pool_is_latest, vms.vm_guid, vms.num_of_monitors, vms.single_qxl_pci, vms.allow_console_reconnect, vms.is_initialized, vms.num_of_sockets, vms.cpu_per_socket, vms.usb_policy, vms.acpi_enable, vms.session, vms.num_of_sockets * vms.cpu_per_socket AS num_of_cpus, vms.display_ip, vms.display_type, @@ -984,7 +986,7 @@ CREATE OR REPLACE VIEW vm_pools_view AS SELECT vm_pools.vm_pool_id, vm_pools.vm_pool_name, vm_pools.vm_pool_description, vm_pools.vm_pool_comment, vm_pools.vm_pool_type, vm_pools.parameters, vm_pools.prestarted_vms, vm_pools.vds_group_id, vds_groups.name AS vds_group_name, vds_groups.architecture AS architecture, storage_pool.name as storage_pool_name, storage_pool.id as storage_pool_id, vm_pools.max_assigned_vms_per_user as max_assigned_vms_per_user, - vm_pools.spice_proxy as spice_proxy + vm_pools.spice_proxy as spice_proxy, vm_pools.vm_pool_vmt_guid as vm_pool_vmt_guid, vm_pools.vm_pool_is_latest as vm_pool_is_latest FROM vm_pools JOIN vds_groups ON vm_pools.vds_group_id = vds_groups.vds_group_id LEFT JOIN storage_pool ON storage_pool.id = vds_groups.storage_pool_id; @@ -992,7 +994,7 @@ CREATE OR REPLACE VIEW vm_pools_full_view AS - SELECT vmp.vm_pool_id, vmp.vm_pool_name, vmp.vm_pool_description, vmp.vm_pool_comment, vmp.vm_pool_type, vmp.parameters, vmp.prestarted_vms, vmp.vds_group_id, vmp.vds_group_name, vmp.architecture, vmp.max_assigned_vms_per_user, vmp.spice_proxy as spice_proxy, ( SELECT count(vm_pool_map.vm_pool_id) AS expr1 + SELECT vmp.vm_pool_id, vmp.vm_pool_name, vmp.vm_pool_description, vmp.vm_pool_comment, vmp.vm_pool_type, vmp.parameters, vmp.prestarted_vms, vmp.vds_group_id, vmp.vds_group_name, vmp.architecture, vmp.max_assigned_vms_per_user, vmp.spice_proxy as spice_proxy, vmp.vm_pool_vmt_guid as vm_pool_vmt_guid, vmp.vm_pool_is_latest as vm_pool_is_latest, ( SELECT count(vm_pool_map.vm_pool_id) AS expr1 FROM vm_pools_view v1 LEFT JOIN vm_pool_map ON v1.vm_pool_id = vm_pool_map.vm_pool_id AND v1.vm_pool_id = vmp.vm_pool_id) AS assigned_vm_count, ( SELECT count(v2.vm_pool_id) AS expr1 FROM vm_pools v2 diff --git a/packaging/dbscripts/upgrade/03_06_0700_add_template_id_to_pool.sql b/packaging/dbscripts/upgrade/03_06_0700_add_template_id_to_pool.sql new file mode 100644 index 0000000..9c91c94 --- /dev/null +++ b/packaging/dbscripts/upgrade/03_06_0700_add_template_id_to_pool.sql @@ -0,0 +1,7 @@ +SELECT fn_db_add_column('vm_pools', 'vm_pool_vmt_guid', 'uuid'); +SELECT fn_db_add_column('vm_pools', 'vm_pool_is_latest', 'boolean'); + +-- Updating pool with template-id based on vm_static data (at this point it's still safe). +-- From this point on different VMs in a pool may have different template versions (in a NEXT-RUN use case). +UPDATE vm_pools SET vm_pool_vmt_guid=(SELECT vmt_guid FROM vm_static INNER JOIN vm_pool_map ON vm_static.vm_guid=vm_pool_map.vm_guid WHERE vm_pool_map.vm_pool_id=vm_pools.vm_pool_id LIMIT 1); +UPDATE vm_pools SET vm_pool_is_latest=(SELECT CASE WHEN template_version_number IS NULL THEN TRUE ELSE FALSE END AS vm_is_latest FROM vm_static INNER JOIN vm_pool_map ON vm_static.vm_guid=vm_pool_map.vm_guid WHERE vm_pool_map.vm_pool_id=vm_pools.vm_pool_id LIMIT 1); diff --git a/packaging/dbscripts/vm_pools_sp.sql b/packaging/dbscripts/vm_pools_sp.sql index c59ae00..eced199 100644 --- a/packaging/dbscripts/vm_pools_sp.sql +++ b/packaging/dbscripts/vm_pools_sp.sql @@ -12,12 +12,14 @@ v_prestarted_vms INTEGER, v_vds_group_id UUID, v_max_assigned_vms_per_user SMALLINT, - v_spice_proxy VARCHAR(255)) + v_spice_proxy VARCHAR(255), + v_vm_pool_vmt_guid UUID, + v_vm_pool_is_latest BOOLEAN) RETURNS VOID AS $procedure$ BEGIN - INSERT INTO vm_pools(vm_pool_id,vm_pool_description, vm_pool_comment, vm_pool_name, vm_pool_type,parameters, prestarted_vms, vds_group_id, max_assigned_vms_per_user, spice_proxy) - VALUES(v_vm_pool_id,v_vm_pool_description, v_vm_pool_comment, v_vm_pool_name,v_vm_pool_type,v_parameters, v_prestarted_vms, v_vds_group_id, v_max_assigned_vms_per_user, v_spice_proxy); + INSERT INTO vm_pools(vm_pool_id,vm_pool_description, vm_pool_comment, vm_pool_name, vm_pool_type,parameters, prestarted_vms, vds_group_id, max_assigned_vms_per_user, spice_proxy, vm_pool_vmt_guid, vm_pool_is_latest) + VALUES(v_vm_pool_id,v_vm_pool_description, v_vm_pool_comment, v_vm_pool_name,v_vm_pool_type,v_parameters, v_prestarted_vms, v_vds_group_id, v_max_assigned_vms_per_user, v_spice_proxy, v_vm_pool_vmt_guid, v_vm_pool_is_latest); END; $procedure$ LANGUAGE plpgsql; @@ -34,7 +36,9 @@ v_prestarted_vms INTEGER, v_vds_group_id UUID, v_max_assigned_vms_per_user SMALLINT, - v_spice_proxy VARCHAR(255)) + v_spice_proxy VARCHAR(255), + v_vm_pool_vmt_guid UUID, + v_vm_pool_is_latest BOOLEAN) RETURNS VOID --The [vm_pools] table doesn't have a timestamp column. Optimistic concurrency logic cannot be generated @@ -43,7 +47,8 @@ UPDATE vm_pools SET vm_pool_description = v_vm_pool_description, vm_pool_comment = v_vm_pool_comment, vm_pool_name = v_vm_pool_name, vm_pool_type = v_vm_pool_type,parameters = v_parameters, prestarted_vms = v_prestarted_vms, vds_group_id = v_vds_group_id, - max_assigned_vms_per_user = v_max_assigned_vms_per_user, spice_proxy = v_spice_proxy + max_assigned_vms_per_user = v_max_assigned_vms_per_user, spice_proxy = v_spice_proxy, vm_pool_vmt_guid=v_vm_pool_vmt_guid, + vm_pool_is_latest = v_vm_pool_is_latest WHERE vm_pool_id = v_vm_pool_id; END; $procedure$ LANGUAGE plpgsql; @@ -73,7 +78,7 @@ DROP TYPE IF EXISTS GetAllFromVm_pools_rs CASCADE; -Create type GetAllFromVm_pools_rs AS (vm_pool_id UUID, assigned_vm_count INTEGER, vm_running_count INTEGER, vm_pool_description VARCHAR(4000), vm_pool_comment text, vm_pool_name VARCHAR(255), vm_pool_type INTEGER, parameters VARCHAR(200), prestarted_vms INTEGER, vds_group_id UUID, vds_group_name VARCHAR(40), max_assigned_vms_per_user SMALLINT, spice_proxy VARCHAR(255)); +Create type GetAllFromVm_pools_rs AS (vm_pool_id UUID, assigned_vm_count INTEGER, vm_running_count INTEGER, vm_pool_description VARCHAR(4000), vm_pool_comment text, vm_pool_name VARCHAR(255), vm_pool_type INTEGER, parameters VARCHAR(200), prestarted_vms INTEGER, vds_group_id UUID, vds_group_name VARCHAR(40), max_assigned_vms_per_user SMALLINT, spice_proxy VARCHAR(255), vm_pool_vmt_guid UUID, vm_pool_is_latest BOOLEAN); Create or replace FUNCTION GetAllFromVm_pools() RETURNS SETOF GetAllFromVm_pools_rs AS $procedure$ BEGIN @@ -146,7 +151,9 @@ vds_group_id UUID, vds_group_name VARCHAR(40), max_assigned_vms_per_user SMALLINT, - spice_proxy VARCHAR(255) + spice_proxy VARCHAR(255), + vm_pool_vmt_guid UUID, + vm_pool_is_latest BOOLEAN ) WITH OIDS; exception when others then truncate table tt_VM_POOL_RESULT; @@ -163,10 +170,12 @@ vds_group_id, vds_group_name, max_assigned_vms_per_user, - spice_proxy) + spice_proxy, + vm_pool_vmt_guid, + vm_pool_is_latest) select ppr.vm_pool_id, ppr.assigned_vm_count, ppr.vm_running_count, p.vm_pool_description, p.vm_pool_comment, p.vm_pool_name, p.vm_pool_type, p.parameters, p.prestarted_vms, - p.vds_group_id, p.vds_group_name, p.max_assigned_vms_per_user, p.spice_proxy + p.vds_group_id, p.vds_group_name, p.max_assigned_vms_per_user, p.spice_proxy, p.vm_pool_vmt_guid, p.vm_pool_is_latest from tt_VM_POOL_PRERESULT ppr inner join vm_pools_view p on ppr.vm_pool_id = p.vm_pool_id; RETURN QUERY select * diff --git a/packaging/dbscripts/vm_templates_sp.sql b/packaging/dbscripts/vm_templates_sp.sql index 8e8d26f..b454758 100644 --- a/packaging/dbscripts/vm_templates_sp.sql +++ b/packaging/dbscripts/vm_templates_sp.sql @@ -550,7 +550,8 @@ BEGIN RETURN QUERY SELECT * from vm_templates_view - where base_template_id = v_base_template_id and vmt_guid != v_base_template_id; + where base_template_id = v_base_template_id and vmt_guid != v_base_template_id + order by template_version_number desc; END; $procedure$ LANGUAGE plpgsql; diff --git a/packaging/dbscripts/vms_sp.sql b/packaging/dbscripts/vms_sp.sql index 74ef317..dcbce0e 100644 --- a/packaging/dbscripts/vms_sp.sql +++ b/packaging/dbscripts/vms_sp.sql @@ -896,6 +896,19 @@ END; $procedure$ LANGUAGE plpgsql; +Create or replace FUNCTION GetPoolVmsFromVms(v_user_id UUID, v_pool_id UUID, v_is_filtered boolean) RETURNS SETOF vms STABLE +AS $procedure$ +BEGIN +RETURN QUERY SELECT DISTINCT vms.* + FROM vms + WHERE vm_pool_id = v_pool_id AND + (NOT v_is_filtered OR EXISTS (SELECT 1 + FROM user_vm_permissions_view + WHERE user_id = v_user_id AND entity_id = vm_guid)) + ORDER BY vm_guid; +END; $procedure$ +LANGUAGE plpgsql; + -- To view, visit http://gerrit.ovirt.org/36507 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib106016955c702bc28f9347d828c4602e47bd233 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Eldan Shachar <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
