Tomas Jelinek has uploaded a new change for review.

Change subject: engine,frontend: clone VM WIP
......................................................................

engine,frontend: clone VM WIP

Just a WIP, do not review

Change-Id: I2492f54834553e1dd06675b20342410152759f7f
Signed-off-by: Tomas Jelinek <tjeli...@redhat.com>
---
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CloneVmCommand.java
A 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/CloneVmParameters.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/StepEnum.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.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/section/main/view/tab/MainTabVirtualMachineView.java
7 files changed, 313 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/81/23581/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CloneVmCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CloneVmCommand.java
new file mode 100644
index 0000000..bdc353c
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CloneVmCommand.java
@@ -0,0 +1,214 @@
+package org.ovirt.engine.core.bll;
+
+import org.ovirt.engine.core.bll.context.CommandContext;
+import org.ovirt.engine.core.bll.job.ExecutionContext;
+import org.ovirt.engine.core.bll.job.ExecutionHandler;
+import org.ovirt.engine.core.bll.job.JobRepositoryFactory;
+import org.ovirt.engine.core.bll.utils.PermissionSubject;
+import org.ovirt.engine.core.common.VdcObjectType;
+import org.ovirt.engine.core.common.action.AddVmFromSnapshotParameters;
+import org.ovirt.engine.core.common.action.CloneVmParameters;
+import org.ovirt.engine.core.common.action.CreateAllSnapshotsFromVmParameters;
+import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.action.VdcReturnValueBase;
+import org.ovirt.engine.core.common.businessentities.Snapshot;
+import org.ovirt.engine.core.common.errors.VdcBLLException;
+import org.ovirt.engine.core.common.errors.VdcBllErrors;
+import org.ovirt.engine.core.common.errors.VdcBllMessages;
+import org.ovirt.engine.core.common.job.Job;
+import org.ovirt.engine.core.common.job.Step;
+import org.ovirt.engine.core.common.job.StepEnum;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+import org.ovirt.engine.core.dal.job.ExecutionMessageDirector;
+import org.ovirt.engine.core.utils.RandomUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+@NonTransactiveCommandAttribute
+public class CloneVmCommand<T extends CloneVmParameters> extends 
CommandBase<T> {
+
+    public static final String CLONE_SNAPSHOT_DESCRIPTION = "clone snapshot";
+
+    public CloneVmCommand(T parameters) {
+        super(parameters);
+        setVmId((parameters.getVmId().equals(Guid.Empty)) ? Guid.newGuid() : 
parameters.getVmId());
+        parameters.getVm().setName(parameters.getNewName() + 
RandomUtils.instance().nextInt());
+        setVmName(parameters.getVm().getName());
+    }
+
+    @Override
+    protected void executeCommand() {
+        if (getParameters().getNextAction() == null) {
+            makeSnapshot();
+        }
+    }
+
+    private void makeSnapshot() {
+        VdcReturnValueBase vdcReturnValue = getBackend().runInternalAction(
+                        VdcActionType.CreateAllSnapshotsFromVm,
+                        buildCreateSnapshotParameters(),
+                        createSubstepContext(StepEnum.CREATING_SNAPSHOTS));
+
+        // setting lock to null in order not to release lock twice
+        setLock(null);
+        setSucceeded(vdcReturnValue.getSucceeded());
+
+        if (vdcReturnValue.getSucceeded()) {
+            List<Guid> internalVdsmTaskIdList = 
vdcReturnValue.getInternalVdsmTaskIdList();
+            if (internalVdsmTaskIdList == null || 
internalVdsmTaskIdList.size() == 0) {
+                cloneVmFromSnapshot();
+            } else {
+                
getReturnValue().getVdsmTaskIdList().addAll(internalVdsmTaskIdList);
+            }
+        } else {
+            if (areDisksLocked(vdcReturnValue)) {
+                throw new 
VdcBLLException(VdcBllErrors.IRS_IMAGE_STATUS_ILLEGAL);
+            }
+            getReturnValue().setFault(vdcReturnValue.getFault());
+            log.errorFormat("Failed to create stateless snapshot for VM {0} 
({1})",
+                    getVm().getName(), getVm().getId());
+        }
+    }
+
+    private void cloneVmFromSnapshot() {
+        VdcReturnValueBase vdcReturnValue = getBackend().runInternalAction(
+                VdcActionType.AddVmFromSnapshot,
+                creataAddVmFromSnapshotParameters(),
+                createContextForRunStatelessVm(StepEnum.CLONE_VM));
+
+        // setting lock to null in order not to release lock twice
+        setLock(null);
+        setSucceeded(vdcReturnValue.getSucceeded());
+
+        if (vdcReturnValue.getSucceeded()) {
+            List<Guid> internalVdsmTaskIdList = 
vdcReturnValue.getInternalVdsmTaskIdList();
+            if (internalVdsmTaskIdList == null || 
internalVdsmTaskIdList.size() == 0) {
+                setSucceeded(true);
+            } else {
+                
getReturnValue().getVdsmTaskIdList().addAll(internalVdsmTaskIdList);
+            }
+        } else {
+            if (areDisksLocked(vdcReturnValue)) {
+                throw new 
VdcBLLException(VdcBllErrors.IRS_IMAGE_STATUS_ILLEGAL);
+            }
+            getReturnValue().setFault(vdcReturnValue.getFault());
+            log.errorFormat("Failed to create stateless snapshot for VM {0} 
({1})",
+                    getVm().getName(), getVm().getId());
+        }
+    }
+
+    private AddVmFromSnapshotParameters creataAddVmFromSnapshotParameters() {
+        List<Snapshot> snapshots = 
DbFacade.getInstance().getSnapshotDao().getAll(getVmId());
+        // TODO handle the situation when there is no snapshot
+        Snapshot snapshot = snapshots.get(snapshots.size() - 1);
+        String name = getVm().getStaticData().getName() + 
RandomUtils.instance().nextByte();
+        getVm().getStaticData().setName(name);
+        AddVmFromSnapshotParameters parameters =
+                new AddVmFromSnapshotParameters(getVm().getStaticData(), 
snapshot.getId());
+        
parameters.setDiskInfoDestinationMap(getParameters().getDiskInfoDestinationMap());
+        parameters.setSessionId(getParameters().getSessionId());
+        parameters.setParentParameters(getParameters());
+
+        return parameters;
+    }
+
+    @Override
+    protected void endSuccessfully() {
+        if (getParameters().getNextAction() == null) {
+            getBackend().endAction(VdcActionType.CreateAllSnapshotsFromVm, 
buildCreateSnapshotParametersForEndAction());
+            getParameters().setShouldBeLogged(false);
+
+            setSucceeded(true);
+
+            if (!getSucceeded()) {
+                getParameters().setShouldBeLogged(true);
+                log.errorFormat("Could not run VM {0} ({1}) in stateless mode",
+                        getVm().getName(), getVm().getId());
+                // could not run the vm don't try to run the end action again
+                getReturnValue().setEndActionTryAgain(false);
+            }
+
+            getParameters().setNextAction(VdcActionType.AddVmFromSnapshot);
+            cloneVmFromSnapshot();
+        } else if (getParameters().getNextAction() == 
VdcActionType.AddVmFromSnapshot) {
+            getBackend().endAction(VdcActionType.AddVmFromSnapshot, 
creataAddVmFromSnapshotParameters());
+            
+
+
+            setSucceeded(true);
+        }
+
+    }
+
+    private CommandContext createContextForRunStatelessVm(StepEnum 
substepName) {
+        Step step = getExecutionContext().getStep();
+        Job job = 
JobRepositoryFactory.getJobRepository().getJobWithSteps(step.getJobId());
+        Step executingStep = job.getDirectStep(StepEnum.EXECUTING);
+
+        ExecutionContext runStatelessVmCtx = new ExecutionContext();
+        runStatelessVmCtx.setMonitored(true);
+        Step runStatelessStep =
+                ExecutionHandler.addSubStep(getExecutionContext(),
+                        executingStep,
+                        substepName,
+                        
ExecutionMessageDirector.resolveStepMessage(substepName,
+                                getVmValuesForMsgResolving()));
+        runStatelessVmCtx.setShouldEndJob(true);
+        runStatelessVmCtx.setJob(job);
+        runStatelessVmCtx.setStep(runStatelessStep);
+        return new CommandContext(runStatelessVmCtx);
+    }
+
+    private CommandContext createSubstepContext(StepEnum substepName) {
+        Map<String, String> values = getVmValuesForMsgResolving();
+        // Creating snapshots as sub step of run stateless
+        Step createSnapshotsStep = addSubStep(StepEnum.EXECUTING, substepName, 
values);
+
+        // Add the step as the first step of the new context
+        ExecutionContext createSnapshotsCtx = new ExecutionContext();
+        createSnapshotsCtx.setMonitored(true);
+        createSnapshotsCtx.setStep(createSnapshotsStep);
+        return new CommandContext(createSnapshotsCtx, 
getCompensationContext(), getLock());
+    }
+
+    private CreateAllSnapshotsFromVmParameters buildCreateSnapshotParameters() 
{
+        CreateAllSnapshotsFromVmParameters parameters =
+                new CreateAllSnapshotsFromVmParameters(getVm().getId(), 
CLONE_SNAPSHOT_DESCRIPTION);
+        parameters.setShouldBeLogged(false);
+        parameters.setParentCommand(getActionType());
+        parameters.setEntityInfo(getParameters().getEntityInfo());
+        parameters.setSnapshotType(Snapshot.SnapshotType.REGULAR);
+        parameters.setParentParameters(getParameters());
+        parameters.setSessionId(getParameters().getSessionId());
+
+        return parameters;
+    }
+
+    private CreateAllSnapshotsFromVmParameters 
buildCreateSnapshotParametersForEndAction() {
+        CreateAllSnapshotsFromVmParameters parameters = 
buildCreateSnapshotParameters();
+        parameters.setImagesParameters(getParameters().getImagesParameters());
+        return parameters;
+    }
+
+    private boolean areDisksLocked(VdcReturnValueBase vdcReturnValue) {
+        return vdcReturnValue.getCanDoActionMessages().contains(
+                VdcBllMessages.ACTION_TYPE_FAILED_DISKS_LOCKED.name());
+    }
+
+    protected Map<String, String> getVmValuesForMsgResolving() {
+        return Collections.singletonMap(VdcObjectType.VM.name().toLowerCase(), 
getVmName());
+    }
+
+    @Override
+    public List<PermissionSubject> getPermissionCheckSubjects() {
+        List<PermissionSubject> permissionList = new 
ArrayList<PermissionSubject>();
+        permissionList.add(new PermissionSubject(getParameters().getVmId(),
+                VdcObjectType.VM,
+                getActionType().getActionGroup()));
+        return permissionList;
+    }
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/CloneVmParameters.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/CloneVmParameters.java
new file mode 100644
index 0000000..7275a97
--- /dev/null
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/CloneVmParameters.java
@@ -0,0 +1,35 @@
+package org.ovirt.engine.core.common.action;
+
+import org.ovirt.engine.core.common.businessentities.VM;
+
+public class CloneVmParameters extends VmManagementParametersBase {
+
+    public CloneVmParameters() {
+
+    }
+
+    public CloneVmParameters(VM vm, String newName) {
+        super(vm);
+        this.newName = newName;
+    }
+
+    private String newName;
+
+    public String getNewName() {
+        return newName;
+    }
+
+    public void setNewName(String newName) {
+        this.newName = newName;
+    }
+
+    private VdcActionType nextAction;
+
+    public VdcActionType getNextAction() {
+        return nextAction;
+    }
+
+    public void setNextAction(VdcActionType nextAction) {
+        this.nextAction = nextAction;
+    }
+}
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 cf253f0..ead34e9 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,8 @@
     CancelMigrateVm(41, ActionGroup.MIGRATE_VM, false, QuotaDependency.NONE),
     ActivateDeactivateVmNic(42, QuotaDependency.NONE),
     AddVmFromSnapshot(52, ActionGroup.CREATE_VM, QuotaDependency.BOTH),
+    // the sub commands take care of it
+    CloneVm(53, ActionGroup.CREATE_VM, QuotaDependency.NONE),
     ImportVmFromConfiguration(43, ActionGroup.IMPORT_EXPORT_VM, 
QuotaDependency.NONE),
     // VdsCommands
     AddVds(101, ActionGroup.CREATE_HOST, QuotaDependency.NONE),
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/StepEnum.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/StepEnum.java
index c13c17a..5fbb9df 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/StepEnum.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/StepEnum.java
@@ -18,6 +18,7 @@
     MIGRATE_VM,
     CREATING_SNAPSHOTS,
     RUN_STATELESS_VM,
+    CLONE_VM,
     TAKING_VM_FROM_POOL,
 
     // Gluster
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 e929e14..f461435 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
@@ -345,6 +345,9 @@
     @DefaultStringValue("New VM")
     String newVm();
 
+    @DefaultStringValue("Clone VM")
+    String cloneVm();
+
     @DefaultStringValue("Power Off")
     String powerOffVm();
 
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 a3c57c4..88b9560 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
@@ -14,6 +14,7 @@
 import org.ovirt.engine.core.common.action.AttachEntityToTagParameters;
 import org.ovirt.engine.core.common.action.ChangeDiskCommandParameters;
 import org.ovirt.engine.core.common.action.ChangeVMClusterParameters;
+import org.ovirt.engine.core.common.action.CloneVmParameters;
 import org.ovirt.engine.core.common.action.MigrateVmParameters;
 import org.ovirt.engine.core.common.action.MigrateVmToServerParameters;
 import org.ovirt.engine.core.common.action.MoveVmParameters;
@@ -46,6 +47,7 @@
 import org.ovirt.engine.core.common.queries.IdQueryParameters;
 import org.ovirt.engine.core.common.queries.SearchParameters;
 import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
+import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
 import org.ovirt.engine.core.common.queries.VdcQueryType;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.compat.StringHelper;
@@ -92,6 +94,17 @@
 public class VmListModel extends VmBaseListModel<VM> implements 
ISupportSystemTreeContext {
 
     public static final Version BALLOON_DEVICE_MIN_VERSION = Version.v3_2;
+
+    private UICommand cloneVmCommand;
+
+    public UICommand getCloneVmCommand() {
+        return cloneVmCommand;
+    }
+
+    public void setCloneVmCommand(UICommand cloneVmCommand) {
+        this.cloneVmCommand = cloneVmCommand;
+    }
+
     private UICommand newVMCommand;
 
     public UICommand getNewVmCommand() {
@@ -392,6 +405,7 @@
         setConsoleHelpers();
 
         setNewVmCommand(new UICommand("NewVm", this)); //$NON-NLS-1$
+        setCloneVmCommand(new UICommand("NewVm", this)); //$NON-NLS-1$
         setEditCommand(new UICommand("Edit", this)); //$NON-NLS-1$
         setRemoveCommand(new UICommand("Remove", this)); //$NON-NLS-1$
         setRunCommand(new UICommand("Run", this, true)); //$NON-NLS-1$
@@ -2233,6 +2247,7 @@
                 getSelectedItems() != null && getSelectedItem() != null ? 
getSelectedItems()
                         : new ArrayList();
 
+        getCloneVmCommand().setIsExecutionAllowed(items.size() == 1);
         
getEditCommand().setIsExecutionAllowed(isEditCommandExecutionAllowed(items));
         getRemoveCommand().setIsExecutionAllowed(items.size() > 0
                 && VdcActionUtils.canExecute(items, VM.class, 
VdcActionType.RemoveVm));
@@ -2319,7 +2334,9 @@
     {
         super.executeCommand(command);
 
-        if (command == getNewVmCommand())
+        if (command == getCloneVmCommand()) {
+            cloneVm();
+        } else if (command == getNewVmCommand())
         {
             newVm();
         }
@@ -2461,6 +2478,39 @@
 
     }
 
+    private void cloneVm() {
+        final VM vm = (VM) getSelectedItem();
+        if (vm == null) {
+            return;
+        }
+
+        final HashMap<Guid, DiskImage> diskInfoDestinationMap = new 
HashMap<Guid, DiskImage>();
+
+        Frontend.getInstance().runQuery(VdcQueryType.GetAllDisksByVmId, new 
IdQueryParameters(vm.getId()),
+                new AsyncQuery(this, new INewAsyncCallback() {
+
+                    @Override
+                    public void onSuccess(Object model, Object returnValue) {
+                        List<Disk> vmDisks = ((VdcQueryReturnValue) 
returnValue).getReturnValue();
+                        for (Disk disk : vmDisks) {
+                            if (disk.getDiskStorageType() == 
DiskStorageType.IMAGE) {
+                                diskInfoDestinationMap.put(disk.getId(), 
(DiskImage) disk);
+                            }
+                        }
+
+                        CloneVmParameters params = new CloneVmParameters(vm, 
"someNewName"); //$NON-NLS-1$
+                        
params.setDiskInfoDestinationMap(diskInfoDestinationMap);
+                        
Frontend.getInstance().runAction(VdcActionType.CloneVm, params,
+                                new IFrontendActionAsyncCallback() {
+                                    @Override
+                                    public void 
executed(FrontendActionAsyncResult result) {
+                                        System.out.println("");
+                                    }
+                                }, this);
+                    }
+                }));
+    }
+
     private void connectToConsoles() {
         StringBuilder errorMessages = null;
 
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 08c11c5..9b73883 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
@@ -191,6 +191,13 @@
                 return getMainModel().getRemoveCommand();
             }
         });
+        getTable().addActionButton(new 
WebAdminButtonDefinition<VM>(constants.cloneVm()) {
+
+            @Override
+            protected UICommand resolveCommand() {
+                return getMainModel().getCloneVmCommand();
+            }
+        });
         // TODO: separator
         getTable().addActionButton(new 
WebAdminButtonDefinition<VM>(constants.runOnceVm()) {
             @Override


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2492f54834553e1dd06675b20342410152759f7f
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Tomas Jelinek <tjeli...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to