Ramesh N has uploaded a new change for review. Change subject: gluster: Add support for gluster brick creation ......................................................................
gluster: Add support for gluster brick creation Add Create Brick action to 'Storage Devices' sub tab in Hosts main tab. It helps to create bricks from the usable storage devices and these bricks are mounted at the given mount point and it can be directly used by the gluster volumes Change-Id: If43b6503dd8362d2a0907ac9648335a750828427 Signed-off-by: Ramesh Nachimuthu <rnach...@redhat.com> --- M frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java A frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/CreateBrickModel.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/HostGlusterStorageDevicesListModel.java M frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java M frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/HostModule.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/CreateBrickPopupPresenterWidget.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/CreateBrickPopupView.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/CreateBrickPopupView.ui.xml M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/host/SubTabHostGlusterStorageDevicesView.java M frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties 13 files changed, 677 insertions(+), 5 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/90/40190/1 diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java index d2cf668..1eb950e 100644 --- a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java @@ -3179,6 +3179,18 @@ @DefaultStringValue("Cannot ${action} ${type}. The selected cluster doesn't support Storage provisioning.") String ACTION_TYPE_FAILED_STORAGE_PROVISIONING_NOT_SUPPORTED_BY_CLUSTER(); + @DefaultStringValue("Cannot ${action} ${type}. Storage Device is locked.") + String ACTION_TYPE_FAILED_STORAGE_DEVICE_LOCKED(); + + @DefaultStringValue("Cannot ${action} ${type}. At least one storage device is required.") + String ACTION_TYPE_FAILED_STORAGE_DEVICE_REQUIRED(); + + @DefaultStringValue("Cannot ${action} ${type}. Different types of storage devices are selected.") + String ACTION_TYPE_FAILED_DIFFERENT_STORAGE_DEVICE_TYPES_SELECTED(); + + @DefaultStringValue("Cannot ${action} ${type}. Storage Device ${storageDevice} is already in use.") + String ACTION_TYPE_FAILED_DEVICE_IS_ALREADY_IN_USE(); + @DefaultStringValue("Cannot ${action} ${type}. All three values are needed in order to define QoS on each network directions.") String ACTION_TYPE_FAILED_NETWORK_QOS_MISSING_VALUES(); diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java index 52f99b9..aa70144 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java @@ -460,6 +460,9 @@ gluster_storage_devices("gluster_storage_devices", HelpTagType.WEBADMIN), //$NON-NLS-1$ + create_brick( + "create_brick", HelpTagType.WEBADMIN, "[gluster] Hosts main tab -> Storage Devices sub tab -> 'Create Brick' dialog"), //$NON-NLS-1$ //$NON-NLS-2$ + virtual_machines("virtual_machines", HelpTagType.UNKNOWN), //$NON-NLS-1$ vm_import("vm_import", HelpTagType.UNKNOWN), //$NON-NLS-1$ diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/CreateBrickModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/CreateBrickModel.java new file mode 100644 index 0000000..b00c2dd --- /dev/null +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/CreateBrickModel.java @@ -0,0 +1,184 @@ +package org.ovirt.engine.ui.uicommonweb.models.gluster; + +import java.util.Arrays; +import java.util.List; + +import org.ovirt.engine.core.common.businessentities.RaidType; +import org.ovirt.engine.core.common.businessentities.gluster.StorageDevice; +import org.ovirt.engine.core.common.utils.Pair; +import org.ovirt.engine.core.common.utils.SizeConverter; +import org.ovirt.engine.core.common.utils.SizeConverter.SizeUnit; +import org.ovirt.engine.ui.uicommonweb.models.EntityModel; +import org.ovirt.engine.ui.uicommonweb.models.ListModel; +import org.ovirt.engine.ui.uicommonweb.models.Model; +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; + +import com.google.gwt.i18n.client.NumberFormat; + +public class CreateBrickModel extends Model { + EntityModel<String> lvName; + EntityModel<String> size; + EntityModel<String> mountPoint; + EntityModel<String> defaultMountFolder; + EntityModel<Integer> stripeSize; + EntityModel<Integer> noOfPhysicalDisksInRaidVolume; + ListModel<RaidType> raidTypeList; + private ListModel<StorageDevice> storageDevices; + + public CreateBrickModel() { + setLvName(new EntityModel<String>()); + setStorageDevices(new ListModel<StorageDevice>()); + setSize(new EntityModel<String>()); + setStripeSize(new EntityModel<Integer>()); + setNoOfPhysicalDisksInRaidVolume(new EntityModel<Integer>()); + setRaidTypeList(new ListModel<RaidType>()); + setMountPoint(new EntityModel<String>()); + setDefaultMountFolder(new EntityModel<String>()); + List<RaidType> list = Arrays.asList(RaidType.values()); + getRaidTypeList().setItems(list); + getRaidTypeList().setSelectedItem(RaidType.None); + getNoOfPhysicalDisksInRaidVolume().setIsAvailable(false); + getStripeSize().setIsAvailable(false); + initSize(); + getStorageDevices().getSelectedItemsChangedEvent().addListener(new IEventListener<EventArgs>() { + + @Override + public void eventRaised(Event<? extends EventArgs> ev, Object sender, EventArgs args) { + updateBrickSize(); + } + + }); + + getLvName().getEntityChangedEvent().addListener(new IEventListener<EventArgs>() { + + @Override + public void eventRaised(Event<? extends EventArgs> ev, Object sender, EventArgs args) { + String mountPoint = getDefaultMountFolder().getEntity() + "/" + getLvName().getEntity(); //$NON-NLS-1$ + getMountPoint().setEntity(mountPoint); + } + }); + + getRaidTypeList().getSelectedItemChangedEvent().addListener(new IEventListener<EventArgs>() { + @Override + public void eventRaised(Event<? extends EventArgs> ev, Object sender, EventArgs args) { + if (getRaidTypeList().getSelectedItem() != RaidType.None + && getRaidTypeList().getSelectedItem() != RaidType.Raid0) { + getNoOfPhysicalDisksInRaidVolume().setIsAvailable(true); + getStripeSize().setIsAvailable(true); + } else { + getNoOfPhysicalDisksInRaidVolume().setIsAvailable(false); + getStripeSize().setIsAvailable(false); + } + onPropertyChanged(new PropertyChangedEventArgs("raidTypeChanged")); //$NON-NLS-1$ + } + }); + + } + + private void updateBrickSize() { + long totalSize = 0; + // Calculate and show the total size of all selected device so that user can get an idea of what will be his + // brick + // capacity. + if (getStorageDevices().getSelectedItems() != null) { + for (StorageDevice storageDevice : getStorageDevices().getSelectedItems()) { + totalSize += storageDevice.getSize(); + } + } + + Pair<SizeUnit, Double> convertedSize = SizeConverter.autoConvert(totalSize, SizeUnit.MB); + setBrickSize(convertedSize); + } + + public EntityModel<String> getLvName() { + return lvName; + } + + public EntityModel<String> getSize() { + return size; + } + + private void initSize() { + setBrickSize(new Pair<SizeConverter.SizeUnit, Double>(SizeUnit.BYTES, 0D)); + } + + private void setBrickSize(Pair<SizeUnit, Double> size) { + String sizeString = getSizeString(size); + getSize().setEntity(sizeString); + } + + private String getSizeString(Pair<SizeUnit, Double> size) { + return formatSize(size.getSecond()) + " " + size.getFirst().toString();//$NON-NLS-1$ + } + + public ListModel<StorageDevice> getStorageDevices() { + return storageDevices; + } + + public void setLvName(EntityModel<String> lvName) { + this.lvName = lvName; + } + + public void setSize(EntityModel<String> size) { + this.size = size; + } + + protected void setSelectedDevices(List<StorageDevice> selectedDevices) { + getStorageDevices().setSelectedItems(selectedDevices); + } + + public void setStorageDevices(ListModel<StorageDevice> storageDevices) { + this.storageDevices = storageDevices; + } + + public boolean validate() { + return true; + } + + public String formatSize(double size) { + return NumberFormat.getFormat("#.##").format(size);//$NON-NLS-1$ + } + + public EntityModel<Integer> getStripeSize() { + return stripeSize; + } + + public EntityModel<Integer> getNoOfPhysicalDisksInRaidVolume() { + return noOfPhysicalDisksInRaidVolume; + } + + public void setStripeSize(EntityModel<Integer> stripeSize) { + this.stripeSize = stripeSize; + } + + public void setNoOfPhysicalDisksInRaidVolume(EntityModel<Integer> noOfPhysicalDisksInRaidVolume) { + this.noOfPhysicalDisksInRaidVolume = noOfPhysicalDisksInRaidVolume; + } + + public ListModel<RaidType> getRaidTypeList() { + return raidTypeList; + } + + public void setRaidTypeList(ListModel<RaidType> raidTypeList) { + this.raidTypeList = raidTypeList; + } + + public EntityModel<String> getMountPoint() { + return mountPoint; + } + + public void setMountPoint(EntityModel<String> mountPoint) { + this.mountPoint = mountPoint; + } + + public EntityModel<String> getDefaultMountFolder() { + return defaultMountFolder; + } + + public void setDefaultMountFolder(EntityModel<String> defaultMountFolder) { + this.defaultMountFolder = defaultMountFolder; + } +} diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/HostGlusterStorageDevicesListModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/HostGlusterStorageDevicesListModel.java index 564e28c..ea1a38d 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/HostGlusterStorageDevicesListModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/HostGlusterStorageDevicesListModel.java @@ -1,15 +1,19 @@ package org.ovirt.engine.ui.uicommonweb.models.gluster; - +import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.ovirt.engine.core.common.action.VdcActionType; +import org.ovirt.engine.core.common.action.VdcReturnValueBase; import org.ovirt.engine.core.common.action.VdsActionParameters; +import org.ovirt.engine.core.common.action.gluster.CreateBrickParameters; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSStatus; import org.ovirt.engine.core.common.businessentities.gluster.StorageDevice; import org.ovirt.engine.core.common.mode.ApplicationMode; +import org.ovirt.engine.core.common.queries.ConfigurationValues; +import org.ovirt.engine.core.common.queries.GetConfigurationValueParameters; import org.ovirt.engine.ui.frontend.AsyncQuery; import org.ovirt.engine.ui.frontend.Frontend; import org.ovirt.engine.ui.frontend.INewAsyncCallback; @@ -19,6 +23,8 @@ import org.ovirt.engine.ui.uicommonweb.help.HelpTag; import org.ovirt.engine.ui.uicommonweb.models.SearchableListModel; import org.ovirt.engine.ui.uicompat.ConstantsManager; +import org.ovirt.engine.ui.uicompat.FrontendActionAsyncResult; +import org.ovirt.engine.ui.uicompat.IFrontendActionAsyncCallback; import org.ovirt.engine.ui.uicompat.PropertyChangedEventArgs; public class HostGlusterStorageDevicesListModel extends SearchableListModel { @@ -28,6 +34,7 @@ setHelpTag(HelpTag.gluster_storage_devices); setHashName("gluster_storage_devices"); //$NON-NLS-1$ setSyncStorageDevicesCommand(new UICommand("sync", this)); //$NON-NLS-1$ + setCreateBrickCommand(new UICommand("createBrick", this)); //$NON-NLS-1$ setAvailableInModes(ApplicationMode.GlusterOnly); } @@ -41,6 +48,16 @@ super.setEntity(value); updateActionAvailability(); + } + + private UICommand createBrickCommand; + + public UICommand getCreateBrickCommand() { + return createBrickCommand; + } + + public void setCreateBrickCommand(UICommand createBrickCommand) { + this.createBrickCommand = createBrickCommand; } private UICommand syncStorageDevicesCommand; @@ -99,20 +116,141 @@ return "HostGlusterStorageDevicesListModel"; //$NON-NLS-1$ } + private void createBrick() { + if (getWindow() != null) { + return; + } + + VDS host = getEntity(); + if (host == null) { + return; + } + + final CreateBrickModel lvModel = new CreateBrickModel(); + lvModel.setTitle(ConstantsManager.getInstance().getConstants().createBrick()); + lvModel.setHelpTag(HelpTag.create_brick); + lvModel.setHashName("create_brick"); //$NON-NLS-1$ + lvModel.startProgress(ConstantsManager.getInstance().getConstants().fetchingDataMessage()); + setWindow(lvModel); + + AsyncQuery asyncQueryForDeviceList = new AsyncQuery(); + asyncQueryForDeviceList.setModel(lvModel); + asyncQueryForDeviceList.asyncCallback = new INewAsyncCallback() { + + @Override + public void onSuccess(Object model, Object returnValue) { + lvModel.stopProgress(); + CreateBrickModel lvModel = (CreateBrickModel) model; + List<StorageDevice> devices = (List<StorageDevice>) returnValue; + final List<StorageDevice> eligibleDevices = new ArrayList<>(); + + for (StorageDevice device : devices) { + if (device.getCanCreateBrick()) { + eligibleDevices.add(device); + } + } + lvModel.getStorageDevices().setItems(eligibleDevices); + if (getSelectedItems() != null) { + lvModel.setSelectedDevices(getSelectedItems()); + } + } + }; + AsyncDataProvider.getInstance().getStorageDevices(asyncQueryForDeviceList, host.getId()); + + AsyncQuery asyncQueryForDefaultMountPoint = new AsyncQuery(); + asyncQueryForDefaultMountPoint.setModel(lvModel); + asyncQueryForDefaultMountPoint.asyncCallback = new INewAsyncCallback() { + + @Override + public void onSuccess(Object model, Object returnValue) { + lvModel.stopProgress(); + CreateBrickModel lvModel = (CreateBrickModel) model; + String defaultMountPoint = (String) returnValue; + lvModel.getDefaultMountFolder().setEntity(defaultMountPoint); + } + }; + AsyncDataProvider.getInstance() + .getConfigFromCache(new GetConfigurationValueParameters(ConfigurationValues.DefaultGlusterBrickMountPoint, + AsyncDataProvider.getInstance().getDefaultConfigurationVersion()), + asyncQueryForDefaultMountPoint); + + UICommand okCommand = UICommand.createDefaultOkUiCommand("onCreateBrick", this); //$NON-NLS-1$ + lvModel.getCommands().add(okCommand); + + UICommand cancelCommand = UICommand.createCancelUiCommand("closeWindow", this); //$NON-NLS-1$ + lvModel.getCommands().add(cancelCommand); + } + private void syncStorageDevices() { - Frontend.getInstance().runAction(VdcActionType.SyncStorageDevices, new VdsActionParameters(getEntity().getId())); + Frontend.getInstance() + .runAction(VdcActionType.SyncStorageDevices, new VdsActionParameters(getEntity().getId())); } private void updateActionAvailability() { VDS vds = getEntity(); if (vds != null) { getSyncStorageDevicesCommand().setIsExecutionAllowed(vds.getStatus() == VDSStatus.Up); + getCreateBrickCommand().setIsExecutionAllowed(vds.getStatus() == VDSStatus.Up); } } + + private void onCreateBrick() { + CreateBrickModel lvModel = (CreateBrickModel) getWindow(); + if (lvModel == null) { + return; + } + if (!lvModel.validate()) { + return; + } + + VDS host = getEntity(); + if (host == null) { + return; + } + + lvModel.startProgress(null); + + List<StorageDevice> selectedDevices = new ArrayList<StorageDevice>(); + for (StorageDevice device : lvModel.getStorageDevices().getSelectedItems()) { + selectedDevices.add(device); + } + + CreateBrickParameters parameters = + new CreateBrickParameters(host.getId(), + lvModel.getLvName().getEntity(), + lvModel.getMountPoint().getEntity(), + lvModel.getRaidTypeList().getSelectedItem(), + lvModel.getNoOfPhysicalDisksInRaidVolume().getEntity(), + lvModel.getStripeSize().getEntity(), + selectedDevices); + + Frontend.getInstance().runAction(VdcActionType.CreateBrick, parameters, new IFrontendActionAsyncCallback() { + @Override + public void executed(FrontendActionAsyncResult result) { + postCreateBrick(result.getReturnValue()); + } + }, this); + + } + + private void postCreateBrick(VdcReturnValueBase returnValue) { + CreateBrickModel model = (CreateBrickModel) getWindow(); + model.stopProgress(); + if (returnValue != null && returnValue.getSucceeded()) { + setWindow(null); + } + } + @Override public void executeCommand(UICommand command) { super.executeCommand(command); - if (command.equals(getSyncStorageDevicesCommand())) { + if (command.equals(getCreateBrickCommand())) { + createBrick(); + } else if (command.getName().equals("onCreateBrick")) { //$NON-NLS-1$ + onCreateBrick(); + } else if (command.getName().equals("closeWindow")) { //$NON-NLS-1$ + setWindow(null); + } else if (command.equals(getSyncStorageDevicesCommand())) { syncStorageDevices(); } } diff --git a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java index abf3f5f..4eb14b9 100644 --- a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java +++ b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java @@ -511,6 +511,10 @@ String AuditLogType___GLUSTER_VOLUME_SNAPSHOT_CREATE_FAILED(); + String AuditLogType___CREATE_GLUSTER_BRICK(); + + String AuditLogType___CREATE_GLUSTER_BRICK_FAILED(); + String VdcActionType___ActivateVds(); String VdcActionType___RecoveryStoragePool(); @@ -856,6 +860,8 @@ String VdcActionType___RestoreGlusterVolumeSnapshot(); + String VdcActionType___CreateBrick(); + String VdcObjectType___AdElements(); String VdcObjectType___System(); @@ -986,6 +992,20 @@ String GlusterServiceStatus___UNKNOWN(); + String RaidType___None(); + + String RaidType___Raid0(); + + String RaidType___Raid1(); + + String RaidType___Raid2(); + + String RaidType___Raid5(); + + String RaidType___Raid6(); + + String RaidType___Raid10(); + String VmWatchdogType___i6300esb(); String VmWatchdogAction___NONE(); diff --git a/frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties b/frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties index c8b59bc..cddf30f 100644 --- a/frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties +++ b/frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties @@ -253,6 +253,8 @@ AuditLogType___GLUSTER_VOLUME_SNAPSHOT_CONFIG_UPDATE_FAILED_PARTIALLY=Failed to update some gluster volume snapshot configuration AuditLogType___GLUSTER_MASTER_VOLUME_STOP_FAILED_DURING_SNAPSHOT_RESTORE=Could not stop master volume ${glusterVolumeName} during snapshot restore. AuditLogType___GLUSTER_MASTER_VOLUME_SNAPSHOT_RESTORE_FAILED=Could not restore master volume ${glusterVolumeName}. +AuditLogType___CREATE_GLUSTER_BRICK=Brick ${brickName} created successfully. +AuditLogType___CREATE_GLUSTER_BRICK_FAILED=Failed to create brick ${brickName}. VdcActionType___ActivateVds=Activate Host VdcActionType___RecoveryStoragePool=Reinitialize Data Center @@ -381,6 +383,7 @@ VdcActionType___AddGlusterHook=Add Gluster Hook VdcActionType___RemoveGlusterHook=Remove Gluster Hook VdcActionType___RefreshGlusterHook=Refresh Gluster Hook +VdcActionType___CreateBrick=Create Brick VdcActionType___ManageGlusterService=Manage Service VdcActionType___RefreshGeoRepSessions=Refresh Geo-replication Sessions VdcActionType___CreateGlusterVolumeGeoRepSession=Created geo-replication session @@ -492,6 +495,13 @@ GlusterServiceStatus___MIXED=Partially Up GlusterServiceStatus___NOT_AVAILABLE=Not Installed GlusterServiceStatus___UNKNOWN=Unknown +RaidType___None=None +RaidType___Raid0=Raid0 +RaidType___Raid1=Raid1 +RaidType___Raid2=Raid2 +RaidType___Raid5=Raid5 +RaidType___Raid6=Raid6 +RaidType___Raid10=Raid10 VmWatchdogType___i6300esb=i6300esb VmWatchdogAction___NONE=none VmWatchdogAction___RESET=reset diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java index c3679c7..97fc2e6 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java @@ -41,6 +41,7 @@ import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.event.EventPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.AddBrickPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.BrickAdvancedDetailsPopupPresenterWidget; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.CreateBrickPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.DetachGlusterHostsPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterClusterSnapshotConfigureOptionsPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeGeoRepActionConfirmPopUpViewPresenterWidget; @@ -284,6 +285,7 @@ import org.ovirt.engine.ui.webadmin.section.main.view.popup.event.EventPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.AddBrickPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.BrickAdvancedDetailsPopupView; +import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.CreateBrickPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.DetachGlusterHostsPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GeoRepActionConfirmPopUpView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GlusterClusterSnapshotConfigureOptionsPopupView; @@ -1480,6 +1482,10 @@ AddBrickPopupPresenterWidget.ViewDef.class, AddBrickPopupView.class); + bindPresenterWidget(CreateBrickPopupPresenterWidget.class, + CreateBrickPopupPresenterWidget.ViewDef.class, + CreateBrickPopupView.class); + bindPresenterWidget(RemoveBrickPopupPresenterWidget.class, RemoveBrickPopupPresenterWidget.ViewDef.class, RemoveBrickPopupView.class); diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/HostModule.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/HostModule.java index 4936ab7..1756a10 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/HostModule.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/HostModule.java @@ -48,6 +48,7 @@ import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.DetachConfirmationPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.PermissionsPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.event.EventPopupPresenterWidget; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.CreateBrickPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.host.ConfigureLocalStoragePopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.host.HostBondPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.host.HostInstallPopupPresenterWidget; @@ -183,11 +184,23 @@ @Provides @Singleton public SearchableDetailModelProvider<StorageDevice, HostListModel, HostGlusterStorageDevicesListModel> getHostGlusterStorageDevicesListProvider(EventBus eventBus, - Provider<DefaultConfirmationPopupPresenterWidget> defaultConfirmPopupProvider) { + Provider<DefaultConfirmationPopupPresenterWidget> defaultConfirmPopupProvider, + final Provider<CreateBrickPopupPresenterWidget> createBrickPopupProvider) { return new SearchableDetailTabModelProvider<StorageDevice, HostListModel, HostGlusterStorageDevicesListModel>( eventBus, defaultConfirmPopupProvider, HostListModel.class, - HostGlusterStorageDevicesListModel.class); + HostGlusterStorageDevicesListModel.class){ + @Override + public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(HostGlusterStorageDevicesListModel source, + UICommand lastExecutedCommand, + Model windowModel) { + if (lastExecutedCommand == getModel().getCreateBrickCommand()) { + return createBrickPopupProvider.get(); + } else { + return super.getModelPopup(source, lastExecutedCommand, windowModel); + } + } + }; } @Provides diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/CreateBrickPopupPresenterWidget.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/CreateBrickPopupPresenterWidget.java new file mode 100644 index 0000000..86651db --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/CreateBrickPopupPresenterWidget.java @@ -0,0 +1,46 @@ +package org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster; + +import org.ovirt.engine.core.common.businessentities.RaidType; +import org.ovirt.engine.ui.common.presenter.AbstractModelBoundPopupPresenterWidget; +import org.ovirt.engine.ui.uicommonweb.models.gluster.CreateBrickModel; +import org.ovirt.engine.ui.uicompat.Event; +import org.ovirt.engine.ui.uicompat.IEventListener; +import org.ovirt.engine.ui.uicompat.PropertyChangedEventArgs; + +import com.google.gwt.event.shared.EventBus; +import com.google.inject.Inject; + +public class CreateBrickPopupPresenterWidget extends AbstractModelBoundPopupPresenterWidget<CreateBrickModel, CreateBrickPopupPresenterWidget.ViewDef> { + + public interface ViewDef extends AbstractModelBoundPopupPresenterWidget.ViewDef<CreateBrickModel> { + void setDeviceInfoText(String raidType); + void setDeviceInfoVisibility(boolean isVisiable); + } + + @Inject + public CreateBrickPopupPresenterWidget(EventBus eventBus, ViewDef view) { + super(eventBus, view); + } + + @Override + public void init(final CreateBrickModel model) { + super.init(model); + model.getPropertyChangedEvent().addListener(new IEventListener<PropertyChangedEventArgs>() { + @Override + public void eventRaised(Event<? extends PropertyChangedEventArgs> ev, + Object sender, + PropertyChangedEventArgs args) { + String propName = args.propertyName; + if ("raidTypeChanged".equals(propName)) { //$NON-NLS-1$ + if (model.getRaidTypeList().getSelectedItem() != RaidType.None + && model.getRaidTypeList().getSelectedItem() != RaidType.Raid0) { + getView().setDeviceInfoText(model.getRaidTypeList().getSelectedItem().name()); + getView().setDeviceInfoVisibility(true); + } else { + getView().setDeviceInfoVisibility(false); + } + } + } + }); + } +} diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/CreateBrickPopupView.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/CreateBrickPopupView.java new file mode 100644 index 0000000..934baf9 --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/CreateBrickPopupView.java @@ -0,0 +1,181 @@ +package org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster; + +import org.ovirt.engine.core.common.businessentities.RaidType; +import org.ovirt.engine.core.common.businessentities.gluster.StorageDevice; +import org.ovirt.engine.core.common.utils.Pair; +import org.ovirt.engine.core.common.utils.SizeConverter; +import org.ovirt.engine.core.common.utils.SizeConverter.SizeUnit; +import org.ovirt.engine.ui.common.idhandler.ElementIdHandler; +import org.ovirt.engine.ui.common.idhandler.WithElementId; +import org.ovirt.engine.ui.common.view.popup.AbstractModelBoundPopupView; +import org.ovirt.engine.ui.common.widget.dialog.SimpleDialogPanel; +import org.ovirt.engine.ui.common.widget.editor.ListModelListBoxEditor; +import org.ovirt.engine.ui.common.widget.editor.ListModelObjectCellTable; +import org.ovirt.engine.ui.common.widget.editor.generic.IntegerEntityModelTextBoxEditor; +import org.ovirt.engine.ui.common.widget.editor.generic.StringEntityModelLabelEditor; +import org.ovirt.engine.ui.common.widget.editor.generic.StringEntityModelTextBoxEditor; +import org.ovirt.engine.ui.common.widget.renderer.EnumRenderer; +import org.ovirt.engine.ui.common.widget.table.column.AbstractTextColumn; +import org.ovirt.engine.ui.uicommonweb.models.ListModel; +import org.ovirt.engine.ui.uicommonweb.models.gluster.CreateBrickModel; +import org.ovirt.engine.ui.webadmin.ApplicationConstants; +import org.ovirt.engine.ui.webadmin.gin.AssetProvider; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.CreateBrickPopupPresenterWidget; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.editor.client.SimpleBeanEditorDriver; +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.i18n.client.NumberFormat; +import com.google.gwt.resources.client.CssResource; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Label; +import com.google.inject.Inject; + +public class CreateBrickPopupView extends AbstractModelBoundPopupView<CreateBrickModel> implements CreateBrickPopupPresenterWidget.ViewDef { + + interface Driver extends SimpleBeanEditorDriver<CreateBrickModel, CreateBrickPopupView> { + } + + interface ViewUiBinder extends UiBinder<SimpleDialogPanel, CreateBrickPopupView> { + ViewUiBinder uiBinder = GWT.create(ViewUiBinder.class); + } + + interface ViewIdHandler extends ElementIdHandler<CreateBrickPopupView> { + ViewIdHandler idHandler = GWT.create(ViewIdHandler.class); + } + + interface WidgetStyle extends CssResource { + String editorContentWidget(); + + String forceEditorWidget(); + } + + @UiField + @Path(value = "lvName.entity") + @WithElementId + StringEntityModelTextBoxEditor lvNameEditor; + + @UiField + @Path(value = "mountPoint.entity") + @WithElementId + StringEntityModelTextBoxEditor mountPointEditor; + + @UiField + @Ignore + @WithElementId + Label deviceHeader; + + @UiField(provided = true) + @Ignore + @WithElementId + ListModelObjectCellTable<StorageDevice, ListModel<StorageDevice>> deviceTable; + + @UiField + @Path(value = "size.entity") + @WithElementId + StringEntityModelLabelEditor sizeEditor; + + @UiField(provided = true) + @Path(value = "raidTypeList.selectedItem") + @WithElementId + ListModelListBoxEditor<RaidType> raidTypeEditor; + + @UiField + @Ignore + Label deviceSelectionInfo; + + @UiField + @Path(value = "noOfPhysicalDisksInRaidVolume.entity") + @WithElementId + IntegerEntityModelTextBoxEditor noOfPhysicalDisksEditor; + + @UiField + @Path(value = "stripeSize.entity") + @WithElementId + IntegerEntityModelTextBoxEditor stripeSizeEditor; + + private final static ApplicationConstants constants = AssetProvider.getConstants(); + + private final Driver driver = GWT.create(Driver.class); + + @Inject + public CreateBrickPopupView(EventBus eventBus) { + super(eventBus); + initListBoxEditors(); + deviceTable = new ListModelObjectCellTable<StorageDevice, ListModel<StorageDevice>>(true, false); + initWidget(ViewUiBinder.uiBinder.createAndBindUi(this)); + ViewIdHandler.idHandler.generateAndSetIds(this); + localize(constants); + initTableColumns(constants); + driver.initialize(this); + } + + private void initListBoxEditors() { + raidTypeEditor = new ListModelListBoxEditor<RaidType>(new EnumRenderer<RaidType>()); + } + + protected void initTableColumns(ApplicationConstants constants) { + // Table Entity Columns + deviceTable.addColumn(new AbstractTextColumn<StorageDevice>() { + @Override + public String getValue(StorageDevice entity) { + return entity.getName(); + } + }, constants.deviceName()); + + deviceTable.addColumnAndSetWidth(new AbstractTextColumn<StorageDevice>() { + @Override + public String getValue(StorageDevice entity) { + return entity.getDevType(); + } + }, constants.deviceType(), "100px"); //$NON-NLS-1$ + + deviceTable.addColumnAndSetWidth(new AbstractTextColumn<StorageDevice>() { + @Override + public String getValue(StorageDevice entity) { + Pair<SizeUnit, Double> convertedSize = SizeConverter.autoConvert(entity.getSize(), SizeUnit.MB); + return formatSize(convertedSize.getSecond()) + " " + convertedSize.getFirst().toString(); //$NON-NLS-1$ + } + }, constants.size(), "100px"); //$NON-NLS-1$ + } + + private void localize(ApplicationConstants constants) { + lvNameEditor.setLabel(constants.logicalVolume()); + mountPointEditor.setLabel(constants.mountPoint()); + sizeEditor.setLabel(constants.lvSize()); + raidTypeEditor.setLabel(constants.raidType()); + noOfPhysicalDisksEditor.setLabel(constants.noOfPhysicalDisksInRaidVolume()); + stripeSizeEditor.setLabel(constants.stripeSize()); + deviceHeader.setText(constants.storageDevices()); + deviceSelectionInfo.setText(constants.getStorageDeviceSelectionInfo()); + } + + @Override + public void edit(final CreateBrickModel object) { + deviceTable.asEditor().edit(object.getStorageDevices()); + driver.edit(object); + deviceSelectionInfo.setText(null); + setDeviceInfoVisibility(false); + } + + @Override + public CreateBrickModel flush() { + deviceTable.flush(); + return driver.flush(); + } + + public String formatSize(double size) { + return NumberFormat.getFormat("#.##").format(size);//$NON-NLS-1$ + } + + @Override + public void setDeviceInfoText(String raidType) { + deviceSelectionInfo.setText("(" + constants.getStorageDeviceSelectionInfo() + raidType + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + @Override + public void setDeviceInfoVisibility(boolean isVisiable) { + deviceSelectionInfo.setVisible(isVisiable); + } +} diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/CreateBrickPopupView.ui.xml b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/CreateBrickPopupView.ui.xml new file mode 100644 index 0000000..561a032 --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/CreateBrickPopupView.ui.xml @@ -0,0 +1,48 @@ +<?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> + .headerLabel { + font-weight: bold; + padding: 5px; + } + + .tablePanel { + height: 270px; + width: 530px; + padding-left: 15px; + padding-bottom: 15px; + border: 1px solid #CED8DF; + } + .explanationLabel { + font-style: italic; + padding-bottom: 10px; + } + </ui:style> + + <d:SimpleDialogPanel width="550px" height="575px"> + <d:content> + <g:FlowPanel> + <ge:StringEntityModelTextBoxEditor ui:field="lvNameEditor" /> + <ge:StringEntityModelTextBoxEditor ui:field="mountPointEditor" /> + <e:ListModelListBoxEditor ui:field="raidTypeEditor" /> + <ge:IntegerEntityModelTextBoxEditor ui:field="noOfPhysicalDisksEditor" /> + <ge:IntegerEntityModelTextBoxEditor ui:field="stripeSizeEditor" /> + <g:Label ui:field="deviceHeader" addStyleNames="{style.headerLabel}"/> + <g:Label ui:field="deviceSelectionInfo" addStyleNames="{style.explanationLabel}"/> + <g:HorizontalPanel spacing="5" verticalAlignment="ALIGN_MIDDLE"> + <g:VerticalPanel> + <g:ScrollPanel addStyleNames="{style.tablePanel}"> + <e:ListModelObjectCellTable ui:field="deviceTable"/> + </g:ScrollPanel> + </g:VerticalPanel> + </g:HorizontalPanel> + <ge:StringEntityModelLabelEditor ui:field="sizeEditor" /> + </g:FlowPanel> + </d:content> + </d:SimpleDialogPanel> +</ui:UiBinder> diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/host/SubTabHostGlusterStorageDevicesView.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/host/SubTabHostGlusterStorageDevicesView.java index 1dde554..353925b 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/host/SubTabHostGlusterStorageDevicesView.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/host/SubTabHostGlusterStorageDevicesView.java @@ -97,6 +97,13 @@ fsTypeColumn.makeSortable(); getTable().addColumn(fsTypeColumn, constants.fileSystemType(), "170px"); //$NON-NLS-1$ + getTable().addActionButton(new WebAdminButtonDefinition<StorageDevice>(constants.createBrick()) { + @Override + protected UICommand resolveCommand() { + return getDetailModel().getCreateBrickCommand(); + } + }); + getTable().addActionButton(new WebAdminButtonDefinition<StorageDevice>(constants.syncStorageDevices()) { @Override protected UICommand resolveCommand() { diff --git a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties index fdf6fc8..8abb59f 100644 --- a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties +++ b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties @@ -1133,6 +1133,10 @@ ACTION_TYPE_FAILED_GLUSTER_VOLUME_SNAPSHOT_ALREADY_ACTIVATED=Cannot ${action} ${type}. Gluster volume snapshot ${snapname} is already activated. ACTION_TYPE_FAILED_GLUSTER_VOLUME_SNAPSHOT_ALREADY_DEACTIVATED=Cannot ${action} ${type}. Gluster volume snapshot ${snapname} is already de-activated. GLUSTER_TASKS_NOT_SUPPORTED_FOR_CLUSTER_LEVEL=Cannot ${action} ${type}. Gluster task management is not supported in compatibility version ${compatibilityVersion}. +ACTION_TYPE_FAILED_STORAGE_DEVICE_LOCKED=Cannot ${action} ${type}. Storage Device is locked. +ACTION_TYPE_FAILED_STORAGE_DEVICE_REQUIRED=Cannot ${action} ${type}. At least one storage device is required. +ACTION_TYPE_FAILED_DIFFERENT_STORAGE_DEVICE_TYPES_SELECTED=Cannot ${action} ${type}. Different types of storage devices are selected. +ACTION_TYPE_FAILED_DEVICE_IS_ALREADY_IN_USE=Cannot ${action} ${type}. Storage Device ${storageDevice} is already in use. ACTION_TYPE_FAILED_TAG_ID_REQUIRED=Cannot ${action} ${type}. Tag ID is required. -- To view, visit https://gerrit.ovirt.org/40190 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If43b6503dd8362d2a0907ac9648335a750828427 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: ovirt-engine-3.5-gluster Gerrit-Owner: Ramesh N <rnach...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches