Ravi Nori has uploaded a new change for review.

Change subject: core, engine, webadmin: Maintenance operations on a VM would 
ask for an optional reason
......................................................................

core, engine, webadmin: Maintenance operations on a VM would ask for an 
optional reason

When a VM is shutdown/powered off from the mananger there's
an optional "reason" field where the administrator can write
a free-form explanation for the maintenance, which would be
bought to attention in the logs and when/if someone attempts
to power on.

Adds a Reson column to VMs tab which is populated if a
reson was specified during shutdown/power off operations.

Change-Id: I17645e5bc97a1a4d460956ec45f88524465dfd7b
Bug-Url: https://bugzilla.redhat.com/1065753
Signed-off-by: Ravi Nori <[email protected]>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ShutdownVmCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/StopVmCommandBase.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/ShutdownVmParameters.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/StopVmParameters.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VmOperationParameterBase.java
A 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/Reasoned.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VM.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmDynamic.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/DestroyVmVDSCommandParameters.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.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/VmDynamicDAODbFacadeImpl.java
M 
backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
M 
backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd
M 
backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/VmMapper.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/DestroyVmVDSCommand.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/gin/BasePresenterModule.java
A 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/presenter/popup/RemoveConfirmationWithCommentPopupPresenterWidget.java
A 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/AbstractConfirmationWithCommentPopupView.java
A 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/RemoveConfirmationWithCommentPopupView.java
A 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/RemoveConfirmationWithCommentPopupView.ui.xml
M 
frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml
A 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/ConfirmationWithReasonModel.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmListModel.java
M 
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VirtualMachineModule.java
M 
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVirtualMachineView.java
A 
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/table/column/ReasonColumn.java
M packaging/dbscripts/create_views.sql
A packaging/dbscripts/upgrade/03_05_0110_add_vm_dynamic_reason.sql
M packaging/dbscripts/vms_sp.sql
33 files changed, 492 insertions(+), 46 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/33/25633/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ShutdownVmCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ShutdownVmCommand.java
index 87f284b..09da20f 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ShutdownVmCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ShutdownVmCommand.java
@@ -60,7 +60,7 @@
                     .getInstance()
                     .getResourceManager()
                     .RunVdsCommand(VDSCommandType.DestroyVm,
-                            new DestroyVmVDSCommandParameters(getVdsId(), 
getVmId(), false, true, secondsToWait))
+                            new DestroyVmVDSCommandParameters(getVdsId(), 
getVmId(), getParameters().getReason(), false, true, secondsToWait))
                     .getReturnValue());
         }
         else {
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/StopVmCommandBase.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/StopVmCommandBase.java
index af40379..e95c2ee 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/StopVmCommandBase.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/StopVmCommandBase.java
@@ -74,14 +74,14 @@
                     .RunVdsCommand(
                             VDSCommandType.DestroyVm,
                             new DestroyVmVDSCommandParameters(new 
Guid(getVm().getMigratingToVds().toString()),
-                                    getVmId(), true, false, 0));
+                                    getVmId(), getParameters().getReason(), 
true, false, 0));
         }
 
         setActionReturnValue(Backend
                 .getInstance()
                 .getResourceManager()
                 .RunVdsCommand(VDSCommandType.DestroyVm,
-                        new DestroyVmVDSCommandParameters(getVdsId(), 
getVmId(), false, false, 0)).getReturnValue());
+                        new DestroyVmVDSCommandParameters(getVdsId(), 
getVmId(), getParameters().getReason(), false, false, 0)).getReturnValue());
     }
 
     @Override
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 f02027f..58d2b7a 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
@@ -59,6 +59,7 @@
     public VmCommand(T parameters) {
         super(parameters);
         setVmId(parameters.getVmId());
+        setReason(parameters.getReason());
     }
 
     @Override
@@ -535,6 +536,7 @@
     }
 
     protected boolean canRunActionOnNonManagedVm() {
+        getVmName();
         ValidationResult nonManagedVmValidationResult = 
VmHandler.canRunActionOnNonManagedVm(getVm(), this.getActionType());
         if (!nonManagedVmValidationResult.isValid()) {
             return failCanDoAction(nonManagedVmValidationResult.getMessage());
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/ShutdownVmParameters.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/ShutdownVmParameters.java
index 0175cce..0e5103a 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/ShutdownVmParameters.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/ShutdownVmParameters.java
@@ -4,15 +4,20 @@
 
 public class ShutdownVmParameters extends VmOperationParameterBase implements 
java.io.Serializable {
     private static final long serialVersionUID = 7007574816935458890L;
-    private boolean _waitBeforeShutdown;
+    private boolean waitBeforeShutdown;
 
     public ShutdownVmParameters() {
-        _waitBeforeShutdown = true;
+        waitBeforeShutdown = true;
     }
 
     public ShutdownVmParameters(Guid vmID, boolean waitBeforeShutdown) {
+        this(vmID, waitBeforeShutdown, null);
+    }
+
+    public ShutdownVmParameters(Guid vmID, boolean waitBeforeShutdown, String 
reason) {
         super(vmID);
-        _waitBeforeShutdown = waitBeforeShutdown;
+        this.waitBeforeShutdown = waitBeforeShutdown;
+        setReason(reason);
     }
 
     /**
@@ -20,11 +25,11 @@
      * message is displayed within the guest.
      */
     public boolean getWaitBeforeShutdown() {
-        return _waitBeforeShutdown;
+        return waitBeforeShutdown;
     }
 
     public void setWaitBeforeShutdown(boolean value) {
-        _waitBeforeShutdown = value;
+        waitBeforeShutdown = value;
     }
 
 }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/StopVmParameters.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/StopVmParameters.java
index 628afee..b2c0b1e 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/StopVmParameters.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/StopVmParameters.java
@@ -4,22 +4,28 @@
 
 public class StopVmParameters extends VmOperationParameterBase implements 
java.io.Serializable {
     private static final long serialVersionUID = -1331508207367552128L;
-    private StopVmTypeEnum _stopVmType;
+    private StopVmTypeEnum stopVmType;
+
+    public StopVmParameters() {
+        stopVmType = StopVmTypeEnum.NORMAL;
+    }
 
     public StopVmParameters(Guid vmID, StopVmTypeEnum stopVmType) {
+        this(vmID, stopVmType, "");
+    }
+
+    public StopVmParameters(Guid vmID, StopVmTypeEnum stopVmType, String 
reason) {
         super(vmID);
-        _stopVmType = stopVmType;
+        this.stopVmType = stopVmType;
+        setReason(reason);
     }
 
     public StopVmTypeEnum getStopVmType() {
-        return _stopVmType;
+        return stopVmType;
     }
 
     public void setStopVmType(StopVmTypeEnum value) {
-        _stopVmType = value;
+        stopVmType = value;
     }
 
-    public StopVmParameters() {
-        _stopVmType = StopVmTypeEnum.NORMAL;
-    }
 }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VmOperationParameterBase.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VmOperationParameterBase.java
index f7a566b..c64ded7 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VmOperationParameterBase.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VmOperationParameterBase.java
@@ -5,6 +5,7 @@
 public class VmOperationParameterBase extends VdcActionParametersBase 
implements java.io.Serializable {
     private static final long serialVersionUID = -6248335374537898949L;
     private Guid quotaId;
+    private String reason;
 
     public VmOperationParameterBase() {
         vmId = Guid.Empty;
@@ -31,4 +32,8 @@
     public void setQuotaId(Guid value) {
         quotaId = value;
     }
+
+    public String getReason() { return reason; }
+
+    public void setReason(String value) { reason = value; }
 }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/Reasoned.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/Reasoned.java
new file mode 100644
index 0000000..ccc33b1
--- /dev/null
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/Reasoned.java
@@ -0,0 +1,7 @@
+package org.ovirt.engine.core.common.businessentities;
+
+public interface Reasoned {
+    String getReason();
+
+    void setReason(String value);
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VM.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VM.java
index f4311e3..e4ae286 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VM.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VM.java
@@ -18,7 +18,7 @@
 import org.ovirt.engine.core.compat.StringHelper;
 import org.ovirt.engine.core.compat.Version;
 
-public class VM extends IVdcQueryable implements Serializable, 
BusinessEntityWithStatus<Guid, VMStatus>, HasStoragePool<Guid>, Nameable, 
Commented {
+public class VM extends IVdcQueryable implements Serializable, 
BusinessEntityWithStatus<Guid, VMStatus>, HasStoragePool<Guid>, Nameable, 
Commented, Reasoned {
     private static final long serialVersionUID = -4078140531074414263L;
     @Valid
     private VmStatic vmStatic;
@@ -214,6 +214,14 @@
         this.vmStatic.setComment(value);
     }
 
+    public String getReason() {
+        return this.vmDynamic.getReason();
+    }
+
+    public void setReason(String value) {
+        this.vmDynamic.setReason(value);
+    }
+
     public int getNumOfMonitors() {
         return this.vmStatic.getNumOfMonitors();
     }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmDynamic.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmDynamic.java
index 4f10cfa..4fd6184 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmDynamic.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmDynamic.java
@@ -67,6 +67,7 @@
     @UnchangeableByVdsm
     private String cpuName;
     private String currentCd;
+    private String reason;
 
     public static final String APPLICATIONS_LIST_FIELD_NAME = "appList";
     public static final String STATUS_FIELD_NAME = "status";
@@ -116,6 +117,7 @@
         result = prime * result + (runOnce ? 1231 : 1237);
         result = prime * result + (cpuName == null ? 0 : cpuName.hashCode());
         result = prime * result + (currentCd == null ? 0 : 
currentCd.hashCode());
+        result = prime * result + (reason == null ? 0 : reason.hashCode());
         return result;
     }
 
@@ -171,7 +173,8 @@
                 && ObjectUtils.objectsEqual(lastWatchdogAction, 
other.lastWatchdogAction)
                 && runOnce == other.runOnce
                 && ObjectUtils.objectsEqual(cpuName, other.cpuName)
-                && ObjectUtils.objectsEqual(currentCd, other.currentCd));
+                && ObjectUtils.objectsEqual(currentCd, other.currentCd)
+                && ObjectUtils.objectsEqual(reason, other.reason));
     }
 
     public String getExitMessage() {
@@ -539,4 +542,12 @@
     public void setCurrentCd(String currentCd) {
         this.currentCd = currentCd;
     }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
 }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/DestroyVmVDSCommandParameters.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/DestroyVmVDSCommandParameters.java
index 5db0527..b51cbd0 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/DestroyVmVDSCommandParameters.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/DestroyVmVDSCommandParameters.java
@@ -4,37 +4,46 @@
 
 public class DestroyVmVDSCommandParameters extends VdsAndVmIDVDSParametersBase 
{
     public DestroyVmVDSCommandParameters(Guid vdsId, Guid vmId, boolean force, 
boolean gracefully, int secondsToWait) {
-        super(vdsId, vmId);
-        _force = force;
-        _gracefully = gracefully;
-        _secondsToWait = secondsToWait;
+        this(vdsId, vmId, null, force, gracefully, secondsToWait);
     }
 
-    private boolean _force;
-    private boolean _gracefully;
-    private int _secondsToWait;
+    public DestroyVmVDSCommandParameters(Guid vdsId, Guid vmId, String reason, 
boolean force, boolean gracefully, int secondsToWait) {
+        super(vdsId, vmId);
+        this.force = force;
+        this.gracefully = gracefully;
+        this.secondsToWait = secondsToWait;
+        this.reason = reason;
+    }
+
+    private boolean force;
+    private boolean gracefully;
+    private int secondsToWait;
+    private String reason;
 
     public boolean getForce() {
-        return _force;
+        return force;
     }
 
     public int getSecondsToWait() {
-        return _secondsToWait;
+        return secondsToWait;
     }
 
     public boolean getGracefully() {
-        return _gracefully;
+        return gracefully;
     }
+
+    public String getReason() { return reason == null ? "" : reason; }
 
     public DestroyVmVDSCommandParameters() {
     }
 
     @Override
     public String toString() {
-        return String.format("%s, force=%s, secondsToWait=%s, gracefully=%s",
+        return String.format("%s, force=%s, secondsToWait=%s, gracefully=%s, 
reason=%s",
                 super.toString(),
                 getForce(),
                 getSecondsToWait(),
-                getGracefully());
+                getGracefully(),
+                getReason());
     }
 }
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
index 1426fd5..21e1470 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
@@ -57,6 +57,7 @@
     private Guid mUserId = Guid.Empty;
     private String mUserName;
     private String mVmName;
+    private String mReason;
     private Map<String, String> customValues = Collections.emptyMap();
     private Guid mVdsId;
     private String mVdsName;
@@ -215,6 +216,17 @@
         mVmName = value;
     }
 
+    public String getReason() {
+        if (mReason == null && getVm() != null) {
+            mReason = getVm().getReason();
+        }
+        return mReason;
+    }
+
+    public void setReason(String value) {
+        mReason = value;
+    }
+
     public Guid getVdsIdRef() {
         if (mVdsId == null && getVds() != null) {
             mVdsId = getVds().getId();
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 1a67cdc..e0da25f 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
@@ -419,6 +419,7 @@
             entity.setUseLatestVersion(rs.getObject("template_version_number") 
==
                     
VmStaticDAODbFacadeImpl.USE_LATEST_VERSION_NUMBER_INDICATOR);
             entity.setCurrentCd(rs.getString("current_cd"));
+            entity.setReason(rs.getString("reason"));
             return entity;
         }
     }
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDynamicDAODbFacadeImpl.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDynamicDAODbFacadeImpl.java
index 8cf6cec..177fa37 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDynamicDAODbFacadeImpl.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmDynamicDAODbFacadeImpl.java
@@ -115,7 +115,8 @@
                 .addValue("last_watchdog_action", vm.getLastWatchdogAction())
                 .addValue("is_run_once", vm.isRunOnce())
                 .addValue("cpu_name", vm.getCpuName())
-                .addValue("current_cd", vm.getCurrentCd());
+                .addValue("current_cd", vm.getCurrentCd())
+                .addValue("reason", vm.getReason());
     }
 
     @Override
@@ -180,6 +181,7 @@
                 entity.setRunOnce(rs.getBoolean("is_run_once"));
                 entity.setCpuName(rs.getString("cpu_name"));
                 entity.setCurrentCd(rs.getString("current_cd"));
+                entity.setReason(rs.getString("reason"));
                 return entity;
             }
         };
@@ -230,7 +232,8 @@
                         .addValue("last_watchdog_action", 
entity.getLastWatchdogAction())
                         .addValue("is_run_once", entity.isRunOnce())
                         .addValue("cpu_name", entity.getCpuName())
-                        .addValue("current_cd", entity.getCurrentCd());
+                        .addValue("current_cd", entity.getCurrentCd())
+                        .addValue("reason", entity.getReason());
 
                 return paramValue;
             }
diff --git 
a/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
 
b/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
index 8821f09..df86156 100644
--- 
a/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
+++ 
b/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
@@ -74,9 +74,9 @@
 USER_RUN_VM_AS_STATELESS_WITH_DISKS_NOT_ALLOWING_SNAPSHOT=VM ${VmName} was run 
as stateless with one or more of disks that do not allow snapshots 
(User:${UserName}).
 USER_RUN_VM_FAILURE_STATELESS_SNAPSHOT_LEFT=Failed to start VM ${VmName}, 
because exist snapshot for stateless state. Snapshot will be deleted.
 USER_FAILED_STOP_VM=Failed to power off VM ${VmName} (Host: ${VdsName}, User: 
${UserName}).
-USER_INITIATED_SHUTDOWN_VM=VM shutdown initiated by ${UserName} on VM 
${VmName} (Host: ${VdsName}).
+USER_INITIATED_SHUTDOWN_VM=VM shutdown initiated by ${UserName} on VM 
${VmName} (Host: ${VdsName}) (Reason: ${Reason}).
 USER_FAILED_SHUTDOWN_VM=Failed to initiate shutdown on VM ${VmName} (Host: 
${VdsName}, User: ${UserName}).
-USER_STOPPED_VM_INSTEAD_OF_SHUTDOWN=VM ${VmName} was powered off ungracefully 
by ${UserName} (Host: ${VdsName}).
+USER_STOPPED_VM_INSTEAD_OF_SHUTDOWN=VM ${VmName} was powered off ungracefully 
by ${UserName} (Host: ${VdsName}) (Reason: ${Reason}).
 USER_FAILED_STOPPING_VM_INSTEAD_OF_SHUTDOWN=Failed to power off VM ${VmName} 
(Host: ${VdsName}, User: ${UserName}).
 USER_ADD_DISK_TO_VM=Add-Disk operation of ${DiskAlias} was initiated on VM 
${VmName} by ${UserName}.
 USER_ADD_DISK_TO_VM_FINISHED_SUCCESS=The disk ${DiskAlias} was successfully 
added to VM ${VmName}.
@@ -178,8 +178,8 @@
 USER_RUN_VM_ON_NON_DEFAULT_VDS=Guest ${VmName} started on Host ${VdsName}. 
(Default Host parameter was ignored - assigned Host was not available).
 USER_REBOOT_VM=User ${UserName} initiated reboot of VM ${VmName}.
 USER_FAILED_REBOOT_VM=Failed to reboot VM ${VmName} (User: ${UserName}).
-USER_STOP_VM=VM ${VmName} powered off by ${UserName} (Host: ${VdsName}).
-USER_STOP_SUSPENDED_VM=Suspended VM ${VmName} powered off by ${UserName}.
+USER_STOP_VM=VM ${VmName} powered off by ${UserName} (Host: ${VdsName}) 
(Reason: ${Reason}).
+USER_STOP_SUSPENDED_VM=Suspended VM ${VmName} powered off by ${UserName} 
(Reason: ${Reason}).
 USER_STOP_SUSPENDED_VM_FAILED=Failed to power off suspended VM ${VmName} 
(User: ${UserName}).
 USER_TRY_BACK_TO_SNAPSHOT=Snapshot-Preview ${SnapshotName} for VM ${VmName} 
was initiated by ${UserName}.
 USER_TRY_BACK_TO_SNAPSHOT_FINISH_SUCCESS=Snapshot-Preview ${SnapshotName} for 
VM ${VmName} has been completed.
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd
 
b/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd
index c69298d..6bd1b58 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd
@@ -2639,6 +2639,7 @@
         <xs:sequence>
           <xs:element name="type" type="xs:string" minOccurs="0"/>
           <xs:element ref="status" minOccurs="0" maxOccurs="1"/>
+          <xs:element name="reason" type="xs:string" minOccurs="0" 
maxOccurs="1"/>
           <xs:element name="memory" type="xs:long" minOccurs="0"/>
           <xs:element name="cpu" type="CPU" minOccurs="0"/>
           <xs:element name="cpu_shares" type="xs:int" minOccurs="0" 
maxOccurs="1"/>
diff --git 
a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/VmMapper.java
 
b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/VmMapper.java
index a6cf6c6..30dc162 100644
--- 
a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/VmMapper.java
+++ 
b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/VmMapper.java
@@ -369,6 +369,9 @@
                 
model.getStatus().setDetail(entity.getVmPauseStatus().name().toLowerCase());
             }
         }
+        if (entity.getReason() != null) {
+            model.setReason(entity.getReason());
+        }
         if (entity.getBootSequence() != null ||
             entity.getKernelUrl() != null ||
             entity.getInitrdUrl() != null ||
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/DestroyVmVDSCommand.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/DestroyVmVDSCommand.java
index 59f0fc2..4676b98 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/DestroyVmVDSCommand.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/DestroyVmVDSCommand.java
@@ -40,11 +40,15 @@
 
                 changeStatus(parameters, curVm);
 
+                // Updating the DB
+                ResourceManager.getInstance().InternalSetVmStatus(curVm,
+                        parameters.getGracefully() ? VMStatus.PoweringDown : 
VMStatus.Down);
                 TransactionSupport.executeInNewTransaction(new 
TransactionMethod<Void>() {
                     @Override
                     public Void runInTransaction() {
 
                         curVm.guestLogoutTimeTreatmentAfterDestroy();
+                        curVm.setReason(getParameters().getReason());
                         // SaveVmDynamicToDBThreaded(curVm);
                         
DbFacade.getInstance().getVmDynamicDao().update(curVm.getDynamicData());
                         
DbFacade.getInstance().getVmStatisticsDao().update(curVm.getStatisticsData());
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java
index 7c0c1ef..281ea0c 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java
@@ -172,6 +172,12 @@
             }
         }
 
+        for (VmDynamic vmDynamic : _vmDynamicToSave.values()) {
+             if (vmDynamic.getStatus() == VMStatus.Up) {
+                 // clear the reason for VM shutdown
+                 vmDynamic.setReason("");
+             }
+        }
         
getDbFacade().getVmDynamicDao().updateAllInBatch(_vmDynamicToSave.values());
         
getDbFacade().getVmStatisticsDao().updateAllInBatch(_vmStatisticsToSave.values());
 
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
index ece625c..e5c9a3f 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
@@ -505,6 +505,9 @@
     @DefaultStringValue("Comment")
     String commentLabel();
 
+    @DefaultStringValue("Reason")
+    String reasonLabel();
+
     @DefaultStringValue("Based on Template")
     String basedOnTemplateVmPopup();
 
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/gin/BasePresenterModule.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/gin/BasePresenterModule.java
index 07629db..f6630d7 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/gin/BasePresenterModule.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/gin/BasePresenterModule.java
@@ -5,12 +5,14 @@
 import 
org.ovirt.engine.ui.common.presenter.popup.DefaultConfirmationPopupPresenterWidget;
 import org.ovirt.engine.ui.common.presenter.popup.ErrorPopupPresenterWidget;
 import 
org.ovirt.engine.ui.common.presenter.popup.RemoveConfirmationPopupPresenterWidget;
+import 
org.ovirt.engine.ui.common.presenter.popup.RemoveConfirmationWithCommentPopupPresenterWidget;
 import 
org.ovirt.engine.ui.common.presenter.popup.RolePermissionsRemoveConfirmationPopupPresenterWidget;
 import org.ovirt.engine.ui.common.view.ScrollableTabBarView;
 import org.ovirt.engine.ui.common.view.popup.ConsolePopupView;
 import org.ovirt.engine.ui.common.view.popup.DefaultConfirmationPopupView;
 import org.ovirt.engine.ui.common.view.popup.ErrorPopupView;
 import org.ovirt.engine.ui.common.view.popup.RemoveConfirmationPopupView;
+import 
org.ovirt.engine.ui.common.view.popup.RemoveConfirmationWithCommentPopupView;
 import 
org.ovirt.engine.ui.common.view.popup.RolePermissionsRemoveConfirmationPopupView;
 
 import com.gwtplatform.mvp.client.gin.AbstractPresenterModule;
@@ -33,6 +35,9 @@
         bindPresenterWidget(RemoveConfirmationPopupPresenterWidget.class,
                 RemoveConfirmationPopupPresenterWidget.ViewDef.class,
                 RemoveConfirmationPopupView.class);
+        
bindPresenterWidget(RemoveConfirmationWithCommentPopupPresenterWidget.class,
+                
RemoveConfirmationWithCommentPopupPresenterWidget.ViewDef.class,
+                RemoveConfirmationWithCommentPopupView.class);
         // Permissions removal
         
bindPresenterWidget(RolePermissionsRemoveConfirmationPopupPresenterWidget.class,
                 
RolePermissionsRemoveConfirmationPopupPresenterWidget.ViewDef.class,
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/presenter/popup/RemoveConfirmationWithCommentPopupPresenterWidget.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/presenter/popup/RemoveConfirmationWithCommentPopupPresenterWidget.java
new file mode 100644
index 0000000..4c9729d
--- /dev/null
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/presenter/popup/RemoveConfirmationWithCommentPopupPresenterWidget.java
@@ -0,0 +1,29 @@
+package org.ovirt.engine.ui.common.presenter.popup;
+
+import com.google.gwt.event.shared.EventBus;
+import com.google.inject.Inject;
+import 
org.ovirt.engine.ui.common.presenter.AbstractModelBoundPopupPresenterWidget;
+import org.ovirt.engine.ui.uicommonweb.models.ConfirmationWithReasonModel;
+
+/**
+ * Implements the remove confirmation dialog bound to UiCommon {@link 
org.ovirt.engine.ui.uicommonweb.models.ConfirmationModel}.
+ */
+public class RemoveConfirmationWithCommentPopupPresenterWidget extends 
AbstractModelBoundPopupPresenterWidget<ConfirmationWithReasonModel, 
RemoveConfirmationWithCommentPopupPresenterWidget.ViewDef> {
+
+    public interface ViewDef extends 
AbstractModelBoundPopupPresenterWidget.ViewDef<ConfirmationWithReasonModel> {
+    }
+
+    @Inject
+    public RemoveConfirmationWithCommentPopupPresenterWidget(EventBus 
eventBus, ViewDef view) {
+        super(eventBus, view);
+    }
+
+    @Override
+    protected void updateHashName(ConfirmationWithReasonModel model) {
+        super.updateHashName(model);
+
+        // The message depends on the hash name
+        updateMessage(model);
+    }
+
+}
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/AbstractConfirmationWithCommentPopupView.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/AbstractConfirmationWithCommentPopupView.java
new file mode 100644
index 0000000..a5a9ffe
--- /dev/null
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/AbstractConfirmationWithCommentPopupView.java
@@ -0,0 +1,25 @@
+package org.ovirt.engine.ui.common.view.popup;
+
+import com.google.gwt.event.shared.EventBus;
+import com.google.gwt.safehtml.shared.SafeHtmlUtils;
+import com.google.gwt.uibinder.client.UiField;
+import com.google.gwt.user.client.ui.HTML;
+import org.ovirt.engine.ui.common.CommonApplicationResources;
+import org.ovirt.engine.ui.uicommonweb.models.ConfirmationWithReasonModel;
+
+public abstract class AbstractConfirmationWithCommentPopupView extends 
AbstractModelBoundPopupView<ConfirmationWithReasonModel> {
+
+    @UiField
+    @Ignore
+    public HTML messageHTML;
+
+    public AbstractConfirmationWithCommentPopupView(EventBus eventBus, 
CommonApplicationResources resources) {
+        super(eventBus, resources);
+    }
+
+    @Override
+    public void setMessage(String message) {
+        messageHTML.setHTML(SafeHtmlUtils.fromString(message != null ? message 
: "").asString().replace("\n", "<br>"));//$NON-NLS-1$ //$NON-NLS-2$ 
//$NON-NLS-3$
+    }
+
+}
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/RemoveConfirmationWithCommentPopupView.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/RemoveConfirmationWithCommentPopupView.java
new file mode 100644
index 0000000..94e5e8b
--- /dev/null
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/RemoveConfirmationWithCommentPopupView.java
@@ -0,0 +1,189 @@
+package org.ovirt.engine.ui.common.view.popup;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.editor.client.SimpleBeanEditorDriver;
+import com.google.gwt.event.shared.EventBus;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeHtmlUtils;
+import com.google.gwt.uibinder.client.UiBinder;
+import com.google.gwt.uibinder.client.UiField;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Label;
+import com.google.inject.Inject;
+import org.ovirt.engine.ui.common.CommonApplicationConstants;
+import org.ovirt.engine.ui.common.CommonApplicationMessages;
+import org.ovirt.engine.ui.common.CommonApplicationResources;
+import org.ovirt.engine.ui.common.idhandler.ElementIdHandler;
+import org.ovirt.engine.ui.common.idhandler.WithElementId;
+import 
org.ovirt.engine.ui.common.presenter.popup.RemoveConfirmationWithCommentPopupPresenterWidget;
+import org.ovirt.engine.ui.common.widget.Align;
+import org.ovirt.engine.ui.common.widget.dialog.SimpleDialogPanel;
+import org.ovirt.engine.ui.common.widget.editor.EntityModelCheckBoxEditor;
+import 
org.ovirt.engine.ui.common.widget.editor.generic.StringEntityModelTextBoxEditor;
+import org.ovirt.engine.ui.uicommonweb.models.ConfirmationWithReasonModel;
+import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
+import org.ovirt.engine.ui.uicompat.Event;
+import org.ovirt.engine.ui.uicompat.EventArgs;
+import org.ovirt.engine.ui.uicompat.IEventListener;
+import org.ovirt.engine.ui.uicompat.PropertyChangedEventArgs;
+
+public class RemoveConfirmationWithCommentPopupView extends 
AbstractConfirmationWithCommentPopupView implements 
RemoveConfirmationWithCommentPopupPresenterWidget.ViewDef {
+
+    interface Driver extends 
SimpleBeanEditorDriver<ConfirmationWithReasonModel, 
RemoveConfirmationWithCommentPopupView> {
+    }
+
+    interface ViewUiBinder extends UiBinder<SimpleDialogPanel, 
RemoveConfirmationWithCommentPopupView> {
+        ViewUiBinder uiBinder = GWT.create(ViewUiBinder.class);
+    }
+
+    interface ViewIdHandler extends 
ElementIdHandler<RemoveConfirmationWithCommentPopupView> {
+        ViewIdHandler idHandler = GWT.create(ViewIdHandler.class);
+    }
+
+    private final Driver driver = GWT.create(Driver.class);
+
+    protected final CommonApplicationMessages messages;
+    protected final CommonApplicationConstants constants;
+
+    @UiField
+    protected FlowPanel itemPanel;
+
+    @UiField(provided = true)
+    @Path(value = "latch.entity")
+    @WithElementId
+    protected EntityModelCheckBoxEditor latch;
+
+    @UiField(provided = true)
+    @Path(value = "force.entity")
+    @WithElementId
+    protected EntityModelCheckBoxEditor force;
+
+    @UiField
+    @Ignore
+    protected HTML noteHTML;
+
+    @UiField
+    @Path(value = "reason.entity")
+    @WithElementId
+    StringEntityModelTextBoxEditor reasonEditor;
+
+    @Inject
+
+    public RemoveConfirmationWithCommentPopupView(EventBus eventBus,
+                                                  CommonApplicationResources 
resources,
+                                                  CommonApplicationMessages 
messages,
+                                                  CommonApplicationConstants 
constants) {
+        super(eventBus, resources);
+        latch = new EntityModelCheckBoxEditor(Align.RIGHT);
+        latch.setLabel(constants.approveOperation());
+        force = new EntityModelCheckBoxEditor(Align.RIGHT);
+        force.setLabel(constants.forceRemove());
+        force.getContentWidgetContainer().getElement().getStyle().setWidth(90, 
Unit.PCT);
+        this.constants= constants;
+        this.messages = messages;
+        initWidget(ViewUiBinder.uiBinder.createAndBindUi(this));
+        ViewIdHandler.idHandler.generateAndSetIds(this);
+        localize(constants);
+        driver.initialize(this);
+    }
+
+    @Override
+    public void setMessage(String message) {
+        super.setMessage(message == null ? 
constants.removeConfirmationPopupMessage() : message);
+    }
+
+    @Override
+    public void setItems(Iterable<?> items) {
+        if (items != null) {
+            addItems(items);
+        } else {
+            itemPanel.clear();
+        }
+    }
+
+    void setNote(String note) {
+        noteHTML.setHTML(SafeHtmlUtils.fromString(note != null ? note : 
"").asString().replace("\n", "<br>")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    protected void addItems(Iterable<?> items) {
+        for (Object item : items) {
+            addItemText(item);
+        }
+    }
+
+    protected void addItemText(Object item) {
+        addItemLabel(getItemTextFormatted(String.valueOf(item)));
+    }
+
+    void addItemLabel(String text) {
+        itemPanel.add(new Label(text));
+    }
+
+    protected void addItemLabel(SafeHtml html) {
+        itemPanel.add(new HTML(html));
+    }
+
+    String getItemTextFormatted(String itemText) {
+        return "- " + itemText; //$NON-NLS-1$
+    }
+
+    @Override
+    public void edit(ConfirmationWithReasonModel object) {
+        driver.edit(object);
+
+        // Bind "Latch.IsAvailable"
+        object.getLatch().getPropertyChangedEvent().addListener(new 
IEventListener() {
+
+            @Override
+            public void eventRaised(Event ev, Object sender, EventArgs args) {
+                if ("IsAvailable".equals(((PropertyChangedEventArgs) 
args).propertyName)) { //$NON-NLS-1$
+                    EntityModel entity = (EntityModel) sender;
+                    if (entity.getIsAvailable()) {
+                        latch.setVisible(true);
+                    }
+                }
+            }
+        });
+
+        if (object.getForceLabel() != null) {
+            force.setLabel(object.getForceLabel());
+        }
+
+        force.asCheckBox().setValue((Boolean) object.getForce().getEntity());
+        // Bind "Force.Label"
+        object.getPropertyChangedEvent().addListener(new IEventListener() {
+            @Override
+            public void eventRaised(Event ev, Object sender, EventArgs args) {
+                if ("ForceLabel".equals(((PropertyChangedEventArgs) 
args).propertyName)) { //$NON-NLS-1$
+                    ConfirmationWithReasonModel entity = 
(ConfirmationWithReasonModel) sender;
+                    force.setLabel(entity.getForceLabel());
+                }
+            }
+        });
+
+        setNote(object.getNote());
+        // Bind "Note"
+        object.getPropertyChangedEvent().addListener(new IEventListener() {
+            @Override
+            public void eventRaised(Event ev, Object sender, EventArgs args) {
+                if ("Note".equals(((PropertyChangedEventArgs) 
args).propertyName)) { //$NON-NLS-1$
+                    ConfirmationWithReasonModel entity = 
(ConfirmationWithReasonModel) sender;
+                    setNote(entity.getNote());
+                }
+            }
+        });
+    }
+
+    protected void localize(CommonApplicationConstants constants) {
+        latch.setLabel(constants.latchApproveOperationLabel());
+        reasonEditor.setLabel(constants.reasonLabel());
+    }
+
+    @Override
+    public ConfirmationWithReasonModel flush() {
+        return driver.flush();
+    }
+
+}
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/RemoveConfirmationWithCommentPopupView.ui.xml
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/RemoveConfirmationWithCommentPopupView.ui.xml
new file mode 100644
index 0000000..9b3eb8d
--- /dev/null
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/RemoveConfirmationWithCommentPopupView.ui.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent";>
+<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" 
xmlns:g="urn:import:com.google.gwt.user.client.ui"
+       xmlns:d="urn:import:org.ovirt.engine.ui.common.widget.dialog"
+    xmlns:e="urn:import:org.ovirt.engine.ui.common.widget.editor"
+    xmlns:ge="urn:import:org.ovirt.engine.ui.common.widget.editor.generic">
+
+       <ui:style>
+               .items {
+                       margin-top: 20px;
+                       margin-bottom: 20px;
+                       height: 60%;
+                       overflow: auto;
+               }
+               
+               .noteHTML {
+                       position: absolute;
+                       margin-top: 20px;
+                       line-height: 20px;
+                       color: red;
+                       font-size: 12px;
+               }
+               
+       </ui:style>
+
+       <d:SimpleDialogPanel width="500px" height="400px">
+               <d:content>
+                       <g:FlowPanel>
+                               <g:HTML ui:field="messageHTML" />
+                               <g:FlowPanel ui:field="itemPanel" 
addStyleNames="{style.items}" />
+                               <e:EntityModelCheckBoxEditor ui:field="latch" 
visible="false" />
+                               <e:EntityModelCheckBoxEditor ui:field="force" 
visible="false" />
+                               <g:HTML ui:field="noteHTML" 
addStyleNames="{style.noteHTML}"/>
+                <ge:StringEntityModelTextBoxEditor ui:field="reasonEditor" />
+                       </g:FlowPanel>
+               </d:content>
+       </d:SimpleDialogPanel>
+
+</ui:UiBinder>
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml
 
b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml
index c547f48..ea4d98c 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml
@@ -82,6 +82,7 @@
                <include 
name="common/businessentities/network/ExternalSubnet.java" />
 
                <include name="common/businessentities/Commented.java" />
+               <include name="common/businessentities/Reasoned.java" />
                <include name="common/businessentities/IVdcQueryable.java" />
                <include name="common/businessentities/FenceAgentOrder.java" />
                <include name="common/businessentities/LUNs.java" />
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/ConfirmationWithReasonModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/ConfirmationWithReasonModel.java
new file mode 100644
index 0000000..413999d
--- /dev/null
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/ConfirmationWithReasonModel.java
@@ -0,0 +1,34 @@
+package org.ovirt.engine.ui.uicommonweb.models;
+
+import org.ovirt.engine.ui.uicommonweb.validation.IValidation;
+import 
org.ovirt.engine.ui.uicommonweb.validation.SpecialAsciiI18NOrNoneValidation;
+
+@SuppressWarnings("unused")
+public class ConfirmationWithReasonModel extends ConfirmationModel
+{
+
+    private EntityModel<String> reason;
+
+    public EntityModel<String> getReason()
+    {
+        return reason;
+    }
+
+    public void setReason(EntityModel<String> value)
+    {
+        reason = value;
+    }
+
+    public ConfirmationWithReasonModel()
+    {
+        super();
+        setReason(new EntityModel());
+    }
+
+    public boolean validate()
+    {
+        getReason().validateEntity(new IValidation[] { new 
SpecialAsciiI18NOrNoneValidation() });
+
+        return super.validate() && getReason().getIsValid();
+    }
+}
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmListModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmListModel.java
index 15bee5e..413c181 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmListModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmListModel.java
@@ -74,6 +74,7 @@
 import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
 import org.ovirt.engine.ui.uicommonweb.help.HelpTag;
 import org.ovirt.engine.ui.uicommonweb.models.ConfirmationModel;
+import org.ovirt.engine.ui.uicommonweb.models.ConfirmationWithReasonModel;
 import org.ovirt.engine.ui.uicommonweb.models.ConsoleModelsCache;
 import org.ovirt.engine.ui.uicommonweb.models.ConsolePopupModel;
 import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
@@ -1593,8 +1594,7 @@
         }
     }
 
-    private void powerAction(String actionName, String title, String message) {
-        ConfirmationModel model = new ConfirmationModel();
+    private void powerAction(String actionName, String title, String message, 
ConfirmationModel model) {
         setWindow(model);
         model.setTitle(title);
 
@@ -1669,14 +1669,16 @@
         UIConstants constants = ConstantsManager.getInstance().getConstants();
         powerAction(SHUTDOWN,
                     constants.shutdownVirtualMachinesTitle(),
-                    
constants.areYouSureYouWantToShutDownTheFollowingVirtualMachinesMsg());
+                    
constants.areYouSureYouWantToShutDownTheFollowingVirtualMachinesMsg(),
+                    new ConfirmationWithReasonModel());
     }
 
     private void onShutdown() {
+        final ConfirmationWithReasonModel model = 
(ConfirmationWithReasonModel) getWindow();
         onPowerAction(VdcActionType.ShutdownVm, new 
PowerActionParametersFactory<VdcActionParametersBase>() {
             @Override
             public VdcActionParametersBase createActionParameters(VM vm) {
-                return new ShutdownVmParameters(vm.getId(), true);
+                return new ShutdownVmParameters(vm.getId(), true, 
model.getReason().getEntity());
             }
         });
     }
@@ -1685,14 +1687,16 @@
         UIConstants constants = ConstantsManager.getInstance().getConstants();
         powerAction(STOP,
                     constants.stopVirtualMachinesTitle(),
-                    
constants.areYouSureYouWantToStopTheFollowingVirtualMachinesMsg());
+                    
constants.areYouSureYouWantToStopTheFollowingVirtualMachinesMsg(),
+                    new ConfirmationWithReasonModel());
     }
 
     private void onStop() {
+        final ConfirmationWithReasonModel model = 
(ConfirmationWithReasonModel) getWindow();
         onPowerAction(VdcActionType.StopVm, new 
PowerActionParametersFactory<VdcActionParametersBase>() {
             @Override
             public VdcActionParametersBase createActionParameters(VM vm) {
-                return new StopVmParameters(vm.getId(), StopVmTypeEnum.NORMAL);
+                return new StopVmParameters(vm.getId(), StopVmTypeEnum.NORMAL, 
model.getReason().getEntity());
             }
         });
     }
@@ -1701,7 +1705,8 @@
         UIConstants constants = ConstantsManager.getInstance().getConstants();
         powerAction(REBOOT,
                     constants.rebootVirtualMachinesTitle(),
-                    
constants.areYouSureYouWantToRebootTheFollowingVirtualMachinesMsg());
+                    
constants.areYouSureYouWantToRebootTheFollowingVirtualMachinesMsg(),
+                    new ConfirmationModel());
     }
 
     private void onReboot() {
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VirtualMachineModule.java
 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VirtualMachineModule.java
index 37321d8..691bec1 100644
--- 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VirtualMachineModule.java
+++ 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VirtualMachineModule.java
@@ -12,6 +12,7 @@
 import org.ovirt.engine.ui.common.presenter.popup.ConsolePopupPresenterWidget;
 import 
org.ovirt.engine.ui.common.presenter.popup.DefaultConfirmationPopupPresenterWidget;
 import 
org.ovirt.engine.ui.common.presenter.popup.RemoveConfirmationPopupPresenterWidget;
+import 
org.ovirt.engine.ui.common.presenter.popup.RemoveConfirmationWithCommentPopupPresenterWidget;
 import 
org.ovirt.engine.ui.common.presenter.popup.RolePermissionsRemoveConfirmationPopupPresenterWidget;
 import org.ovirt.engine.ui.common.uicommon.model.DetailModelProvider;
 import org.ovirt.engine.ui.common.uicommon.model.DetailTabModelProvider;
@@ -81,7 +82,7 @@
             final Provider<VmMigratePopupPresenterWidget> migratePopupProvider,
             final Provider<VmPopupPresenterWidget> newVmPopupProvider,
             final Provider<GuidePopupPresenterWidget> guidePopupProvider,
-            final Provider<RemoveConfirmationPopupPresenterWidget> 
removeConfirmPopupProvider,
+            final Provider<RemoveConfirmationWithCommentPopupPresenterWidget> 
removeConfirmPopupProvider,
             final Provider<VmRemovePopupPresenterWidget> 
vmRemoveConfirmPopupProvider,
             final Provider<ReportPresenterWidget> reportWindowProvider,
             final Provider<ConsolePopupPresenterWidget> consolePopupProvider,
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVirtualMachineView.java
 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVirtualMachineView.java
index 2f5771d..d9ce4d9 100644
--- 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVirtualMachineView.java
+++ 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVirtualMachineView.java
@@ -25,6 +25,7 @@
 import 
org.ovirt.engine.ui.webadmin.widget.action.WebAdminMenuBarButtonDefinition;
 import org.ovirt.engine.ui.webadmin.widget.table.column.CommentColumn;
 import org.ovirt.engine.ui.webadmin.widget.table.column.PercentColumn;
+import org.ovirt.engine.ui.webadmin.widget.table.column.ReasonColumn;
 import org.ovirt.engine.ui.webadmin.widget.table.column.UptimeColumn;
 import org.ovirt.engine.ui.webadmin.widget.table.column.VmStatusColumn;
 import org.ovirt.engine.ui.webadmin.widget.table.column.VmTypeColumn;
@@ -71,6 +72,8 @@
         CommentColumn<VM> commentColumn = new CommentColumn<VM>();
         getTable().addColumnWithHtmlHeader(commentColumn, 
commentColumn.getHeaderHtml(), "30px"); //$NON-NLS-1$
 
+        ReasonColumn<VM> reasonColumn = new ReasonColumn<VM>();
+        getTable().addColumnWithHtmlHeader(reasonColumn, 
reasonColumn.getHeaderHtml(), "30px"); //$NON-NLS-1$
 
         TextColumnWithTooltip<VM> hostColumn = new TextColumnWithTooltip<VM>() 
{
             @Override
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/table/column/ReasonColumn.java
 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/table/column/ReasonColumn.java
new file mode 100644
index 0000000..6607ae9
--- /dev/null
+++ 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/table/column/ReasonColumn.java
@@ -0,0 +1,26 @@
+package org.ovirt.engine.ui.webadmin.widget.table.column;
+
+import com.google.gwt.resources.client.ImageResource;
+import org.ovirt.engine.core.common.businessentities.Reasoned;
+
+public class ReasonColumn<T extends Reasoned> extends 
WebAdminImageResourceColumn<T> {
+
+    @Override
+    public ImageResource getValue(T value) {
+        setTitle(value.getReason());
+        if (value.getReason() != null && !value.getReason().isEmpty()) {
+            return getApplicationResources().commentImage();
+        }
+        return null;
+    }
+
+    @Override
+    public ImageResource getDefaultImage() {
+        return getApplicationResources().commentImage();
+    }
+
+    @Override
+    public String getDefaultTitle() {
+        return CONSTANTS.reasonLabel();
+    }
+}
diff --git a/packaging/dbscripts/create_views.sql 
b/packaging/dbscripts/create_views.sql
index bd934f7..083cc0e 100644
--- a/packaging/dbscripts/create_views.sql
+++ b/packaging/dbscripts/create_views.sql
@@ -611,7 +611,7 @@
                       vm_static.default_display_type as default_display_type, 
vm_static.priority as priority,vm_static.iso_path as iso_path, vm_static.origin 
as origin, vds_groups.compatibility_version as vds_group_compatibility_version,
                       vm_static.initrd_url as initrd_url, vm_static.kernel_url 
as kernel_url, vm_static.kernel_params as kernel_params, 
vm_dynamic.pause_status as pause_status, vm_dynamic.exit_message as 
exit_message, vm_dynamic.exit_status as exit_status,vm_static.migration_support 
as migration_support,vm_static.predefined_properties as 
predefined_properties,vm_static.userdefined_properties as 
userdefined_properties,vm_static.min_allocated_mem as min_allocated_mem,  
vm_dynamic.hash as hash, vm_static.cpu_pinning as cpu_pinning, 
vm_static.db_generation as db_generation, vm_static.host_cpu_flags as 
host_cpu_flags,
                       vm_static.tunnel_migration as tunnel_migration, 
vm_static.vnc_keyboard_layout as vnc_keyboard_layout, 
vm_static.is_run_and_pause as is_run_and_pause, vm_static.created_by_user_id as 
created_by_user_id,
-                      vm_dynamic.last_watchdog_event as last_watchdog_event, 
vm_dynamic.last_watchdog_action as last_watchdog_action, vm_dynamic.is_run_once 
as is_run_once, vm_dynamic.vm_fqdn as vm_fqdn, vm_dynamic.cpu_name as cpu_name, 
vm_dynamic.current_cd as current_cd,
+                      vm_dynamic.last_watchdog_event as last_watchdog_event, 
vm_dynamic.last_watchdog_action as last_watchdog_action, vm_dynamic.is_run_once 
as is_run_once, vm_dynamic.vm_fqdn as vm_fqdn, vm_dynamic.cpu_name as cpu_name, 
vm_dynamic.current_cd as current_cd, vm_dynamic.reason as reason,
                       vm_static.instance_type_id as instance_type_id, 
vm_static.image_type_id as image_type_id, vds_groups.architecture as 
architecture, vm_static.original_template_id as original_template_id, 
vm_static.original_template_name as original_template_name, 
vm_dynamic.last_stop_time as last_stop_time,
                       vm_static.migration_downtime as migration_downtime, 
vm_static.template_version_number as template_version_number
 FROM         vm_static INNER JOIN
diff --git a/packaging/dbscripts/upgrade/03_05_0110_add_vm_dynamic_reason.sql 
b/packaging/dbscripts/upgrade/03_05_0110_add_vm_dynamic_reason.sql
new file mode 100644
index 0000000..e5223c5
--- /dev/null
+++ b/packaging/dbscripts/upgrade/03_05_0110_add_vm_dynamic_reason.sql
@@ -0,0 +1 @@
+select fn_db_add_column('vm_dynamic', 'reason', 'text');
diff --git a/packaging/dbscripts/vms_sp.sql b/packaging/dbscripts/vms_sp.sql
index 228a359..2e9abd8 100644
--- a/packaging/dbscripts/vms_sp.sql
+++ b/packaging/dbscripts/vms_sp.sql
@@ -295,7 +295,8 @@
         v_last_watchdog_action VARCHAR(8),
         v_is_run_once BOOLEAN,
         v_cpu_name VARCHAR(255),
-        v_current_cd VARCHAR(4000))
+        v_current_cd VARCHAR(4000),
+        v_reason VARCHAR(4000))
 RETURNS VOID
 
        --The [vm_dynamic] table doesn't have a timestamp column. Optimistic 
concurrency logic cannot be generated
@@ -320,7 +321,8 @@
       hibernation_vol_handle = v_hibernation_vol_handle,exit_status = 
v_exit_status,
       pause_status = v_pause_status,exit_message = v_exit_message, 
hash=v_hash, guest_agent_nics_hash = v_guest_agent_nics_hash,
       last_watchdog_event = v_last_watchdog_event, last_watchdog_action = 
v_last_watchdog_action, is_run_once = v_is_run_once, cpu_name = v_cpu_name,
-      current_cd = v_current_cd
+      current_cd = v_current_cd,
+      reason = v_reason
       WHERE vm_guid = v_vm_guid;
 END; $procedure$
 LANGUAGE plpgsql;


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

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

Reply via email to