Omer Frenkel has uploaded a new change for review. Change subject: core: automatically update vms on new version ......................................................................
core: automatically update vms on new version When new version of a template is available, or when stateless(\pool) vm goes to down, we update the vm to the new version. Change-Id: I5449eee954bd6096b6f2e423a75a8cac3e5bcc3b Signed-off-by: Omer Frenkel <ofren...@redhat.com> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddVmAndAttachToPoolCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddVmTemplateCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmTemplateCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RestoreStatelessVmCommand.java A 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/VmCommand.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/RemoveVmParameters.java A 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/action/VdcActionType.java A backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/CopyOnNewVersion.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmBase.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/VmStaticDAO.java M backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmStaticDAODbFacadeImpl.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/VmDAOTest.java M backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmStaticDAOTest.java M backend/manager/modules/dal/src/test/resources/fixtures.xml 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/vms_sp.sql 25 files changed, 537 insertions(+), 31 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/10/23610/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddVmAndAttachToPoolCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddVmAndAttachToPoolCommand.java index ae9dc04..a3ee980 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddVmAndAttachToPoolCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddVmAndAttachToPoolCommand.java @@ -2,6 +2,7 @@ import java.util.Map; +import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.bll.job.ExecutionHandler; import org.ovirt.engine.core.common.action.AddVmAndAttachToPoolParameters; import org.ovirt.engine.core.common.action.AddVmFromScratchParameters; @@ -57,7 +58,11 @@ private VdcReturnValueBase addVm(VmStatic vmStatic) { VmManagementParametersBase parameters = new VmManagementParametersBase(vmStatic); - parameters.setSessionId(getParameters().getSessionId()); + if (StringUtils.isEmpty(getParameters().getSessionId())) { + parameters.setParametersCurrentUser(getCurrentUser()); + } else { + parameters.setSessionId(getParameters().getSessionId()); + } parameters.setDontAttachToDefaultTag(true); parameters.setDiskInfoDestinationMap(diskInfoDestinationMap); parameters.setSoundDeviceEnabled(getParameters().isSoundDeviceEnabled()); diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddVmTemplateCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddVmTemplateCommand.java index 6501804..1d3e885 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddVmTemplateCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddVmTemplateCommand.java @@ -8,6 +8,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.bll.quota.QuotaConsumptionParameter; @@ -28,6 +30,7 @@ import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.action.AddVmTemplateParameters; import org.ovirt.engine.core.common.action.CreateImageTemplateParameters; +import org.ovirt.engine.core.common.action.UpdateVmVersionParameters; import org.ovirt.engine.core.common.action.VdcActionParametersBase; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VdcReturnValueBase; @@ -56,11 +59,14 @@ import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.common.validation.group.CreateEntity; import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.compat.TransactionScopeOption; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase; import org.ovirt.engine.core.dao.PermissionDAO; import org.ovirt.engine.core.utils.collections.MultiValueMapUtils; +import org.ovirt.engine.core.utils.timer.OnTimerMethodAnnotation; +import org.ovirt.engine.core.utils.timer.SchedulerUtilQuartzImpl; import org.ovirt.engine.core.utils.transaction.TransactionMethod; import org.ovirt.engine.core.utils.transaction.TransactionSupport; @@ -77,6 +83,7 @@ private boolean isVmInDb; private static final String BASE_TEMPLATE_VERSION_NAME = "base version"; + private static Map<Guid, String> updateVmsJobIdMap = new ConcurrentHashMap<Guid, String>(); /** * Constructor for command creation when compensation is applied on startup @@ -203,6 +210,16 @@ getParameters().setBaseTemplateId(getVmTemplateId()); if (StringUtils.isEmpty(getParameters().getTemplateVersionName())) { getParameters().setTemplateVersionName(BASE_TEMPLATE_VERSION_NAME); + } + } else { + String jobId = updateVmsJobIdMap.remove(getParameters().getBaseTemplateId()); + if (jobId != null) { + log.infoFormat("Cancelling current running update for vms for base template id {0}", getParameters().getBaseTemplateId()); + try { + SchedulerUtilQuartzImpl.getInstance().deleteJob(jobId); + } catch (Exception e) { + log.warnFormat("Failed deleting job {0} at cancelRecoveryJob", jobId); + } } } @@ -569,6 +586,29 @@ private void endDefaultOperations() { endUnlockOps(); + + // in case of new version of a template, update vms marked to use latest + if (getParameters().getBaseTemplateId() != null) { + String jobId = SchedulerUtilQuartzImpl.getInstance().scheduleAOneTimeJob(this, "onTimerHandleVdsRecovering", new Class[0], + new Object[0], 0, TimeUnit.SECONDS); + updateVmsJobIdMap.put(getParameters().getBaseTemplateId(), jobId); + } + } + + @OnTimerMethodAnnotation("onTimerHandleVdsRecovering") + public void onTimerHandleVdsRecovering() { + for (Guid vmId : getVmDAO().getVmIdsForVersionUpdate(getParameters().getBaseTemplateId())) { + // if the job was removed, stop executing, we probably have new version creation going on + if (!updateVmsJobIdMap.containsKey(getParameters().getBaseTemplateId())) { + break; + } + UpdateVmVersionParameters params = new UpdateVmVersionParameters(vmId); + params.setSessionId(getParameters().getSessionId()); + // execute in new transaction, as failure here should not fail template creation + params.setTransactionScopeOption(TransactionScopeOption.RequiresNew); + getBackend().runInternalAction(VdcActionType.UpdateVmVersion, params); + } + updateVmsJobIdMap.remove(getParameters().getBaseTemplateId()); } private void endUnlockOps() { diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java index c0ccd32..9cc7654 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java @@ -261,9 +261,16 @@ private RemoveAllVmImagesParameters buildRemoveAllVmImagesParameters(List<DiskImage> images) { RemoveAllVmImagesParameters params = new RemoveAllVmImagesParameters(getVmId(), images); - params.setParentCommand(getActionType()); - params.setEntityInfo(getParameters().getEntityInfo()); - params.setParentParameters(getParameters()); + if (getParameters().getParentCommand() == VdcActionType.Unknown) { + params.setParentCommand(getActionType()); + params.setEntityInfo(getParameters().getEntityInfo()); + params.setParentParameters(getParameters()); + } else { + params.setParentCommand(getParameters().getParentCommand()); + params.setEntityInfo(getParameters().getParentParameters().getEntityInfo()); + params.setParentParameters(getParameters().getParentParameters()); + } + return params; } @@ -283,7 +290,7 @@ removeVmUsers(); removeVmNetwork(); memoryStates = removeVmSnapshots(); - removeVmStatic(); + removeVmStatic(getParameters().isRemovePermissions()); } /** diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmTemplateCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmTemplateCommand.java index 4c71bfe..3f721af 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmTemplateCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmTemplateCommand.java @@ -154,7 +154,7 @@ } // for base templates, make sure it has no versions that need to be removed first - if (vmTemplateId.equals(template.getBaseTemplateId())) { + if (getParameters().isRemoveTemplateFromDb() && vmTemplateId.equals(template.getBaseTemplateId())) { List<VmTemplate> templateVersions = getVmTemplateDAO().getTemplateVersionsForBaseTemplate(vmTemplateId); if (!templateVersions.isEmpty()) { List<String> templateVersionsNames = new ArrayList<>(); diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RestoreStatelessVmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RestoreStatelessVmCommand.java index 70b3037..1123cd7 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RestoreStatelessVmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RestoreStatelessVmCommand.java @@ -4,6 +4,7 @@ import org.ovirt.engine.core.bll.job.ExecutionHandler; import org.ovirt.engine.core.common.action.RestoreAllSnapshotsParameters; +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.VmOperationParameterBase; @@ -30,27 +31,44 @@ @Override protected void executeCommand() { - boolean returnVal = true; - Guid snapshotId = DbFacade.getInstance().getSnapshotDao().getId(getVmId(), SnapshotType.STATELESS); - List<DiskImage> imagesList = null; + VdcReturnValueBase result = + getBackend().runInternalAction(VdcActionType.UpdateVmVersion, + new UpdateVmVersionParameters(getVmId()), + ExecutionHandler.createDefaultContexForTasks(getExecutionContext(), getLock())); - if (snapshotId != null) { - imagesList = DbFacade.getInstance().getDiskImageDao().getAllSnapshotsForVmSnapshot(snapshotId); - } + // if it fail because of canDoAction, its safe to restore the snapshot + // and the vm will still be usable with previous version + if (!result.getSucceeded() && !result.getCanDoAction()) { + log.warnFormat("Couldn't update VM {0} ({1}) version from it's template, continue with restoring stateless snapshot.", + getVm().getName(), + getVmId()); - if (imagesList != null && imagesList.size() > 0) { - /** - * restore all snapshots - */ - RestoreAllSnapshotsParameters tempVar = new RestoreAllSnapshotsParameters(getVm().getId(), snapshotId); - tempVar.setShouldBeLogged(false); - tempVar.setImages(imagesList); - VdcReturnValueBase vdcReturn = - Backend.getInstance().runInternalAction(VdcActionType.RestoreAllSnapshots, - tempVar, - ExecutionHandler.createDefaultContexForTasks(getExecutionContext(), getLock())); - returnVal = vdcReturn.getSucceeded(); + boolean returnVal = true; + Guid snapshotId = DbFacade.getInstance().getSnapshotDao().getId(getVmId(), SnapshotType.STATELESS); + List<DiskImage> imagesList = null; + + if (snapshotId != null) { + imagesList = DbFacade.getInstance().getDiskImageDao().getAllSnapshotsForVmSnapshot(snapshotId); + } + + if (imagesList != null && imagesList.size() > 0) { + /** + * restore all snapshots + */ + RestoreAllSnapshotsParameters tempVar = new RestoreAllSnapshotsParameters(getVm().getId(), snapshotId); + tempVar.setShouldBeLogged(false); + tempVar.setImages(imagesList); + VdcReturnValueBase vdcReturn = + Backend.getInstance().runInternalAction(VdcActionType.RestoreAllSnapshots, + tempVar, + ExecutionHandler.createDefaultContexForTasks(getExecutionContext(), getLock())); + returnVal = vdcReturn.getSucceeded(); + } + setSucceeded(returnVal); } - setSucceeded(returnVal); + } + + private void overrideVmComfig() { + } } 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 new file mode 100644 index 0000000..def4672 --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmVersionCommand.java @@ -0,0 +1,252 @@ +package org.ovirt.engine.core.bll; + +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.ovirt.engine.core.bll.job.ExecutionHandler; +import org.ovirt.engine.core.common.VdcObjectType; +import org.ovirt.engine.core.common.action.AddVmAndAttachToPoolParameters; +import org.ovirt.engine.core.common.action.RemoveVmFromPoolParameters; +import org.ovirt.engine.core.common.action.RemoveVmParameters; +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; +import org.ovirt.engine.core.common.asynctasks.EntityInfo; +import org.ovirt.engine.core.common.businessentities.CopyOnNewVersion; +import org.ovirt.engine.core.common.businessentities.DiskImage; +import org.ovirt.engine.core.common.businessentities.VMStatus; +import org.ovirt.engine.core.common.businessentities.VmBase; +import org.ovirt.engine.core.common.businessentities.VmDeviceGeneralType; +import org.ovirt.engine.core.common.businessentities.VmPayload; +import org.ovirt.engine.core.common.businessentities.VmTemplate; +import org.ovirt.engine.core.common.businessentities.VmWatchdog; +import org.ovirt.engine.core.common.errors.VdcBllMessages; +import org.ovirt.engine.core.common.locks.LockingGroup; +import org.ovirt.engine.core.common.queries.IdQueryParameters; +import org.ovirt.engine.core.common.queries.VdcQueryType; +import org.ovirt.engine.core.common.utils.Pair; +import org.ovirt.engine.core.common.utils.VmDeviceType; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.compat.TransactionScopeOption; +import org.ovirt.engine.core.utils.log.Log; +import org.ovirt.engine.core.utils.log.LogFactory; + +/** + * This class updates VM to the latest template version for stateless vms that has newer template version + */ +@InternalCommandAttribute +@LockIdNameAttribute +public class UpdateVmVersionCommand<T extends UpdateVmVersionParameters> extends VmCommand<T> { + + private static final Log log = LogFactory.getLog(UpdateVmVersionCommand.class); + /** + * Constructor for command creation when compensation is applied on startup + * + * @param commandId + */ + protected UpdateVmVersionCommand(Guid commandId) { + super(commandId); + } + + public UpdateVmVersionCommand(T parameters) { + super(parameters); + parameters.setEntityInfo(new EntityInfo(VdcObjectType.VM, parameters.getVmId())); + + // vm should be filled in end action + if (parameters.getVm() != null) { + setVmTemplateId(parameters.getVm().getVmtGuid()); + } + } + + @Override + protected boolean canDoAction() { + if (getVm() == null) { + return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_NOT_FOUND); + } + + if (getVm().getStatus() != VMStatus.Down) { + return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_IS_NOT_DOWN); + } + + if (!getVm().isUseLatestVersion()) { + return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_NOT_SET_FOR_LATEST); + } + + if (getVmTemplate() == null) { + return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_TEMPLATE_DOES_NOT_EXIST); + } + + if (getVm().getVmtGuid().equals(getVmTemplate().getId())) { + return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_ALREADY_IN_LATEST_VERSION); + } + + getVm().setVmtGuid(getVmTemplate().getId()); + + return true; + } + + @Override + protected void setActionMessageParameters() { + addCanDoActionMessage(VdcBllMessages.VAR__ACTION__UPDATE_VM_VERSION); + addCanDoActionMessage(VdcBllMessages.VAR__TYPE__VM); + } + + @Override + protected void executeVmCommand() { + if (!copyData(getVmTemplate(), getVm().getStaticData())) { + return; + } + getParameters().setVmStaticData(getVm().getStaticData()); + + if (getVm().getVmPoolId() != null) { + getParameters().setVmPoolId(getVm().getVmPoolId()); + RemoveVmFromPoolParameters removeVmFromPoolParas = new RemoveVmFromPoolParameters(getVmId(), false); + removeVmFromPoolParas.setTransactionScopeOption(TransactionScopeOption.RequiresNew); + VdcReturnValueBase result = getBackend().runInternalAction(VdcActionType.RemoveVmFromPool, + removeVmFromPoolParas, + ExecutionHandler.createDefaultContexForTasks(getExecutionContext(), getLock())); + if (!result.getSucceeded()) { + log.errorFormat("Could not detach vm {0} ({1}) from vm-pool {2}.", + getVm().getName(), + getVmId(), + getVm().getVmPoolName()); + return; + } + } + + RemoveVmParameters removeParams = new RemoveVmParameters(getVmId(), false); + removeParams.setParentCommand(getActionType()); + removeParams.setParentParameters(getParameters()); + removeParams.setEntityInfo(getParameters().getEntityInfo()); + VdcReturnValueBase result = getBackend().runInternalAction(VdcActionType.RemoveVm, removeParams, + ExecutionHandler.createDefaultContexForTasks(getExecutionContext(), getLock())); + + if (result.getSucceeded()) { + if (result.getHasAsyncTasks()) { + getReturnValue().getVdsmTaskIdList().addAll(result.getInternalVdsmTaskIdList()); + } else { + endVmCommand(); + } + setSucceeded(true); + } + } + + private void addUpdatedVm() { + VmManagementParametersBase addVmParams; + VdcActionType action; + if (getParameters().getVmPoolId() != null) { + addVmParams = + new AddVmAndAttachToPoolParameters(getParameters().getVmStaticData(), + getParameters().getVmPoolId(), + getParameters().getVmStaticData().getName(), + new HashMap<Guid, DiskImage>()); + action = VdcActionType.AddVmAndAttachToPool; + } else { + addVmParams = new VmManagementParametersBase(getParameters().getVmStaticData()); + action = VdcActionType.AddVm; + } + + addVmParams.setDiskInfoDestinationMap(new HashMap<Guid, DiskImage>()); + addVmParams.setConsoleEnabled(deviceExists(VmDeviceGeneralType.CONSOLE, VmDeviceType.CONSOLE)); + addVmParams.setBalloonEnabled(deviceExists(VmDeviceGeneralType.BALLOON, VmDeviceType.BALLOON)); + addVmParams.setSoundDeviceEnabled(deviceExists(VmDeviceGeneralType.SOUND, VmDeviceType.SOUND)); + addVmParams.setVirtioScsiEnabled(deviceExists(VmDeviceGeneralType.CONTROLLER, VmDeviceType.VIRTIOSCSI)); + + List<VmWatchdog> watchdogs = getBackend().runInternalQuery(VdcQueryType.GetWatchdog, + new IdQueryParameters(getVmTemplateId())).getReturnValue(); + if (!watchdogs.isEmpty()) { + addVmParams.setWatchdog(watchdogs.get(0)); + } + + if (!StringUtils.isEmpty(getParameters().getSessionId())) { + VmPayload payload = getBackend().runInternalQuery(VdcQueryType.GetVmPayload, + new IdQueryParameters(getVmTemplateId())).getReturnValue(); + + if (payload != null) { + addVmParams.setVmPayload(payload); + } + } + + // when this initiated from down vm event (restore stateless vm) + // then there is no session, so using the current user. + if (StringUtils.isEmpty(getParameters().getSessionId())) { + addVmParams.setParametersCurrentUser(getCurrentUser()); + } else { + addVmParams.setSessionId(getParameters().getSessionId()); + } + getBackend().runInternalAction(action, addVmParams, + ExecutionHandler.createDefaultContexForTasks(getExecutionContext(), getLock())); + } + + /** + * Copy fields that annotated with {@link CopyOnNewVersion} from the new template version to the vm + * + * @param source + * - template to copy data from + * @param dest + * - vm to copy data to + */ + private boolean copyData(VmBase source, VmBase dest) { + for (Field srcFld : VmBase.class.getDeclaredFields()) { + try { + if (srcFld.getAnnotation(CopyOnNewVersion.class) != null) { + srcFld.setAccessible(true); + + Field dstFld = VmBase.class.getDeclaredField(srcFld.getName()); + dstFld.setAccessible(true); + dstFld.set(dest, srcFld.get(source)); + } + } catch (Exception exp) { + log.errorFormat("Failed to copy field {0} of new version to VM {1} ({2}), error: {3}", + srcFld.getName(), + source.getName(), + source.getId(), + exp.getMessage()); + return false; + } + } + return true; + } + + private boolean deviceExists(VmDeviceGeneralType generalType, VmDeviceType deviceType) { + return !getVmDeviceDao().getVmDeviceByVmIdTypeAndDevice( + getVmTemplateId(), generalType, deviceType.getName()).isEmpty(); + } + + @Override + protected Map<String, Pair<String, String>> getExclusiveLocks() { + return Collections.singletonMap(getVmId().toString(), + LockMessagesMatchUtil.makeLockingPair(LockingGroup.VM, VdcBllMessages.ACTION_TYPE_FAILED_OBJECT_LOCKED)); + } + + @Override + protected Map<String, Pair<String, String>> getSharedLocks() { + // take shared lock on latest template, since we will add vm from it + if (getVm() != null) { + VmTemplate latest = getVmTemplateDAO().getTemplateWithLatestVersionInChain(getVm().getVmtGuid()); + if (latest != null) { + setVmTemplateId(latest.getId()); + setVmTemplate(latest); + return Collections.singletonMap(latest.getId().toString(), + LockMessagesMatchUtil.makeLockingPair(LockingGroup.TEMPLATE, VdcBllMessages.ACTION_TYPE_FAILED_OBJECT_LOCKED)); + } + } + return null; + } + + @Override + protected void endVmCommand() { + addUpdatedVm(); + setSucceeded(true); + } + + @Override + protected void endWithFailure() { + // nothing to do + } +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCommand.java index 5b2a615..f81e42a 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCommand.java @@ -210,7 +210,11 @@ } protected void removeVmStatic() { - getVmStaticDAO().remove(getVmId()); + removeVmStatic(true); + } + + protected void removeVmStatic(boolean removePermissions) { + getVmStaticDAO().remove(getVmId(), removePermissions); } protected List<VmNic> getInterfaces() { diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/RemoveVmParameters.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/RemoveVmParameters.java index aacebb9..6cd3e9d 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/RemoveVmParameters.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/RemoveVmParameters.java @@ -7,6 +7,7 @@ private static final long serialVersionUID = 4931085923357689965L; private boolean force; private boolean removeDisks; + private boolean removePermissions; public boolean getForce() { return force; @@ -24,10 +25,19 @@ this.removeDisks = removeDisks; } + public boolean isRemovePermissions() { + return removePermissions; + } + + public void setRemovePermissions(boolean removePermissions) { + this.removePermissions = removePermissions; + } + public RemoveVmParameters(Guid vmId, boolean force) { super(vmId); setForce(force); removeDisks = true; + removePermissions = true; } public RemoveVmParameters(Guid vmId, boolean force, boolean removeDisks) { @@ -37,5 +47,6 @@ public RemoveVmParameters() { removeDisks = true; + removePermissions = true; } } 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 new file mode 100644 index 0000000..73edc51 --- /dev/null +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/UpdateVmVersionParameters.java @@ -0,0 +1,24 @@ +package org.ovirt.engine.core.common.action; + +import org.ovirt.engine.core.compat.Guid; + +public class UpdateVmVersionParameters extends VmManagementParametersBase { + + private Guid vmPoolId; + + public UpdateVmVersionParameters() { + } + + public UpdateVmVersionParameters(Guid vmId) { + super(); + setVmId(vmId); + } + + public Guid getVmPoolId() { + return vmPoolId; + } + + public void setVmPoolId(Guid vmPoolId) { + this.vmPoolId = vmPoolId; + } +} diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java index e567fd2..59ca73d 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java @@ -51,6 +51,7 @@ ActivateDeactivateVmNic(42, QuotaDependency.NONE), AddVmFromSnapshot(52, ActionGroup.CREATE_VM, QuotaDependency.BOTH), ImportVmFromConfiguration(43, ActionGroup.IMPORT_EXPORT_VM, QuotaDependency.NONE), + UpdateVmVersion(44, QuotaDependency.NONE), // VdsCommands AddVds(101, ActionGroup.CREATE_HOST, QuotaDependency.NONE), UpdateVds(102, ActionGroup.EDIT_HOST_CONFIGURATION, false, QuotaDependency.NONE), diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/CopyOnNewVersion.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/CopyOnNewVersion.java new file mode 100644 index 0000000..b0e8645 --- /dev/null +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/CopyOnNewVersion.java @@ -0,0 +1,16 @@ +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; + +/** + * This annotation is used to mark a field + * that need to be copied to vm, from a new template version + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface CopyOnNewVersion { + +} diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmBase.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmBase.java index b56f729..0f30c32 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmBase.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmBase.java @@ -49,6 +49,7 @@ @EditableOnTemplate private Guid vdsGroupId; + @CopyOnNewVersion @EditableField private int osId; @@ -63,28 +64,34 @@ @EditableField private String comment; + @CopyOnNewVersion @EditableOnVmStatusField @EditableOnTemplate private int memSizeMb; + @CopyOnNewVersion @EditableOnVmStatusField @EditableOnTemplate private int numOfSockets; + @CopyOnNewVersion @EditableOnVmStatusField @EditableOnTemplate private int cpuPerSocket; + @CopyOnNewVersion @EditableOnVmStatusField @EditableOnTemplate @IntegerContainedInConfigValueList(configValue = ConfigValues.ValidNumOfMonitors, message = "VALIDATION.VM.NUM_OF_MONITORS.EXCEEDED") private int numOfMonitors; + @CopyOnNewVersion @EditableOnVmStatusField @EditableOnTemplate private boolean singleQxlPci; + @CopyOnNewVersion @EditableField @Size(max = BusinessEntitiesDefinitions.GENERAL_DOMAIN_SIZE) private String domain; @@ -94,28 +101,36 @@ @Size(max = BusinessEntitiesDefinitions.GENERAL_TIME_ZONE_SIZE) private String timeZone; + @CopyOnNewVersion @EditableField private VmType vmType; + @CopyOnNewVersion @EditableOnVmStatusField @EditableOnTemplate private UsbPolicy usbPolicy; + @CopyOnNewVersion private boolean failBack; + @CopyOnNewVersion @EditableField private BootSequence defaultBootSequence; + @CopyOnNewVersion @EditableOnVmStatusField private int niceLevel; + @CopyOnNewVersion @EditableOnVmStatusField @EditableOnTemplate private int cpuShares; + @CopyOnNewVersion @EditableField private int priority; + @CopyOnNewVersion @EditableField private boolean autoStartup; @@ -123,9 +138,11 @@ @EditableOnTemplate private boolean stateless; + @CopyOnNewVersion @EditableField private boolean deleteProtected; + @CopyOnNewVersion @EditableOnVmStatusField @EditableOnTemplate private SsoMethod ssoMethod; @@ -133,15 +150,18 @@ @EditableField private long dbGeneration; + @CopyOnNewVersion @EditableField private boolean smartcardEnabled; + @CopyOnNewVersion @EditableField @Size(max = BusinessEntitiesDefinitions.GENERAL_MAX_SIZE) private String isoPath; private OriginType origin; + @CopyOnNewVersion @EditableField @Size(max = BusinessEntitiesDefinitions.GENERAL_MAX_SIZE) @Pattern(regexp = ValidationUtils.NO_TRIMMING_WHITE_SPACES_PATTERN, @@ -149,6 +169,7 @@ UpdateEntity.class }) private String kernelUrl; + @CopyOnNewVersion @EditableField @Size(max = BusinessEntitiesDefinitions.GENERAL_MAX_SIZE) @Pattern(regexp = ValidationUtils.NO_TRIMMING_WHITE_SPACES_PATTERN, @@ -156,6 +177,7 @@ UpdateEntity.class }) private String kernelParams; + @CopyOnNewVersion @EditableField @Size(max = BusinessEntitiesDefinitions.GENERAL_MAX_SIZE) @Pattern(regexp = ValidationUtils.NO_TRIMMING_WHITE_SPACES_PATTERN, @@ -163,12 +185,14 @@ UpdateEntity.class }) private String initrdUrl; + @CopyOnNewVersion @EditableField private boolean allowConsoleReconnect; /** * if this field is null then value should be taken from cluster */ + @CopyOnNewVersion @EditableField private Boolean tunnelMigration; @@ -229,11 +253,13 @@ @EditableField private QuotaEnforcementTypeEnum quotaEnforcementType; + @CopyOnNewVersion @EditableOnVmStatusField @EditableOnTemplate @OvfExportOnlyField(valueToIgnore = "MIGRATABLE", exportOption = ExportOption.EXPORT_NON_IGNORED_VALUES) private MigrationSupport migrationSupport; + @CopyOnNewVersion @EditableOnVmStatusField @EditableOnTemplate private Guid dedicatedVmForVds; @@ -242,6 +268,7 @@ @EditableOnTemplate private DisplayType defaultDisplayType; + @CopyOnNewVersion @EditableOnVmStatusField @EditableOnTemplate @NullOrStringContainedInConfigValueList(configValue = ConfigValues.VncKeyboardLayoutValidValues, @@ -249,9 +276,11 @@ message = "VALIDATION.VM.INVALID_KEYBOARD_LAYOUT") private String vncKeyboardLayout; + @CopyOnNewVersion @EditableField private int minAllocatedMem; + @CopyOnNewVersion @EditableField private boolean runAndPause; 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 d867358..adfbdcb 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 @@ -102,6 +102,7 @@ VAR__ACTION__EXTEND_IMAGE_SIZE, VAR__ACTION__REMOVE_BRICKS_STOP, VAR__ACTION__REMOVE_BRICKS_COMMIT, + VAR__ACTION__UPDATE_VM_VERSION, // Host statuses replacements VAR__HOST_STATUS__UP, @@ -161,6 +162,8 @@ ACTION_TYPE_FAILED_CANNOT_USE_LATEST_WITH_CLONE(ErrorType.BAD_PARAMETERS), ACTION_TYPE_FAILED_VM_NOT_EXIST(ErrorType.BAD_PARAMETERS), ACTION_TYPE_FAILED_VM_ALREADY_EXIST(ErrorType.CONFLICT), + ACTION_TYPE_FAILED_VM_NOT_SET_FOR_LATEST(ErrorType.BAD_PARAMETERS), + ACTION_TYPE_FAILED_VM_ALREADY_IN_LATEST_VERSION(ErrorType.BAD_PARAMETERS), ACTION_TYPE_FAILED_VM_GUID_ALREADY_EXIST(ErrorType.CONFLICT), ACTION_TYPE_FAILED_VM_ATTACHED_TO_POOL(ErrorType.CONFLICT), ACTION_TYPE_FAILED_VM_STATUS_ILLEGAL(ErrorType.CONFLICT), 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 9e2ac37..7c3a3e3 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 @@ -290,4 +290,15 @@ * @return */ List<VM> getAllRunningByCluster(Guid clusterId); + + /** + * Retrieves all ids of vms that are candidate for version update for this base template: + * template_version_number is set to null + * status is down + * vm is stateless or belong to vm pool + * (for vm in pool, check there is no stateless snapshot for it [manual pool]) + * + * @return the list of ids of these vms + */ + List<Guid> getVmIdsForVersionUpdate(Guid baseTemplateId); } 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 d1349dc..8984322 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 @@ -277,6 +277,13 @@ .addValue("cluster_id", clusterId)); } + @Override + public List<Guid> getVmIdsForVersionUpdate(Guid baseTemplateId) { + return getCallsHandler().executeReadList("getVmIdsForVersionUpdate", + createGuidMapper(), getCustomMapSqlParameterSource() + .addValue("base_template_id", baseTemplateId)); + } + static final class VMRowMapper implements RowMapper<VM> { public static final VMRowMapper instance = new VMRowMapper(); diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmStaticDAO.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmStaticDAO.java index 073abc4..9dfa337 100644 --- a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmStaticDAO.java +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmStaticDAO.java @@ -85,4 +85,11 @@ public void incrementDbGeneration(Guid id); List<Guid> getOrderedVmGuidsForRunMultipleActions(List<Guid> guids); + + /** + * remove with optionally remove/keep vm permissions + * @param id vm to remove + * @param removePermissions flag to indicate if to remove the permissions or keep them + */ + public void remove(Guid id, boolean removePermissions); } diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmStaticDAODbFacadeImpl.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmStaticDAODbFacadeImpl.java index 6552eb1..69328e7 100644 --- a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmStaticDAODbFacadeImpl.java +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmStaticDAODbFacadeImpl.java @@ -104,7 +104,13 @@ @Override public void remove(Guid id) { - getCallsHandler().executeModification("DeleteVmStatic", getIdParamterSource(id)); + remove(id, true); + } + + public void remove(Guid id, boolean removePermissions) { + getCallsHandler().executeModification("DeleteVmStatic", + getIdParamterSource(id) + .addValue("remove_permissions", removePermissions)); } private MapSqlParameterSource getIdParamterSource(Guid id) { @@ -179,7 +185,7 @@ public Long getDbGeneration(Guid id) { return getCallsHandler().executeRead("GetDbGeneration", getLongMapper() , getCustomMapSqlParameterSource() - .addValue("vm_guid", id)); + .addValue("vm_guid", id)); } public List<Guid> getOrderedVmGuidsForRunMultipleActions(List<Guid> guids) { 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 3c97e10..1307857 100644 --- a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties +++ b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties @@ -173,6 +173,8 @@ ACTION_TYPE_FAILED_VM_IN_USE_BY_OTHER_USER=Cannot ${action} ${type}. The VM is in use by other user. ACTION_TYPE_FAILED_VM_NOT_FOUND=Cannot ${action} ${type}. VM is not found. ACTION_TYPE_FAILED_CANNOT_USE_LATEST_WITH_CLONE=Cannot ${action} ${type}. Cannot use 'Latest Version' when using clone from Template. +ACTION_TYPE_FAILED_VM_NOT_SET_FOR_LATEST=Cannot ${action} ${type}. Vm is set to use a specific version, and not automatically update to the latest version. +ACTION_TYPE_FAILED_VM_ALREADY_IN_LATEST_VERSION=Cannot ${action} ${type}. Vm is already at the latest version. ACTION_TYPE_FAILED_VM_IS_NON_MIGRTABLE=Cannot ${action} ${type}. VM is non migratable. ACTION_TYPE_FAILED_VM_IS_NON_MIGRTABLE_AND_IS_NOT_FORCED_BY_USER_TO_MIGRATE=Cannot ${action} ${type}. VM is non migratable and user did not specify the force-migration flag ACTION_TYPE_FAILED_VM_IS_PINNED_TO_HOST=Cannot ${action} ${type}. VM is pinned to Host. @@ -332,6 +334,7 @@ VAR__ACTION__SCAN_ALIGNMENT=$action scan alignment VAR__ACTION__FORCE_SELECT=$action force select VAR__ACTION__EXTEND_IMAGE_SIZE=$action extend +VAR__ACTION__UPDATE_VM_VERSION=$action update version for VAR__HOST_STATUS__UP=$hostStatus Up VAR__HOST_STATUS__UP_MAINTENANCE_OR_NON_OPERATIONAL=$hostStatus Up, Maintenance or Non operational VAR__HOST_STATUS__UP_OR_MAINTENANCE=$hostStatus 'Up' or 'Maintenance' diff --git a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmDAOTest.java b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmDAOTest.java index 85e57e8..78a97b3 100644 --- a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmDAOTest.java +++ b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmDAOTest.java @@ -27,6 +27,7 @@ private static final Guid USER_ID = new Guid("9bf7c640-b620-456f-a550-0348f366544b"); private static final Guid STORAGE_DOMAIN_ID = new Guid("72e3a666-89e1-4005-a7ca-f7548004a9ab"); private static final Guid POOL_ID = new Guid("103cfd1d-18b1-4790-8a0c-1e52621b0076"); + private static final Guid VM_TO_UPDATE_ID = new Guid("77296e00-0cad-4e5a-9299-008a7b6f5002"); private static final int VM_COUNT = 7; private VmDAO dao; @@ -500,4 +501,11 @@ assertNotNull(result); assertFalse(result.isEmpty()); } + + @Test + public void testGetVmIdsForVersionUpdate() { + List<Guid> vmIdsToUpdate = dao.getVmIdsForVersionUpdate(FixturesTool.VM_TEMPLATE_RHEL5); + + assertTrue(vmIdsToUpdate.contains(VM_TO_UPDATE_ID)); + } } diff --git a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmStaticDAOTest.java b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmStaticDAOTest.java index 07a99d9..0d27169 100644 --- a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmStaticDAOTest.java +++ b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmStaticDAOTest.java @@ -181,6 +181,24 @@ dao.remove(EXISTING_VM_ID); VmStatic result = dao.get(EXISTING_VM_ID); assertNull(result); + PermissionDAO permissionsDao = dbFacade.getPermissionDao(); + assertEquals("vm permissions wasn't removed", 0, permissionsDao.getAllForEntity(EXISTING_VM_ID).size()); + } + + @Test + public void testRemoveWithoutPermissions() { + for (Snapshot s : dbFacade.getSnapshotDao().getAll()) { + dbFacade.getSnapshotDao().remove(s.getId()); + } + + PermissionDAO permissionsDao = dbFacade.getPermissionDao(); + int numberOfPermissionsBeforeRemove = permissionsDao.getAllForEntity(EXISTING_VM_ID).size(); + + dao.remove(EXISTING_VM_ID, false); + VmStatic result = dao.get(EXISTING_VM_ID); + assertNull(result); + + assertEquals("vm permissions changed during remove although shouldnt have.", numberOfPermissionsBeforeRemove, permissionsDao.getAllForEntity(EXISTING_VM_ID).size()); } @Test diff --git a/backend/manager/modules/dal/src/test/resources/fixtures.xml b/backend/manager/modules/dal/src/test/resources/fixtures.xml index bf4d6d0..bf8bf30 100644 --- a/backend/manager/modules/dal/src/test/resources/fixtures.xml +++ b/backend/manager/modules/dal/src/test/resources/fixtures.xml @@ -2362,7 +2362,7 @@ <null /> <value>1</value> <value></value> - <value>0</value> + <value>1</value> <value>1</value> <value>2010-11-18 11:13:24</value> <null /> 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 3825f02..5801437 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 @@ -445,6 +445,12 @@ @DefaultStringValue("Cannot ${action} ${type}. Cannot use 'Latest Version' when using clone from Template.") String ACTION_TYPE_FAILED_CANNOT_USE_LATEST_WITH_CLONE(); + @DefaultStringValue("Cannot ${action} ${type}. Vm is set to use a specific version, and not automatically update to the latest version.") + String ACTION_TYPE_FAILED_VM_NOT_SET_FOR_LATEST(); + + @DefaultStringValue("Cannot ${action} ${type}. Vm is already at the latest version.") + String ACTION_TYPE_FAILED_VM_ALREADY_IN_LATEST_VERSION(); + @DefaultStringValue("Cannot ${action} ${type}. VM is non migratable.") String ACTION_TYPE_FAILED_VM_IS_NON_MIGRTABLE(); @@ -910,6 +916,9 @@ @DefaultStringValue("$action disable") String VAR__ACTION__DISABLE(); + @DefaultStringValue("$action update version for") + String VAR__ACTION__UPDATE_VM_VERSION(); + @DefaultStringValue("$hostStatus Up") String VAR__HOST_STATUS__UP(); 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 5149a20..bae94da 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 @@ -166,6 +166,8 @@ ACTION_TYPE_FAILED_VM_IN_USE_BY_OTHER_USER=Cannot ${action} ${type}. The VM is in use by other user. ACTION_TYPE_FAILED_VM_NOT_FOUND=Cannot ${action} ${type}. VM is not found. ACTION_TYPE_FAILED_CANNOT_USE_LATEST_WITH_CLONE=Cannot ${action} ${type}. Cannot use 'Latest Version' when using clone from Template. +ACTION_TYPE_FAILED_VM_NOT_SET_FOR_LATEST=Cannot ${action} ${type}. Vm is set to use a specific version, and not automatically update to the latest version. +ACTION_TYPE_FAILED_VM_ALREADY_IN_LATEST_VERSION=Cannot ${action} ${type}. Vm is already at the latest version. ACTION_TYPE_FAILED_VM_IS_NON_MIGRTABLE=Cannot ${action} ${type}. VM is non migratable. ACTION_TYPE_FAILED_VM_IS_NON_MIGRTABLE_AND_IS_NOT_FORCED_BY_USER_TO_MIGRATE=Cannot ${action} ${type}. VM is non migratable and user did not specify the force-migration flag ACTION_TYPE_FAILED_VM_IS_PINNED_TO_HOST=Cannot ${action} ${type}. VM is pinned to Host. @@ -311,6 +313,7 @@ VAR__ACTION__ASSIGN=$action assign VAR__ACTION__SCAN_ALIGNMENT=$action scan alignment VAR__ACTION__EXTEND_IMAGE_SIZE=$action extend +VAR__ACTION__UPDATE_VM_VERSION=$action update version for VAR__HOST_STATUS__UP=$hostStatus Up VAR__HOST_STATUS__UP_MAINTENANCE_OR_NON_OPERATIONAL=$hostStatus Up, Maintenance or Non operational VAR__HOST_STATUS__UP_OR_MAINTENANCE=$hostStatus 'Up' or 'Maintenance' 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 8f3559c..3e7aa6e 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 @@ -170,6 +170,8 @@ ACTION_TYPE_FAILED_VM_IN_USE_BY_OTHER_USER=Cannot ${action} ${type}. The VM is in use by other user. ACTION_TYPE_FAILED_VM_NOT_FOUND=Cannot ${action} ${type}. VM is not found. ACTION_TYPE_FAILED_CANNOT_USE_LATEST_WITH_CLONE=Cannot ${action} ${type}. Cannot use 'Latest Version' when using clone from Template. +ACTION_TYPE_FAILED_VM_NOT_SET_FOR_LATEST=Cannot ${action} ${type}. Vm is set to use a specific version, and not automatically update to the latest version. +ACTION_TYPE_FAILED_VM_ALREADY_IN_LATEST_VERSION=Cannot ${action} ${type}. Vm is already at the latest version. ACTION_TYPE_FAILED_VM_IS_NON_MIGRTABLE=Cannot ${action} ${type}. VM is non migratable. ACTION_TYPE_FAILED_VM_IS_NON_MIGRTABLE_AND_IS_NOT_FORCED_BY_USER_TO_MIGRATE=Cannot ${action} ${type}. VM is non migratable and user did not specify the force-migration flag ACTION_TYPE_FAILED_VM_IS_PINNED_TO_HOST=Cannot ${action} ${type}. VM is pinned to Host. @@ -335,6 +337,7 @@ VAR__ACTION__SCAN_ALIGNMENT=$action scan alignment VAR__ACTION__FORCE_SELECT=$action force select VAR__ACTION__EXTEND_IMAGE_SIZE=$action extend +VAR__ACTION__UPDATE_VM_VERSION=$action update version for VAR__HOST_STATUS__UP=$hostStatus Up VAR__HOST_STATUS__UP_MAINTENANCE_OR_NON_OPERATIONAL=$hostStatus Up, Maintenance or Non operational VAR__HOST_STATUS__UP_OR_MAINTENANCE=$hostStatus 'Up' or 'Maintenance' diff --git a/packaging/dbscripts/vms_sp.sql b/packaging/dbscripts/vms_sp.sql index 10bed79..5c2cde2 100644 --- a/packaging/dbscripts/vms_sp.sql +++ b/packaging/dbscripts/vms_sp.sql @@ -620,7 +620,7 @@ -Create or replace FUNCTION DeleteVmStatic(v_vm_guid UUID) +Create or replace FUNCTION DeleteVmStatic(v_vm_guid UUID, v_remove_permissions boolean) RETURNS VOID AS $procedure$ DECLARE @@ -634,7 +634,9 @@ AND entity_type = 'VM'; -- delete VM permissions -- - DELETE FROM permissions where object_id = v_vm_guid; + if v_remove_permissions then + DELETE FROM permissions where object_id = v_vm_guid; + end if; END; $procedure$ LANGUAGE plpgsql; @@ -1154,3 +1156,22 @@ END; $procedure$ LANGUAGE plpgsql; + +Create or replace FUNCTION GetVmIdsForVersionUpdate(v_base_template_id UUID) RETURNS SETOF UUID STABLE +AS $procedure$ +BEGIN +RETURN QUERY select vs.vm_guid + from vm_static vs + natural join vm_dynamic + where (vmt_guid = v_base_template_id or vmt_guid in + (select vm_guid from vm_static where vmt_guid = v_base_template_id)) + and template_version_number is null and entity_type='VM' and status=0 + and (is_stateless = TRUE or + (exists (select * from vm_pool_map where vm_guid = vs.vm_guid) + and not exists + (SELECT * + FROM snapshots + WHERE vm_id = vs.vm_guid + AND snapshot_type = 'STATELESS'))); +END; $procedure$ +LANGUAGE plpgsql; -- To view, visit http://gerrit.ovirt.org/23610 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5449eee954bd6096b6f2e423a75a8cac3e5bcc3b Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: ovirt-engine-3.4 Gerrit-Owner: Omer Frenkel <ofren...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches