anmolbabu has uploaded a new change for review. Change subject: webadmin : Extend brick from storage devices sutab ......................................................................
webadmin : Extend brick from storage devices sutab Extend brick from storage devices sutab Change-Id: I5ac28696ff29feb56b75c69aa0d506e9ad672446 Signed-off-by: Anmol Babu <[email protected]> --- M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/HostStorageDevicesListModel.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/LogicalVolumeModel.java M frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIConstants.java M frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIMessages.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/HostModule.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/CreateBrickPopupView.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/CreateBrickPopupView.ui.xml 8 files changed, 191 insertions(+), 76 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/14/36314/1 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 acfb3a4..2d7e814 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 @@ -459,6 +459,9 @@ create_brick( "create_brick", HelpTagType.WEBADMIN, "[gluster] Hosts main tab -> Storage Devices sub tab -> 'Create Brick' dialog"), //$NON-NLS-1$ //$NON-NLS-2$ + extend_brick( + "extend_brick", HelpTagType.WEBADMIN, "[gluster] Hosts main tab -> Storage Devices sub tab -> 'Extend 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/HostStorageDevicesListModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/HostStorageDevicesListModel.java index 8cea381..1d5535f 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/HostStorageDevicesListModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/HostStorageDevicesListModel.java @@ -7,6 +7,7 @@ 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.GlusterBrickEntity; import org.ovirt.engine.core.common.businessentities.gluster.StorageDevice; import org.ovirt.engine.core.common.mode.ApplicationMode; import org.ovirt.engine.ui.frontend.AsyncQuery; @@ -98,7 +99,49 @@ } private void extendBrick() { + } + private LogicalVolumeModel getBrickBaseDialog(String title, HelpTag helpTag, String hashName) { + final List<StorageDevice> eligibleDevices = new ArrayList<StorageDevice>(); + if (getWindow() != null) { + return null; + } + + VDS host = getEntity(); + if (host == null || host.getStatus() != VDSStatus.Up) { + return null; + } + + final LogicalVolumeModel lvModel = new LogicalVolumeModel(); + lvModel.setTitle(title); + lvModel.setHelpTag(helpTag); + lvModel.setHashName(hashName); + lvModel.startProgress(ConstantsManager.getInstance().getConstants().fetchingDataMessage()); + setWindow(lvModel); + + AsyncQuery asyncQuery = new AsyncQuery(); + asyncQuery.setModel(lvModel); + asyncQuery.asyncCallback = new INewAsyncCallback() { + @Override + public void onSuccess(Object model, Object returnValue) { + lvModel.stopProgress(); + lvModel.initSize(); + LogicalVolumeModel lvModel = (LogicalVolumeModel) model; + List<StorageDevice> devices = (List<StorageDevice>) returnValue; + + for (StorageDevice device : devices) { + if (device.getCanCreateBrick()) { + eligibleDevices.add(device); + } + } + if (getSelectedItems() != null) { + lvModel.setSelectedDevices(getSelectedItems()); + } + lvModel.getStorageDevices().setItems(eligibleDevices); + } + }; + AsyncDataProvider.getInstance().getStorageDevices(asyncQuery, host.getId()); + return lvModel; } public UICommand getCreateBrickCommand() { @@ -154,48 +197,9 @@ } private void showCreateBrickDialog() { - final List<StorageDevice> eligibleDevices = new ArrayList<StorageDevice>(); - if (getWindow() != null) { - return; - } - - VDS host = getEntity(); - if (host == null || host.getStatus() != VDSStatus.Up) { - return; - } - - final LogicalVolumeModel lvModel = new LogicalVolumeModel(); - 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 asyncQuery = new AsyncQuery(); - asyncQuery.setModel(lvModel); - asyncQuery.asyncCallback = new INewAsyncCallback() { - - @Override - public void onSuccess(Object model, Object returnValue) { - lvModel.stopProgress(); - lvModel.initSize(); - LogicalVolumeModel lvModel = (LogicalVolumeModel) model; - List<StorageDevice> devices = (List<StorageDevice>) returnValue; - - for (StorageDevice device : devices) { - if (device.getCanCreateBrick()) { - eligibleDevices.add(device); - } - } - if (getSelectedItems() != null) { - lvModel.setSelectedDevices(getSelectedItems()); - } - lvModel.getStorageDevices().setItems(eligibleDevices); - - } - }; - AsyncDataProvider.getInstance().getStorageDevices(asyncQuery, host.getId()); - + LogicalVolumeModel lvModel = + getBrickBaseDialog(ConstantsManager.getInstance().getConstants().createBrick(), + HelpTag.create_brick, "create_brick"); //$NON-NLS-1$ UICommand okCommand = new UICommand("OnCreateBrick", this); //$NON-NLS-1$ okCommand.setTitle(ConstantsManager.getInstance().getConstants().ok()); okCommand.setIsDefault(true); @@ -208,8 +212,30 @@ } private void showExtendBrickDialog() { + final LogicalVolumeModel lvModel = + getBrickBaseDialog(ConstantsManager.getInstance().getConstants().extendBrick(), + HelpTag.extend_brick, + "extend_brick");//$NON-NLS-1$ + AsyncDataProvider.getInstance().getGlusterBricksForServer(new AsyncQuery(new INewAsyncCallback() { + @Override + public void onSuccess(Object model, Object returnValue) { + List<GlusterBrickEntity> bricks = (List<GlusterBrickEntity>) returnValue; + lvModel.setBricks(bricks); + } + }), getEntity().getId()); + + UICommand okCommand = new UICommand("OnExtendBrick", this); //$NON-NLS-1$ + okCommand.setTitle(ConstantsManager.getInstance().getConstants().ok()); + okCommand.setIsDefault(true); + lvModel.getCommands().add(okCommand); + + UICommand cancelCommand = new UICommand("Cancel", this); //$NON-NLS-1$ + cancelCommand.setTitle(ConstantsManager.getInstance().getConstants().cancel()); + cancelCommand.setIsCancel(true); + lvModel.getCommands().add(cancelCommand); } + @Override protected void syncSearch() { diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/LogicalVolumeModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/LogicalVolumeModel.java index ca65818..8a03826 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/LogicalVolumeModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/LogicalVolumeModel.java @@ -3,6 +3,8 @@ import java.util.Arrays; import java.util.List; +import org.ovirt.engine.core.common.businessentities.gluster.BrickDetails; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterBrickEntity; 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; @@ -10,6 +12,7 @@ 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.ConstantsManager; import org.ovirt.engine.ui.uicompat.Event; import org.ovirt.engine.ui.uicompat.EventArgs; import org.ovirt.engine.ui.uicompat.IEventListener; @@ -17,6 +20,7 @@ import com.google.gwt.i18n.client.NumberFormat; public class LogicalVolumeModel extends Model { + private ListModel<GlusterBrickEntity> bricks; private ListModel<String> fsTypes; private EntityModel<String> lvName; private ListModel<EntityModel<String>> optimization; @@ -29,20 +33,38 @@ setSize(new EntityModel<String>()); setFsTypes(new ListModel<String>()); setOptimization(new ListModel<EntityModel<String>>()); + setBricks(new ListModel<GlusterBrickEntity>()); getFsTypes().setItems(Arrays.asList("XFS", "ext4", "ext3")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - getStorageDevices().getSelectedItemsChangedEvent().addListener(new IEventListener<EventArgs>() { - @Override - public void eventRaised(Event<? extends EventArgs> ev, Object sender, EventArgs args) { - updateBrickSize(); + registerEditorEventHandlers(); + + setAvailabilities(); + } + + private Pair<SizeUnit, Double> calculateBrickSize(long totalSize) { + totalSize = calculateBrickSizeIncrement(); + return SizeConverter.autoConvert(totalSize, SizeUnit.MB); + } + + private long calculateBrickSizeIncrement() { + long totalSize = 0; + if (getStorageDevices().getSelectedItems() != null) { + for (StorageDevice storageDevice : getStorageDevices().getSelectedItems()) { + if (storageDevice.getSize() != null) { + totalSize += storageDevice.getSize(); + } } - - }); + } + return totalSize; } public String formatSize(double size) { return NumberFormat.getFormat("#.##").format(size);//$NON-NLS-1$ + } + + public ListModel<GlusterBrickEntity> getBricks() { + return bricks; } public ListModel<String> getFsTypes() { @@ -70,12 +92,64 @@ } protected void initSize() { - setBrickSize(new Pair<SizeConverter.SizeUnit, Double>(SizeUnit.BYTES, 0D)); + if (getBricks().getSelectedItem() != null && getBricks().getSelectedItem().getBrickDetails().getBrickProperties() != null) { + setBrickSize(SizeConverter.autoConvert((long) getBricks().getSelectedItem() + .getBrickDetails() + .getBrickProperties() + .getTotalSize(), SizeUnit.MB)); + } else { + setBrickSize(new Pair<SizeConverter.SizeUnit, Double>(SizeUnit.BYTES, 0D)); + } + } + + private void registerEditorEventHandlers() { + getStorageDevices().getSelectedItemsChangedEvent().addListener(new IEventListener<EventArgs>() { + @Override + public void eventRaised(Event<? extends EventArgs> ev, Object sender, EventArgs args) { + setBrickSize(); + } + }); + } + + private void setAvailabilities() { + getBricks().setIsAvailable(false); + } + + protected void setBricks(List<GlusterBrickEntity> bricks) { + getBricks().setItems(bricks); + getBricks().setIsAvailable(true); + getLvName().setIsAvailable(false); + initSize(); + } + + public void setBricks(ListModel<GlusterBrickEntity> bricks) { + this.bricks = bricks; + } + + private void setBrickSize() { + long incrementSize = calculateBrickSizeIncrement(); + Pair<SizeUnit, Double> convertedSize = calculateBrickSize(incrementSize); + GlusterBrickEntity selectedBrick = getBricks().getSelectedItem(); + if (getBricks().getIsAvailable() && selectedBrick != null) { + BrickDetails brickDetails = selectedBrick.getBrickDetails(); + if (brickDetails != null && brickDetails.getBrickProperties() != null) { + long currentBrickSize = (long) brickDetails.getBrickProperties().getTotalSize(); + setBrickSize(SizeConverter.autoConvert(currentBrickSize + incrementSize, SizeUnit.MB), SizeConverter.autoConvert(currentBrickSize, SizeUnit.MB)); + return; + } + } + setBrickSize(convertedSize); } private void setBrickSize(Pair<SizeUnit, Double> size) { String sizeString = getSizeString(size); getSize().setEntity(sizeString); + } + + private void setBrickSize(Pair<SizeUnit, Double> newSize, Pair<SizeUnit, Double> oldSize) { + String newSizeString = getSizeString(newSize); + String oldSizeString = getSizeString(oldSize); + getSize().setEntity(ConstantsManager.getInstance().getMessages().lvExpandedSize(newSizeString, oldSizeString)); } public void setFsTypes(ListModel<String> fsTypes) { @@ -100,20 +174,6 @@ public void setStorageDevices(ListModel<StorageDevice> storageDevices) { this.storageDevices = storageDevices; - } - - private void updateBrickSize() { - long totalSize = 0; - if (getStorageDevices().getSelectedItems() != null) { - for (StorageDevice storageDevice : getStorageDevices().getSelectedItems()) { - if (storageDevice.getSize() != null) { - totalSize += storageDevice.getSize(); - } - } - } - - Pair<SizeUnit, Double> convertedSize = SizeConverter.autoConvert(totalSize, SizeUnit.MB); - setBrickSize(convertedSize); } public boolean validate() { diff --git a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIConstants.java b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIConstants.java index 3ea578a..a8f1939 100644 --- a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIConstants.java +++ b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIConstants.java @@ -2494,4 +2494,7 @@ @DefaultStringValue("Create Brick") String createBrick(); + + @DefaultStringValue("Extend Brick") + String extendBrick(); } diff --git a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIMessages.java b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIMessages.java index 64d019b..40706ee 100644 --- a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIMessages.java +++ b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/UIMessages.java @@ -415,4 +415,7 @@ @DefaultMessage("Do you approve trusting self signed certificate subject {0}, SHA-1 fingerprint {1}?") String approveRootCertificateTrust(String subject, String sha1Fingerprint); + + @DefaultMessage("{0} from {1}") + String lvExpandedSize(String newSize, String oldSize); } 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 52dbdbb..5030f1a 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 @@ -284,7 +284,7 @@ public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(HostStorageDevicesListModel source, UICommand lastExecutedCommand, Model windowModel) { - if (lastExecutedCommand == getModel().getCreateBrickCommand()) { + if (lastExecutedCommand == getModel().getCreateBrickCommand() || lastExecutedCommand == getModel().getExtendBrickCommand()) { return createBrickPopupProvider.get(); } else { return super.getModelPopup(source, lastExecutedCommand, windowModel); 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 index 757f08b..57256b9 100644 --- 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 @@ -1,5 +1,6 @@ package org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterBrickEntity; 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; @@ -12,6 +13,7 @@ import org.ovirt.engine.ui.common.widget.editor.ListModelObjectCellTable; 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.NullSafeRenderer; import org.ovirt.engine.ui.common.widget.table.column.TextColumnWithTooltip; import org.ovirt.engine.ui.uicommonweb.models.EntityModel; import org.ovirt.engine.ui.uicommonweb.models.ListModel; @@ -49,6 +51,11 @@ String forceEditorWidget(); } + @UiField(provided = true) + @Path(value = "bricks.selectedItem") + @WithElementId + ListModelListBoxEditor<GlusterBrickEntity> bricks; + @UiField @Ignore @WithElementId @@ -79,14 +86,11 @@ @Inject public CreateBrickPopupView(EventBus eventBus, ApplicationResources resources, ApplicationConstants constants) { super(eventBus, resources); - deviceTable = new ListModelObjectCellTable<StorageDevice, ListModel<StorageDevice>>(true, true); - deviceTable.enableColumnResizing(); + initEditors(constants); initWidget(ViewUiBinder.uiBinder.createAndBindUi(this)); ViewIdHandler.idHandler.generateAndSetIds(this); localize(constants); - initTableColumns(constants); driver.initialize(this); - } @Override @@ -105,16 +109,29 @@ return NumberFormat.getFormat("#.##").format(size);//$NON-NLS-1$ } + private void initEditors(ApplicationConstants constants) { + deviceTable = new ListModelObjectCellTable<StorageDevice, ListModel<StorageDevice>>(true, true); + deviceTable.enableColumnResizing(); + initTableColumns(constants); + + bricks = new ListModelListBoxEditor<>(new NullSafeRenderer<GlusterBrickEntity>() { + @Override + protected String renderNullSafe(GlusterBrickEntity object) { + return object.getQualifiedName(); + } + }); + } + protected void initTableColumns(ApplicationConstants constants){ // Table Entity Columns - deviceTable.addColumn(new TextColumnWithTooltip<StorageDevice>() { + deviceTable.addColumnAndSetWidth(new TextColumnWithTooltip<StorageDevice>() { @Override public String getValue(StorageDevice entity) { return entity.getName(); } - }, constants.deviceName()); + }, constants.deviceName(), "380px");//$NON-NLS-1$ - deviceTable.addColumn(new TextColumnWithTooltip<StorageDevice>() { + deviceTable.addColumnAndSetWidth(new TextColumnWithTooltip<StorageDevice>() { @Override public String getValue(StorageDevice entity) { if (entity.getSize() != null) { @@ -124,7 +141,7 @@ return ""; //$NON-NLS-1$ } } - }, constants.size()); + }, constants.size(), "120px");//$NON-NLS-1$ } private void localize(ApplicationConstants constants) { @@ -132,5 +149,6 @@ sizeEditor.setLabel(constants.lvSize()); deviceHeader.setText(constants.storageDevices()); optimizationEditor.setLabel(constants.optimizationCriteria()); + bricks.setLabel(constants.logicalVolume()); } } 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 index 499b036..c0c9e21 100644 --- 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 @@ -16,7 +16,6 @@ .tablePanel { height: 270px; width: 530px; - padding-left: 15px; border: 1px solid #CED8DF; } </ui:style> @@ -25,10 +24,13 @@ <d:content> <g:FlowPanel> <ge:StringEntityModelTextBoxEditor ui:field="lvNameEditor" /> + <e:ListModelListBoxEditor ui:field="bricks"/> <g:Label ui:field="deviceHeader" addStyleNames="{style.headerLabel}"/> - <g:ScrollPanel addStyleNames="{style.tablePanel}"> - <e:ListModelObjectCellTable ui:field="deviceTable"/> - </g:ScrollPanel> + <g:VerticalPanel addStyleNames="{style.tablePanel}" horizontalAlignment="ALIGN_CENTER"> + <g:ScrollPanel addStyleNames="{style.tablePanel}"> + <e:ListModelObjectCellTable ui:field="deviceTable"/> + </g:ScrollPanel> + </g:VerticalPanel> <ge:StringEntityModelLabelEditor ui:field="sizeEditor" /> <e:ListModelListBoxEditor ui:field="optimizationEditor"/> </g:FlowPanel> -- To view, visit http://gerrit.ovirt.org/36314 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5ac28696ff29feb56b75c69aa0d506e9ad672446 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: anmolbabu <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
