Daniel Erez has uploaded a new change for review.

Change subject: core: introduce add Cinder disk support
......................................................................

core: introduce add Cinder disk support

Adding support for creating a Cinder disk.
Introduced AddCinderDiskCommand and AddCinderDiskCommandCallback.
AddCinderDiskCommand is invoked from AddDiskCommand.

Change-Id: Ie20f31afc59801e951b52053ba8bfef55e13e323
Bug-Url: https://bugzilla.redhat.com/1185826
Signed-off-by: Daniel Erez <de...@redhat.com>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AbstractDiskVmCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddDiskCommand.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddCinderDiskCommand.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddCinderDiskCommandCallback.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
5 files changed, 291 insertions(+), 7 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/24/39024/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AbstractDiskVmCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AbstractDiskVmCommand.java
index 52ac334..2b6a6cc 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AbstractDiskVmCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AbstractDiskVmCommand.java
@@ -6,6 +6,7 @@
 
 import org.ovirt.engine.core.bll.context.CommandContext;
 import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator;
+import org.ovirt.engine.core.bll.storage.CinderBroker;
 import org.ovirt.engine.core.bll.storage.IStorageHelper;
 import org.ovirt.engine.core.bll.storage.StorageHelperBase;
 import org.ovirt.engine.core.bll.storage.StorageHelperDirector;
@@ -41,6 +42,8 @@
 import org.ovirt.engine.core.dao.StoragePoolIsoMapDAO;
 
 public abstract class AbstractDiskVmCommand<T extends 
VmDiskOperationParameterBase> extends VmCommand<T> {
+
+    private CinderBroker cinderBroker;
 
     public AbstractDiskVmCommand(T parameters) {
         this(parameters, null);
@@ -307,4 +310,11 @@
                 getVm() != null &&
                 validate(new VmValidator(getVm()).vmNotLocked());
     }
+
+    public CinderBroker getCinderBroker() {
+        if (cinderBroker == null) {
+            cinderBroker = new CinderBroker(getStorageDomainId(), 
getReturnValue().getExecuteFailedMessages());
+        }
+        return cinderBroker;
+    }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddDiskCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddDiskCommand.java
index 1e0e567..e2a8da8 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddDiskCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddDiskCommand.java
@@ -1,9 +1,12 @@
 package org.ovirt.engine.core.bll;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 
 import org.apache.commons.lang.StringUtils;
 import org.ovirt.engine.core.bll.context.CommandContext;
@@ -12,8 +15,10 @@
 import org.ovirt.engine.core.bll.quota.QuotaStorageConsumptionParameter;
 import org.ovirt.engine.core.bll.quota.QuotaStorageDependent;
 import org.ovirt.engine.core.bll.storage.StorageDomainCommandBase;
+import org.ovirt.engine.core.bll.tasks.CommandCoordinatorUtil;
 import org.ovirt.engine.core.bll.utils.PermissionSubject;
 import org.ovirt.engine.core.bll.utils.VmDeviceUtils;
+import org.ovirt.engine.core.bll.validator.storage.CinderDisksValidator;
 import org.ovirt.engine.core.bll.validator.storage.DiskValidator;
 import org.ovirt.engine.core.bll.validator.storage.StorageDomainValidator;
 import org.ovirt.engine.core.bll.validator.storage.StoragePoolValidator;
@@ -22,6 +27,7 @@
 import org.ovirt.engine.core.common.action.AddDiskParameters;
 import org.ovirt.engine.core.common.action.AddImageFromScratchParameters;
 import org.ovirt.engine.core.common.action.HotPlugDiskToVmParameters;
+import org.ovirt.engine.core.common.action.VdcActionParametersBase;
 import org.ovirt.engine.core.common.action.VdcActionType;
 import org.ovirt.engine.core.common.action.VdcReturnValueBase;
 import org.ovirt.engine.core.common.asynctasks.EntityInfo;
@@ -35,6 +41,7 @@
 import org.ovirt.engine.core.common.businessentities.VMStatus;
 import org.ovirt.engine.core.common.businessentities.VmDeviceGeneralType;
 import org.ovirt.engine.core.common.businessentities.VmDeviceId;
+import org.ovirt.engine.core.common.businessentities.storage.CinderDisk;
 import org.ovirt.engine.core.common.businessentities.storage.Disk;
 import org.ovirt.engine.core.common.businessentities.storage.DiskStorageType;
 import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
@@ -52,6 +59,7 @@
 import org.ovirt.engine.core.common.validation.group.UpdateEntity;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+import org.ovirt.engine.core.dao.DiskImageDynamicDAO;
 import org.ovirt.engine.core.dao.DiskLunMapDao;
 import org.ovirt.engine.core.dao.SnapshotDao;
 import org.ovirt.engine.core.utils.transaction.TransactionMethod;
@@ -125,6 +133,14 @@
 
         if (DiskStorageType.LUN == 
getParameters().getDiskInfo().getDiskStorageType()) {
             return checkIfLunDiskCanBeAdded(diskValidator);
+        }
+
+        if (DiskStorageType.CINDER == 
getParameters().getDiskInfo().getDiskStorageType()) {
+            CinderDisk cinderDisk = (CinderDisk) getParameters().getDiskInfo();
+            cinderDisk.setStorageIds(new 
ArrayList<>(Arrays.asList(getStorageDomainId())));
+            StorageDomainValidator storageDomainValidator = 
createStorageDomainValidator();
+            CinderDisksValidator cinderDisksValidator = new 
CinderDisksValidator(cinderDisk);
+            return validate(storageDomainValidator.isDomainExistAndActive()) 
&& validate(cinderDisksValidator.validateCinderDiskLimits());
         }
 
         return true;
@@ -288,6 +304,10 @@
         return DbFacade.getInstance().getDiskLunMapDao();
     }
 
+    protected DiskImageDynamicDAO getDiskImageDynamicDao() {
+        return getDbFacade().getDiskImageDynamicDao();
+    }
+
     /**
      * @return The id of the storage domain where the first encountered VM 
image disk reside, if the vm doesn't have no
      *         image disks then Guid.Empty will be returned.
@@ -366,10 +386,16 @@
         getParameters().getDiskInfo().setId(Guid.newGuid());
         getParameters().setEntityInfo(new EntityInfo(VdcObjectType.Disk, 
getParameters().getDiskInfo().getId()));
         ImagesHandler.setDiskAlias(getParameters().getDiskInfo(), getVm());
-        if (DiskStorageType.IMAGE == 
getParameters().getDiskInfo().getDiskStorageType()) {
-            createDiskBasedOnImage();
-        } else {
-            createDiskBasedOnLun();
+        switch (getParameters().getDiskInfo().getDiskStorageType()) {
+            case IMAGE:
+                createDiskBasedOnImage();
+                break;
+            case LUN:
+                createDiskBasedOnLun();
+                break;
+            case CINDER:
+                createDiskBasedOnCinder();
+                break;
         }
     }
 
@@ -398,7 +424,7 @@
         setSucceeded(true);
     }
 
-    private boolean shouldDiskBePlugged() {
+    protected boolean shouldDiskBePlugged() {
         return getVm().getStatus() == VMStatus.Down && 
!Boolean.FALSE.equals(getParameters().getPlugDiskToVm());
     }
 
@@ -461,6 +487,31 @@
         setSucceeded(tmpRetValue.getSucceeded());
     }
 
+    private void createDiskBasedOnCinder() {
+        Future<VdcReturnValueBase> future = 
CommandCoordinatorUtil.executeAsyncCommand(
+                VdcActionType.AddCinderDisk,
+                buildAddCinderDiskParameters(),
+                cloneContextAndDetachFromParent());
+        try {
+            setReturnValue(future.get());
+            setSucceeded(getReturnValue().getSucceeded());
+        } catch (InterruptedException | ExecutionException e) {
+            log.error("Error creating Cinder disk '{}': {}",
+                    getParameters().getDiskInfo().getDiskAlias(),
+                    e.getMessage());
+            log.debug("Exception", e);
+        }
+    }
+
+    private VdcActionParametersBase buildAddCinderDiskParameters() {
+        AddDiskParameters parameters = new AddDiskParameters();
+        parameters.setDiskInfo(getParameters().getDiskInfo());
+        parameters.setPlugDiskToVm(getParameters().getPlugDiskToVm());
+        parameters.setVmId(getParameters().getVmId());
+        parameters.setStorageDomainId(getParameters().getStorageDomainId());
+        return parameters;
+    }
+
     /**
      * If disk is not allow to have snapshot no VM snapshot Id should be 
updated.
      * @param parameters
@@ -486,7 +537,8 @@
     public AuditLogType getAuditLogTypeValue() {
         switch (getActionState()) {
         case EXECUTE:
-            if (getParameters().getDiskInfo().getDiskStorageType() == 
DiskStorageType.IMAGE) {
+            if (getParameters().getDiskInfo().getDiskStorageType() == 
DiskStorageType.IMAGE ||
+                    getParameters().getDiskInfo().getDiskStorageType() == 
DiskStorageType.CINDER) {
                 return getExecuteAuditLogTypeValue(getSucceeded());
             } else {
                 return getEndSuccessAuditLogTypeValue(getSucceeded());
@@ -522,7 +574,7 @@
         }
     }
 
-    private AuditLogType getEndSuccessAuditLogTypeValue(boolean successful) {
+    protected AuditLogType getEndSuccessAuditLogTypeValue(boolean successful) {
         boolean isVmNameExist = StringUtils.isNotEmpty(getVmName());
         if (successful) {
             if (isVmNameExist) {
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddCinderDiskCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddCinderDiskCommand.java
new file mode 100644
index 0000000..c08b718
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddCinderDiskCommand.java
@@ -0,0 +1,146 @@
+package org.ovirt.engine.core.bll.storage;
+
+import org.ovirt.engine.core.bll.AddDiskCommand;
+import org.ovirt.engine.core.bll.ImagesHandler;
+import org.ovirt.engine.core.bll.InternalCommandAttribute;
+import org.ovirt.engine.core.bll.context.CommandContext;
+import org.ovirt.engine.core.bll.tasks.interfaces.CommandCallback;
+import org.ovirt.engine.core.bll.utils.VmDeviceUtils;
+import org.ovirt.engine.core.common.action.AddDiskParameters;
+import org.ovirt.engine.core.common.businessentities.VmDeviceGeneralType;
+import org.ovirt.engine.core.common.businessentities.VmDeviceId;
+import org.ovirt.engine.core.common.businessentities.storage.CinderDisk;
+import org.ovirt.engine.core.common.businessentities.storage.DiskImageDynamic;
+import org.ovirt.engine.core.common.businessentities.storage.ImageStatus;
+import 
org.ovirt.engine.core.common.businessentities.storage.ImageStorageDomainMap;
+import org.ovirt.engine.core.common.businessentities.storage.VolumeFormat;
+import org.ovirt.engine.core.common.businessentities.storage.VolumeType;
+import org.ovirt.engine.core.common.utils.Pair;
+import org.ovirt.engine.core.common.utils.VmDeviceType;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.utils.transaction.TransactionMethod;
+import org.ovirt.engine.core.utils.transaction.TransactionSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Map;
+
+@InternalCommandAttribute
+public class AddCinderDiskCommand<T extends AddDiskParameters> extends 
AddDiskCommand<T> {
+
+    private static final Logger log = 
LoggerFactory.getLogger(AddCinderDiskCommand.class);
+
+    public AddCinderDiskCommand(T parameters) {
+        super(parameters);
+    }
+
+    public AddCinderDiskCommand(T parameters, CommandContext cmdContext) {
+        super(parameters, cmdContext);
+    }
+
+    @Override
+    public void executeCommand() {
+        CinderDisk cinderDisk = createCinderDisk();
+        String volumeId = getCinderBroker().createDisk(cinderDisk);
+
+        cinderDisk.setId(Guid.createGuidFromString(volumeId));
+        cinderDisk.setImageId(Guid.createGuidFromString(volumeId));
+        addCinderDiskToDB(cinderDisk);
+
+        getParameters().setDiskInfo(cinderDisk);
+        persistCommand(getParameters().getParentCommand(), true);
+        getReturnValue().setActionReturnValue(cinderDisk.getId());
+        setSucceeded(true);
+    }
+
+    protected void addCinderDiskToDB(final CinderDisk cinderDisk) {
+        TransactionSupport.executeInNewTransaction(new 
TransactionMethod<Void>() {
+            @Override
+            public Void runInTransaction() {
+                getBaseDiskDao().save(cinderDisk);
+                getImageDao().save(cinderDisk.getImage());
+                getImageStorageDomainMapDao().save(new 
ImageStorageDomainMap(cinderDisk.getImageId(),
+                        cinderDisk.getStorageIds().get(0), 
cinderDisk.getQuotaId(), cinderDisk.getDiskProfileId()));
+
+                DiskImageDynamic diskDynamic = new DiskImageDynamic();
+                diskDynamic.setId(cinderDisk.getImageId());
+                getDiskImageDynamicDao().save(diskDynamic);
+
+                if (getVm() != null) {
+                    VmDeviceUtils.addManagedDevice(new 
VmDeviceId(cinderDisk.getId(), getVmId()),
+                            VmDeviceGeneralType.DISK,
+                            VmDeviceType.DISK,
+                            null,
+                            shouldDiskBePlugged(),
+                            Boolean.TRUE.equals(cinderDisk.getReadOnly()),
+                            null);
+                }
+                return null;
+            }
+        });
+    }
+
+    private CinderDisk createCinderDisk() {
+        final CinderDisk cinderDisk = new CinderDisk();
+        cinderDisk.setDiskAlias(getDiskAlias());
+        cinderDisk.setSize(getParameters().getDiskInfo().getSize());
+        cinderDisk.setBoot(getParameters().getDiskInfo().isBoot());
+        
cinderDisk.setDiskInterface(getParameters().getDiskInfo().getDiskInterface());
+        cinderDisk.setDiskAlias(getParameters().getDiskInfo().getDiskAlias());
+        
cinderDisk.setDiskDescription(getParameters().getDiskInfo().getDiskDescription());
+        cinderDisk.setShareable(getParameters().getDiskInfo().isShareable());
+        cinderDisk.setStorageIds(new 
ArrayList<>(Arrays.asList(getParameters().getStorageDomainId())));
+        cinderDisk.setSize(getParameters().getDiskInfo().getSize());
+        cinderDisk.setVolumeType(VolumeType.Unassigned);
+        cinderDisk.setvolumeFormat(VolumeFormat.RAW);
+        cinderDisk.setCreationDate(new Date());
+        cinderDisk.setLastModified(new Date());
+        cinderDisk.setActive(true);
+        cinderDisk.setImageStatus(ImageStatus.LOCKED);
+        cinderDisk.setVmSnapshotId(getParameters().getVmSnapshotId());
+        
cinderDisk.setCinderVolumeType(getParameters().getDiskInfo().getCinderVolumeType());
+        return cinderDisk;
+    }
+
+    @Override
+    protected void endSuccessfully() {
+        super.endSuccessfully();
+        ImagesHandler.updateImageStatus(getDiskId(), ImageStatus.OK);
+        auditLogDirector.log(this, getEndSuccessAuditLogTypeValue(true));
+    }
+
+    @Override
+    protected void endWithFailure() {
+        super.endWithFailure();
+        ImagesHandler.updateImageStatus(getDiskId(), ImageStatus.ILLEGAL);
+        auditLogDirector.log(this, getEndSuccessAuditLogTypeValue(false));
+    }
+
+    private Guid getDiskId() {
+        return getParameters().getDiskInfo().getId();
+    }
+
+    @Override
+    public boolean canDoAction() {
+        return true;
+    }
+
+    @Override
+    public CommandCallback getCallback() {
+        return new AddCinderDiskCommandCallback();
+    }
+
+    @Override
+    protected Map<String, Pair<String, String>> getExclusiveLocks() {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    protected Map<String, Pair<String, String>> getSharedLocks() {
+        return Collections.emptyMap();
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddCinderDiskCommandCallback.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddCinderDiskCommandCallback.java
new file mode 100644
index 0000000..844537d
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddCinderDiskCommandCallback.java
@@ -0,0 +1,73 @@
+package org.ovirt.engine.core.bll.storage;
+
+import org.ovirt.engine.core.bll.tasks.CommandCoordinatorUtil;
+import org.ovirt.engine.core.common.action.AddDiskParameters;
+import org.ovirt.engine.core.common.businessentities.storage.CinderDisk;
+import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
+import org.ovirt.engine.core.common.businessentities.storage.ImageStatus;
+import org.ovirt.engine.core.compat.CommandStatus;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+import org.ovirt.engine.core.dao.DiskDao;
+
+import java.util.List;
+
+public class AddCinderDiskCommandCallback extends 
AbstractCinderDiskCommandCallback<AddCinderDiskCommand<AddDiskParameters>> {
+
+    @Override
+    public void doPolling(Guid cmdId, List<Guid> childCmdIds) {
+        super.doPolling(cmdId, childCmdIds);
+
+        ImageStatus imageStatus = getCinderBroker().getDiskStatus(getDiskId());
+        DiskImage disk = getDisk();
+        if (imageStatus != null && imageStatus != disk.getImageStatus()) {
+            switch (imageStatus) {
+                case OK:
+                    getCommand().setCommandStatus(CommandStatus.SUCCEEDED);
+                    break;
+                case ILLEGAL:
+                    getCommand().setCommandStatus(CommandStatus.FAILED);
+                    break;
+            }
+        }
+    }
+
+    @Override
+    public void onFailed(Guid cmdId, List<Guid> childCmdIds) {
+        super.onFailed(cmdId, childCmdIds);
+
+        log.error("Failed adding disk to Cinder. ID: {}", getDiskId());
+        getCommand().endAction();
+        CommandCoordinatorUtil.removeAllCommandsInHierarchy(cmdId);
+    }
+
+    @Override
+    public void onSucceeded(Guid cmdId, List<Guid> childCmdIds) {
+        super.onSucceeded(cmdId, childCmdIds);
+
+        log.error("Disk has been successfully added to Cinder. ID: {}", 
getDiskId());
+        getCommand().endAction();
+        CommandCoordinatorUtil.removeAllCommandsInHierarchy(cmdId);
+    }
+
+    @Override
+    protected Guid getDiskId() {
+        return getCommand().getParameters().getDiskInfo().getId();
+    }
+
+    protected CinderDisk getDisk() {
+        if (disk == null) {
+            disk = (CinderDisk) getDiskDao().get(getDiskId());
+        }
+        return disk;
+    }
+
+    protected DiskDao getDiskDao() {
+        return DbFacade.getInstance().getDiskDao();
+    }
+
+    @Override
+    protected CinderBroker getCinderBroker() {
+        return getCommand().getCinderBroker();
+    }
+}
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 c524d69..26796ef 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
@@ -424,6 +424,9 @@
     UpdateMacPool(3101, ActionGroup.EDIT_MAC_POOL, false, 
QuotaDependency.NONE),
     RemoveMacPool(3102, ActionGroup.DELETE_MAC_POOL, false, 
QuotaDependency.NONE),
 
+    // Cinder
+    AddCinderDisk(3200, ActionGroup.CONFIGURE_VM_STORAGE, false, 
QuotaDependency.NONE),
+
     // Host Devices
     RefreshHostDevices(4000, ActionGroup.MANIPULATE_HOST, false, 
QuotaDependency.NONE);
 


-- 
To view, visit https://gerrit.ovirt.org/39024
To unsubscribe, visit https://gerrit.ovirt.org/settings

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

Reply via email to