Omer Frenkel has uploaded a new change for review.

Change subject: core: add support to update running vm
......................................................................

core: add support to update running vm

Change-Id: Ie433352852f53f62e58349ce85475ee89e37ce89
Signed-off-by: Omer Frenkel <[email protected]>
---
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/VmHandler.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolHandler.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VmManagementParametersBase.java
M 
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ObjectIdentityChecker.java
5 files changed, 173 insertions(+), 6 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/58/26758/1

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 fd7e711..bd8e80c 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
@@ -15,6 +15,7 @@
 import org.ovirt.engine.core.bll.quota.QuotaSanityParameter;
 import org.ovirt.engine.core.bll.quota.QuotaVdsDependent;
 import org.ovirt.engine.core.bll.quota.QuotaVdsGroupConsumptionParameter;
+import org.ovirt.engine.core.bll.snapshots.SnapshotsManager;
 import org.ovirt.engine.core.bll.utils.PermissionSubject;
 import org.ovirt.engine.core.bll.utils.VmDeviceUtils;
 import org.ovirt.engine.core.bll.validator.VmWatchdogValidator;
@@ -31,6 +32,7 @@
 import org.ovirt.engine.core.common.businessentities.Disk;
 import org.ovirt.engine.core.common.businessentities.DiskInterface;
 import org.ovirt.engine.core.common.businessentities.MigrationSupport;
+import org.ovirt.engine.core.common.businessentities.Snapshot;
 import org.ovirt.engine.core.common.businessentities.VM;
 import org.ovirt.engine.core.common.businessentities.VMStatus;
 import org.ovirt.engine.core.common.businessentities.VmDevice;
@@ -51,8 +53,10 @@
 import org.ovirt.engine.core.common.validation.group.UpdateVm;
 import org.ovirt.engine.core.compat.DateTime;
 import org.ovirt.engine.core.compat.Guid;
+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.SnapshotDao;
 import org.ovirt.engine.core.dao.VmDeviceDAO;
 import org.ovirt.engine.core.utils.customprop.ValidationError;
 import org.ovirt.engine.core.utils.customprop.VmPropertiesUtils;
@@ -87,6 +91,10 @@
 
     @Override
     protected void executeVmCommand() {
+        if (isRunningConfigurationNeeded()) {
+            createNextRunSnapshot();
+        }
+
         oldVm = getVm();
         VmHandler.warnMemorySizeLegal(getParameters().getVm().getStaticData(), 
getVdsGroup().getcompatibility_version());
         getVmStaticDAO().incrementDbGeneration(getVm().getId());
@@ -95,15 +103,48 @@
         if (newVmStatic.getCreationDate().equals(DateTime.getMinValue())) {
             newVmStatic.setCreationDate(new Date());
         }
+
+        if (getVm().isRunningOrPaused()) {
+            
VmHandler.CopyNonEditableFieldsToDestination(oldVm.getStaticData(), 
newVmStatic);
+        }
+
         UpdateVmNetworks();
-        hotSetCpus();
+        if (!getParameters().isApplyChangesLater()) {
+            hotSetCpus();
+        }
         getVmStaticDAO().update(newVmStatic);
-        updateVmPayload();
-        VmDeviceUtils.updateVmDevices(getParameters(), oldVm);
-        updateWatchdog();
-        checkTrustedService();
+        if (getVm().isNotRunning()) {
+            updateVmPayload();
+            VmDeviceUtils.updateVmDevices(getParameters(), oldVm);
+            updateWatchdog();
+        }
         VmHandler.updateVmInitToDB(getParameters().getVmStaticData());
+
+        checkTrustedService();
         setSucceeded(true);
+    }
+
+    private void createNextRunSnapshot() {
+        // first remove existing snapshot
+        Snapshot runSnap = getSnapshotDao().get(getVmId(), 
Snapshot.SnapshotType.NEXT_RUN);
+        if (runSnap != null) {
+            getSnapshotDao().remove(runSnap.getId());
+        }
+
+        // create new snapshot with new configuration
+        new SnapshotsManager().addSnapshot(Guid.newGuid(),
+                "Next Run configuration snapshot",
+                Snapshot.SnapshotStatus.OK,
+                Snapshot.SnapshotType.NEXT_RUN,
+                getVm(),
+                true,
+                StringUtils.EMPTY,
+                Collections.EMPTY_LIST,
+                getCompensationContext());
+    }
+
+    protected SnapshotDao getSnapshotDao() {
+        return DbFacade.getInstance().getSnapshotDao();
     }
 
     private void hotSetCpus() {
@@ -501,7 +542,18 @@
     protected boolean areUpdatedFieldsLegal() {
         return VmHandler.isUpdateValid(getVm().getStaticData(),
                 getParameters().getVmStaticData(),
-                getVm().getStatus());
+                VMStatus.Down);
+    }
+
+    /**
+     * check if we need to use running-configuration
+     * @return true if vm is running and we change field that has 
@EditableOnVmStatusField annotation
+     *          or runningConfiguration already exist
+     */
+    private boolean isRunningConfigurationNeeded() {
+        return !VmHandler.isUpdateValid(getVm().getStaticData(),
+                getParameters().getVmStaticData(),
+                getVm().getStatus()) || getVm().isNextRunConfigurationExists();
     }
 
     @Override
@@ -571,6 +623,15 @@
     }
 
     @Override
+    protected Map<String, Pair<String, String>> getSharedLocks() {
+        return Collections.singletonMap(
+                getVmId().toString(),
+                LockMessagesMatchUtil.makeLockingPair(
+                        LockingGroup.VM,
+                        VdcBllMessages.ACTION_TYPE_FAILED_OBJECT_LOCKED));
+    }
+
+    @Override
     public List<QuotaConsumptionParameter> getQuotaVdsConsumptionParameters() {
         List<QuotaConsumptionParameter> list = new 
ArrayList<QuotaConsumptionParameter>();
 
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 14c7f87..0f9bc30 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
@@ -135,6 +135,10 @@
         return mUpdateVmsStatic.IsUpdateValid(source, destination);
     }
 
+    public static boolean CopyNonEditableFieldsToDestination(VmStatic source, 
VmStatic destination) {
+        return mUpdateVmsStatic.CopyNonEditableFieldsToDestination(source, 
destination);
+    }
+
     /**
      * Verifies the add vm command .
      *
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolHandler.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolHandler.java
index cfaddcc..59bc380 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolHandler.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolHandler.java
@@ -1,17 +1,26 @@
 package org.ovirt.engine.core.bll;
 
+import java.util.Date;
 import java.util.List;
 
 import org.ovirt.engine.core.bll.context.CommandContext;
 import org.ovirt.engine.core.bll.quota.QuotaManager;
+import org.ovirt.engine.core.bll.snapshots.SnapshotsManager;
 import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.action.VmManagementParametersBase;
 import org.ovirt.engine.core.common.action.VmOperationParameterBase;
 import org.ovirt.engine.core.common.action.VmPoolSimpleUserParameters;
 import org.ovirt.engine.core.common.businessentities.DbUser;
+import org.ovirt.engine.core.common.businessentities.Snapshot;
 import org.ovirt.engine.core.common.businessentities.Snapshot.SnapshotType;
+import org.ovirt.engine.core.common.businessentities.VM;
+import org.ovirt.engine.core.common.businessentities.VmDevice;
+import org.ovirt.engine.core.common.businessentities.VmPayload;
 import org.ovirt.engine.core.common.businessentities.VmPool;
 import org.ovirt.engine.core.common.businessentities.VmPoolMap;
 import org.ovirt.engine.core.common.businessentities.VmPoolType;
+import org.ovirt.engine.core.common.businessentities.VmWatchdog;
+import org.ovirt.engine.core.common.utils.VmDeviceType;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.dal.dbbroker.DbFacade;
 import org.ovirt.engine.core.utils.log.Log;
@@ -50,6 +59,57 @@
 
         QuotaManager.getInstance().rollbackQuotaByVmId(vmId);
         VmHandler.removeStatelessVmUnmanagedDevices(vmId);
+
+        // apply running configuration
+        Snapshot runSnap = DbFacade.getInstance().getSnapshotDao().get(vmId, 
Snapshot.SnapshotType.NEXT_RUN);
+        if (runSnap != null) {
+            DbFacade.getInstance().getSnapshotDao().remove(runSnap.getId());
+            VM vm = DbFacade.getInstance().getVmDao().get(vmId);
+            if (vm != null) {
+                Date originalCreationDate = vm.getVmCreationDate();
+                new SnapshotsManager().updateVmFromConfiguration(vm, 
runSnap.getVmConfiguration());
+                // override creation date because the value in the config is 
the creation date of the config, not the vm
+                vm.setVmCreationDate(originalCreationDate);
+                vm.setExportDate(null);
+                vm.setOvfVersion(null);
+
+                VmManagementParametersBase updateVmParams = new 
VmManagementParametersBase(vm);
+                updateVmParams.setUpdateWatchdog(true);
+                updateVmParams.setSoundDeviceEnabled(false);
+                updateVmParams.setBalloonEnabled(false);
+                updateVmParams.setVirtioScsiEnabled(false);
+                updateVmParams.setClearPayload(true);
+
+                for (VmDevice device : vm.getManagedVmDeviceMap().values()) {
+                    switch (device.getType()) {
+                        case WATCHDOG:
+                            updateVmParams.setWatchdog(new VmWatchdog(device));
+                            break;
+                        case SOUND:
+                            updateVmParams.setSoundDeviceEnabled(true);
+                            break;
+                        case BALLOON:
+                            updateVmParams.setBalloonEnabled(true);
+                            break;
+                        case CONTROLLER:
+                            if 
(VmDeviceType.VIRTIOSCSI.getName().equals(device.getDevice())) {
+                                updateVmParams.setVirtioScsiEnabled(true);
+                            }
+                            break;
+                        case DISK:
+                            if (VmPayload.isPayload(device.getSpecParams())) {
+                                updateVmParams.setVmPayload(new 
VmPayload(VmDeviceType.getByName(device.getDevice()), device.getSpecParams()));
+                            }
+                            break;
+                        case CONSOLE:
+                            updateVmParams.setConsoleEnabled(true);
+                    }
+                }
+                vm.getManagedVmDeviceMap().clear();
+                vm.getVmUnamagedDeviceList().clear();
+                
Backend.getInstance().runInternalAction(VdcActionType.UpdateVm, updateVmParams);
+            }
+        }
     }
 
     public static void removeVmStatelessImages(Guid vmId, CommandContext 
context) {
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VmManagementParametersBase.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VmManagementParametersBase.java
index 143a3c9..80a390b 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VmManagementParametersBase.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VmManagementParametersBase.java
@@ -26,6 +26,7 @@
     private VM vm;
     private VmWatchdog watchdog;
     private boolean copyTemplatePermissions;
+    private boolean applyChangesLater;
 
     /*
      * This parameter is needed at update to make sure that when we get a null 
watchdog from rest-api it is not meant to
@@ -197,4 +198,12 @@
     public void setVirtioScsiEnabled(Boolean virtioScsiEnabled) {
         this.virtioScsiEnabled = virtioScsiEnabled;
     }
+
+    public boolean isApplyChangesLater() {
+        return applyChangesLater;
+    }
+
+    public void setApplyChangesLater(boolean applyChangesLater) {
+        this.applyChangesLater = applyChangesLater;
+    }
 }
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 f1a6612..d5bb2f6 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
@@ -1,5 +1,7 @@
 package org.ovirt.engine.core.utils;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -102,6 +104,37 @@
         return returnValue;
     }
 
+    /**
+     * This method will copy all fields that are not @editable from source obj 
to dest obj
+     *
+     * @param source object that has values of non editable fields
+     * @param destination object to copy the non editable to it
+     */
+    public boolean CopyNonEditableFieldsToDestination(Object source, Object 
destination) {
+        Class<?> srcCls = source.getClass();
+        Class<?> dstCls = destination.getClass();
+        while (!srcCls.equals(Object.class)) {
+        for (Field srcFld : srcCls.getDeclaredFields())
+            try {
+                if (!Modifier.isFinal(srcFld.getModifiers()) && 
!IsFieldUpdatable(srcFld.getName())) {
+                    srcFld.setAccessible(true);
+
+                    Field dstFld = dstCls.getDeclaredField(srcFld.getName());
+                    dstFld.setAccessible(true);
+                    dstFld.set(destination, srcFld.get(source));
+                }
+            } catch (Exception exp) {
+                log.errorFormat("Failed to copy non editable field {0}, error: 
{1}",
+                        srcFld.getName(),
+                        exp.getMessage());
+                return false;
+            }
+            srcCls = srcCls.getSuperclass();
+            dstCls = dstCls.getSuperclass();
+        }
+        return true;
+    }
+
     public final boolean IsUpdateValid(Object source, Object destination) {
         if (source.getClass() != destination.getClass()) {
             return false;


-- 
To view, visit http://gerrit.ovirt.org/26758
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie433352852f53f62e58349ce85475ee89e37ce89
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Omer Frenkel <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to