Eldan Shachar has uploaded a new change for review. Change subject: core:(2) Editing of template version for stateless VMs and pools ......................................................................
core:(2) Editing of template version for stateless VMs and pools --This patch includes the commands and queries changes 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: I2249cfea12ffbab008c162d52928df782f5f9d85 Bug-Url: https://bugzilla.redhat.com/1140569 Signed-off-by: Eldan Shachar <eshac...@redhat.com> --- A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetAllPoolVmsQuery.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetVmTemplatesByBaseTemplateIdQuery.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessDownVmCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmPoolWithVmsCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmVersionCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/UpdateVmVersionParameters.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java 9 files changed, 199 insertions(+), 8 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/08/36508/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetAllPoolVmsQuery.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetAllPoolVmsQuery.java new file mode 100644 index 0000000..e9f4492 --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetAllPoolVmsQuery.java @@ -0,0 +1,27 @@ +package org.ovirt.engine.core.bll; + +import java.util.List; + +import org.ovirt.engine.core.bll.context.EngineContext; +import org.ovirt.engine.core.common.businessentities.VM; +import org.ovirt.engine.core.common.queries.IdQueryParameters; + +public class GetAllPoolVmsQuery<P extends IdQueryParameters> extends QueriesCommandBase<P> { + public GetAllPoolVmsQuery(P parameters) { + super(parameters); + } + + public GetAllPoolVmsQuery(P parameters, EngineContext engineContext) { + super(parameters, engineContext); + } + + @Override + protected void executeQueryCommand() { + List<VM> vmsList = getDbFacade() + .getVmDao().getPoolVms(getParameters().getId()); + for (VM vm : vmsList) { + VmHandler.updateVmGuestAgentVersion(vm); + } + getQueryReturnValue().setReturnValue(vmsList); + } +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetVmTemplatesByBaseTemplateIdQuery.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetVmTemplatesByBaseTemplateIdQuery.java new file mode 100644 index 0000000..952f1ae --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetVmTemplatesByBaseTemplateIdQuery.java @@ -0,0 +1,33 @@ +package org.ovirt.engine.core.bll; + +import org.ovirt.engine.core.common.businessentities.VmTemplate; +import org.ovirt.engine.core.common.queries.GetVmTemplateParameters; +import org.ovirt.engine.core.dal.dbbroker.DbFacade; + +import java.util.List; + +/* Returns a list of all templates under required base template - including the base template */ +public class GetVmTemplatesByBaseTemplateIdQuery<P extends GetVmTemplateParameters> + extends QueriesCommandBase<P> { + public GetVmTemplatesByBaseTemplateIdQuery(P parameters) { + super(parameters); + } + + @Override + protected void executeQueryCommand() { + List<VmTemplate> templateList = + DbFacade.getInstance().getVmTemplateDao().getTemplateVersionsForBaseTemplate(getParameters().getId()); + if (templateList != null) { + VmTemplate baseTemplate = DbFacade.getInstance().getVmTemplateDao().get(getParameters().getId(), getUserID(), getParameters().isFiltered()); + if (baseTemplate != null) { + templateList.add(baseTemplate); + } + // Load VmInit and disks + for (VmTemplate template : templateList) { + VmHandler.updateVmInitFromDB(template, true); + VmTemplateHandler.updateDisksFromDb(template); + } + } + getQueryReturnValue().setReturnValue(templateList); + } +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessDownVmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessDownVmCommand.java index 5c92bb2..f9810a4 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessDownVmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessDownVmCommand.java @@ -61,6 +61,8 @@ @Override protected void executeCommand() { + applyNextRunConfiguration(); + boolean removedStatelessSnapshot = detachUsers(); if (!removedStatelessSnapshot) { // If we are dealing with a prestarted Vm or a regular Vm - clean stateless images @@ -70,8 +72,6 @@ QuotaManager.getInstance().rollbackQuotaByVmId(getVmId()); removeStatelessVmUnmanagedDevices(); - - applyNextRunConfiguration(); } private boolean detachUsers() { diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmCommand.java index 869f6f8..7abb90f 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmCommand.java @@ -32,6 +32,7 @@ import org.ovirt.engine.core.common.action.LockProperties.Scope; import org.ovirt.engine.core.common.action.PlugAction; import org.ovirt.engine.core.common.action.RngDeviceParameters; +import org.ovirt.engine.core.common.action.UpdateVmVersionParameters; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VdcReturnValueBase; import org.ovirt.engine.core.common.action.VmManagementParametersBase; @@ -53,6 +54,7 @@ import org.ovirt.engine.core.common.businessentities.VmPayload; import org.ovirt.engine.core.common.businessentities.VmRngDevice; import org.ovirt.engine.core.common.businessentities.VmStatic; +import org.ovirt.engine.core.common.businessentities.VmTemplate; import org.ovirt.engine.core.common.businessentities.VmWatchdog; import org.ovirt.engine.core.common.businessentities.network.Network; import org.ovirt.engine.core.common.businessentities.network.VmNic; @@ -87,6 +89,7 @@ private VmStatic newVmStatic; private VdcReturnValueBase setNumberOfCpusResult; private List<GraphicsDevice> cachedGraphics; + private boolean isUpdateVmTemplateVersion = false; public UpdateVmCommand(T parameters) { this(parameters, null); @@ -132,11 +135,15 @@ @Override protected void executeVmCommand() { + oldVm = getVm(); // needs to be here for post-actions + if (isUpdateVmTemplateVersion) { + updateVmTemplateVersion(); + return; // template version was changed, no more work is required + } if (isRunningConfigurationNeeded()) { createNextRunSnapshot(); } - oldVm = getVm(); VmHandler.warnMemorySizeLegal(getParameters().getVm().getStaticData(), getVdsGroup().getcompatibility_version()); getVmStaticDAO().incrementDbGeneration(getVm().getId()); newVmStatic = getParameters().getVmStaticData(); @@ -175,6 +182,26 @@ checkTrustedService(); setSucceeded(true); + } + + private void updateVmTemplateVersion() { + if (getVm().getStatus() == VMStatus.Down) { // if vm is down -> updateVmVersionCommand will handle the rest. if it's not, a NEXT_RUN snapshot will be created. + VdcReturnValueBase result = + runInternalActionWithTasksContext( + VdcActionType.UpdateVmVersion, + new UpdateVmVersionParameters(getVmId(), + getParameters().getVm().getVmtGuid(), + getParameters().getVm().isUseLatestVersion()), + getLock() + ); + if (result.getSucceeded()) { + getTaskIdList().addAll(result.getInternalVdsmTaskIdList()); + } + setSucceeded(result.getSucceeded()); + } else { + createNextRunSnapshot(); + setSucceeded(true); + } } private boolean updateRngDevice() { @@ -490,6 +517,28 @@ VM vmFromDB = getVm(); VM vmFromParams = getParameters().getVm(); + // check if VM was changed to use latest + if (vmFromDB.isUseLatestVersion() != vmFromParams.isUseLatestVersion() && vmFromParams.isUseLatestVersion()) { + // check if a version change is actually required or just let the local command to update this field + vmFromParams.setVmtGuid(getVmTemplateDAO().getTemplateWithLatestVersionInChain(getVm().getVmtGuid()).getId()); + } + + // stateless VMs are allowed to change template id, this verifies that the change is only between template versions. + if (!vmFromDB.getVmtGuid().equals(vmFromParams.getVmtGuid())) { + VmTemplate origTemplate = getVmTemplateDAO().get(vmFromDB.getVmtGuid()); + VmTemplate newTemplate = getVmTemplateDAO().get(vmFromParams.getVmtGuid()); + if (newTemplate == null) { + return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_TEMPLATE_DOES_NOT_EXIST); + } else if (origTemplate != null && !origTemplate.getBaseTemplateId().equals(newTemplate.getBaseTemplateId())) { + return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_TEMPLATE_IS_ON_DIFFERENT_CHAIN); + + // check if stateless - if vm is not stateless the field is not legal and command will fail later on + } else if (vmFromParams.isStateless() || vmFromDB.getVmPoolId() != null) { + isUpdateVmTemplateVersion = true; + return true; // no more tests are needed because no more changes are allowed in this state + } + } + if (getVdsGroup() == null) { addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_CLUSTER_CAN_NOT_BE_EMPTY); return false; diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmPoolWithVmsCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmPoolWithVmsCommand.java index 2732efb..47ea946 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmPoolWithVmsCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmPoolWithVmsCommand.java @@ -1,11 +1,19 @@ package org.ovirt.engine.core.bll; import java.util.List; + import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.action.AddVmPoolWithVmsParameters; +import org.ovirt.engine.core.common.action.VdcActionType; +import org.ovirt.engine.core.common.action.VdcReturnValueBase; +import org.ovirt.engine.core.common.action.VmManagementParametersBase; +import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VmPool; import org.ovirt.engine.core.common.errors.VdcBllMessages; +import org.ovirt.engine.core.common.queries.IdQueryParameters; +import org.ovirt.engine.core.common.queries.VdcQueryReturnValue; +import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.common.validation.group.UpdateEntity; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase; @@ -66,9 +74,42 @@ @Override protected void executeCommand() { super.executeCommand(); + if (getSucceeded()) { + updatePoolVms(); + } Backend.getInstance().triggerPoolMonitoringJob(); } + private void updatePoolVms() { + if (!oldPool.getVmtGuid().equals(getParameters().getVmStaticData().getVmtGuid()) || getParameters().getVmStaticData().isUseLatestVersion() != oldPool.isUseLatestVersion()) { + VdcQueryReturnValue qRetVal = + runInternalQuery(VdcQueryType.GetAllPoolVms, new IdQueryParameters(getVmPool().getVmPoolId())); + List<VM> vmsInPool = qRetVal.getSucceeded() ? qRetVal.<List<VM>>getReturnValue() : null; + if (vmsInPool != null) { + VmTemplateHandler.lockVmTemplateInTransaction(getParameters().getVmStaticData().getVmtGuid(), + getCompensationContext()); + for (VM vm : vmsInPool) { + VmManagementParametersBase updateParams = new VmManagementParametersBase(vm); + boolean isLatest = getParameters().getVmStaticData().isUseLatestVersion(); + updateParams.getVmStaticData().setUseLatestVersion(isLatest); + if (!isLatest) { + updateParams.getVmStaticData().setVmtGuid(getParameters().getVmStaticData().getVmtGuid()); + } + + VdcReturnValueBase result = + runInternalActionWithTasksContext( + VdcActionType.UpdateVm, + updateParams, + getLock() + ); + getTaskIdList().addAll(result.getInternalVdsmTaskIdList()); + setSucceeded(getSucceeded() && result.getSucceeded()); + } + VmTemplateHandler.unlockVmTemplate(getParameters().getVmStaticData().getVmtGuid()); + } + } + } + @Override public String getEntityType() { return VdcObjectType.VmPool.getVdcObjectTranslation(); diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmVersionCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmVersionCommand.java index e974098..27f3f4d 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmVersionCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmVersionCommand.java @@ -42,7 +42,7 @@ import org.slf4j.LoggerFactory; /** - * This class updates VM to the latest template version for stateless vms that has newer template version + * This class updates VM to the required template version for stateless VMs */ @InternalCommandAttribute public class UpdateVmVersionCommand<T extends UpdateVmVersionParameters> extends VmCommand<T> { @@ -61,7 +61,11 @@ parameters.setEntityInfo(new EntityInfo(VdcObjectType.VM, parameters.getVmId())); if (getVm() != null) { - setVmTemplate(getVmTemplateDAO().getTemplateWithLatestVersionInChain(getVm().getVmtGuid())); + if(parameters.getNewTemplateVersion() != null) { + setVmTemplate(getVmTemplateDAO().get(parameters.getNewTemplateVersion())); + } else { + setVmTemplate(getVmTemplateDAO().getTemplateWithLatestVersionInChain(getVm().getVmtGuid())); + } } } @@ -80,7 +84,7 @@ return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_IS_NOT_DOWN); } - if (!getVm().isUseLatestVersion()) { + if (!getVm().isUseLatestVersion() && getParameters().getNewTemplateVersion() == null) { return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_NOT_SET_FOR_LATEST); } @@ -111,6 +115,9 @@ return; } + if (getParameters().getLatestStatus() != null) { + getVm().setUseLatestVersion(getParameters().getLatestStatus()); + } getParameters().setPreviousDiskOperatorAuthzPrincipalDbId(getIdOfDiskOperator()); getParameters().setVmStaticData(getVm().getStaticData()); @@ -172,6 +179,7 @@ parameters.setEntityInfo(getParameters().getEntityInfo()); return parameters; } + private void addUpdatedVm() { VdcActionType action = getParameters().getVmPoolId() == null ? VdcActionType.AddVm : VdcActionType.AddVmAndAttachToPool; @@ -281,7 +289,7 @@ @Override protected Map<String, Pair<String, String>> getSharedLocks() { - // take shared lock on latest template, since we will add vm from it + // take shared lock on required template, since we will add vm from it if (getVmTemplateId() != null) { return Collections.singletonMap(getVmTemplateId().toString(), LockMessagesMatchUtil.makeLockingPair(LockingGroup.TEMPLATE, VdcBllMessages.ACTION_TYPE_FAILED_OBJECT_LOCKED)); diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java index acc0497..adc0ad2 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java @@ -33,6 +33,7 @@ import org.ovirt.engine.core.common.businessentities.DisplayType; import org.ovirt.engine.core.common.businessentities.EditableDeviceOnVmStatusField; import org.ovirt.engine.core.common.businessentities.EditableField; +import org.ovirt.engine.core.common.businessentities.EditableOnStatelessVmField; import org.ovirt.engine.core.common.businessentities.EditableOnVm; import org.ovirt.engine.core.common.businessentities.EditableOnVmStatusField; import org.ovirt.engine.core.common.businessentities.GraphicsDevice; @@ -127,6 +128,11 @@ } } + for (Pair<EditableOnStatelessVmField, Field> pair : BaseHandler.extractAnnotatedFields(EditableOnStatelessVmField.class, + inspectedClassNames)) { + mUpdateVmsStatic.AddStatelessFields(pair.getSecond().getName()); + } + for (Pair<EditableDeviceOnVmStatusField, Field> pair : BaseHandler.extractAnnotatedFields(EditableDeviceOnVmStatusField.class, inspectedClassNames)) { mUpdateVmsStatic.AddField(Arrays.asList(pair.getFirst().statuses()), pair.getSecond().getName()); @@ -159,7 +165,7 @@ } public static boolean isUpdateValid(VmStatic source, VmStatic destination, VMStatus status, boolean hotsetEnabled) { - return mUpdateVmsStatic.IsUpdateValid(source, destination, status, hotsetEnabled); + return mUpdateVmsStatic.IsUpdateValid(source, destination, status, hotsetEnabled, source.isStateless()); } public static boolean isUpdateValid(VmStatic source, VmStatic destination) { diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/UpdateVmVersionParameters.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/UpdateVmVersionParameters.java index 484e97f..941ea8d 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/UpdateVmVersionParameters.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/UpdateVmVersionParameters.java @@ -7,13 +7,30 @@ private Guid vmPoolId; /** The ID of disk operator of one of the disks the VM had before the update */ private Guid previousDiskOperatorAuthzPrincipalDbId; + private Guid newTemplateVersion; + private Boolean LatestStatus; public UpdateVmVersionParameters() { } public UpdateVmVersionParameters(Guid vmId) { + this(vmId, null, null); // use latest template version, based on the vm existing latest field + } + + public UpdateVmVersionParameters(Guid vmId, Guid newTemplateVersion, Boolean LatestStatus) { super(); setVmId(vmId); + setNewTemplateVersion(newTemplateVersion); + setLatestStatus(LatestStatus); + } + + + public Guid getNewTemplateVersion() { + return newTemplateVersion; + } + + public void setNewTemplateVersion(Guid newTemplateVersion) { + this.newTemplateVersion = newTemplateVersion; } public Guid getVmPoolId() { @@ -31,4 +48,12 @@ public void setPreviousDiskOperatorAuthzPrincipalDbId(Guid previousDiskOperatorAuthzPrincipalDbId) { this.previousDiskOperatorAuthzPrincipalDbId = previousDiskOperatorAuthzPrincipalDbId; } + + public Boolean getLatestStatus() { + return LatestStatus; + } + + public void setLatestStatus(Boolean latestStatus) { + LatestStatus = latestStatus; + } } diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java index 2864d22..050cd89 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java @@ -9,6 +9,7 @@ GetVmByVmNameForDataCenter(VdcQueryAuthType.User), GetAllVms(VdcQueryAuthType.User), GetAllVmsForUser(VdcQueryAuthType.User), + GetAllPoolVms(VdcQueryAuthType.User), GetUnregisteredVms, GetUnregisteredVmTemplates, GetVmsRunningOnOrMigratingToVds, @@ -131,6 +132,7 @@ GetVmTemplatesByStoragePoolId, GetVmTemplatesByImageGuid, GetSystemPermissions, + GetVmTemplatesByBaseTemplateId(VdcQueryAuthType.User), // VM Snapshot queries GetAllVmSnapshotsByVmId(VdcQueryAuthType.User), -- To view, visit http://gerrit.ovirt.org/36508 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2249cfea12ffbab008c162d52928df782f5f9d85 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Eldan Shachar <eshac...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches