Vojtech Szocs has uploaded a new change for review. Change subject: webadmin,userportal: Progress indicator during login ......................................................................
webadmin,userportal: Progress indicator during login This patch makes sure that a progress indicator, represented as the 'wait' mouse cursor, is shown during the entire login process. >From UiCommon/GWTP point of view, the login process consists of following steps: 0. Default place of login section (#login) gets revealed 1a. If the user is already logged-in on the backend: * UiCommon LoginModel is instructed to sign the user in automatically by calling its AutoLogin method * AutoLogin method takes care of populating appropriate UI fields (UserName, Domain) and fires LoggedInEvent 1b. If the user is NOT already logged-in on the backend: * User fills the login form and hits Enter/Login * UiCommon LoginModel is instructed to initiate the login operation (authentication) by calling its Login method * If successful, Login method fires LoggedInEvent 2. WebAdmin/UserPortal ApplicationInit.onLogin method gets called in response to LoginModel's LoggedInEvent: * Both WebAdmin and UserPortal do some early init logic and then call BaseApplicationInit.performLogin method * BaseApplicationInit.performLogin represents actions taken by UI after successful user authentication 3. Default place of main section (#vms) gets revealed Instead of showing/hiding progress indicator for each of the steps outlined above (e.g. using LoginModel "Progress" for the authentication operation in step 1b), progress indicator is shown once, when the actual login process starts (1a/1b), and is hidden after reaching main section (3). LockInteractionManager is the class responsible for handling progress indicator. For now, it only reacts to "GWTP place transition finished" events, in order to hide the progress indicator after GWTP place transition (e.g. #login -> #vms). In future, it can react to "GWTP place transition started" events as well. For now, there is only one kind of progress indicator: 'wait' mouse cursor (applicable to login section). In future, there might be another kind of progress indicator applicable for main section. Change-Id: Iecc4892e0848bfedf63a974b94acf2564241a0c7 Signed-off-by: Vojtech Szocs <vsz...@redhat.com> --- M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/gin/BaseSystemModule.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/place/ApplicationPlaceManager.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/presenter/AbstractLoginPopupPresenterWidget.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/BaseApplicationInit.java A frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/LockInteractionManager.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/model/DeferredModelCommandInvoker.java M frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/login/presenter/LoginPopupPresenterWidget.java M frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/system/ApplicationInit.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/login/presenter/LoginPopupPresenterWidget.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/system/ApplicationInit.java 10 files changed, 139 insertions(+), 43 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/20/7720/1 diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/gin/BaseSystemModule.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/gin/BaseSystemModule.java index c387841..d024737 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/gin/BaseSystemModule.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/gin/BaseSystemModule.java @@ -10,6 +10,7 @@ import org.ovirt.engine.ui.common.system.AsyncCallFailureHandler; import org.ovirt.engine.ui.common.system.ClientStorage; import org.ovirt.engine.ui.common.system.ErrorPopupManager; +import org.ovirt.engine.ui.common.system.LockInteractionManager; import org.ovirt.engine.ui.common.uicommon.ClientAgentType; import com.google.gwt.event.shared.EventBus; @@ -36,6 +37,7 @@ bind(ClientAgentType.class).in(Singleton.class); bind(ClientStorage.class).in(Singleton.class); bind(ApplicationFocusManager.class).asEagerSingleton(); + bind(LockInteractionManager.class).asEagerSingleton(); } protected void bindResourceConfiguration( diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/place/ApplicationPlaceManager.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/place/ApplicationPlaceManager.java index 4577c33..a264c45 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/place/ApplicationPlaceManager.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/place/ApplicationPlaceManager.java @@ -1,5 +1,6 @@ package org.ovirt.engine.ui.common.place; +import java.util.List; import java.util.logging.Logger; import org.ovirt.engine.ui.common.auth.CurrentUser; @@ -31,6 +32,20 @@ eventBus.addHandler(UserLoginChangeEvent.getType(), this); } + // TODO remove this method after upgrading to GWTP 0.7 + // getCurrentPlaceRequest() implementation in GWTP 0.6 can cause + // ArrayIndexOutOfBoundsException to escape from try/catch block + // in production mode (NOT in development mode) + @Override + public PlaceRequest getCurrentPlaceRequest() { + List<PlaceRequest> placeHierarchy = getCurrentPlaceHierarchy(); + if (placeHierarchy.size() > 0) { + return placeHierarchy.get(placeHierarchy.size() - 1); + } else { + return new PlaceRequest(); + } + } + @Override public void revealDefaultPlace() { revealPlace(getDefaultPlace()); @@ -51,7 +66,8 @@ @Override public void revealErrorPlace(String invalidHistoryToken) { - logger.warning("Invalid place request - no presenter proxy mapped to '" + invalidHistoryToken + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + logger.warning("Invalid place request - no presenter proxy mapped to '" //$NON-NLS-1$ + + invalidHistoryToken + "'"); //$NON-NLS-1$ revealDefaultPlace(); } @@ -73,6 +89,9 @@ @Override public void onUserLoginChange(UserLoginChangeEvent event) { + // Disable auto login for subsequent place requests + user.setAutoLogin(false); + if (autoLoginRequest != null) { revealPlace(autoLoginRequest); diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/presenter/AbstractLoginPopupPresenterWidget.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/presenter/AbstractLoginPopupPresenterWidget.java index fd723ab..54b2939 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/presenter/AbstractLoginPopupPresenterWidget.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/presenter/AbstractLoginPopupPresenterWidget.java @@ -7,19 +7,19 @@ import org.ovirt.engine.core.compat.IEventListener; import org.ovirt.engine.core.compat.PropertyChangedEventArgs; import org.ovirt.engine.ui.common.system.ClientStorage; +import org.ovirt.engine.ui.common.system.LockInteractionManager; import org.ovirt.engine.ui.common.uicommon.model.DeferredModelCommandInvoker; import org.ovirt.engine.ui.common.widget.HasEditorDriver; import org.ovirt.engine.ui.common.widget.HasUiCommandClickHandlers; import org.ovirt.engine.ui.common.widget.dialog.PopupNativeKeyPressHandler; +import org.ovirt.engine.ui.uicommonweb.UICommand; import org.ovirt.engine.ui.uicommonweb.models.LoginModel; import com.google.gwt.dom.client.NativeEvent; -import com.google.gwt.dom.client.Style.Cursor; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.shared.EventBus; -import com.google.gwt.user.client.ui.RootPanel; import com.gwtplatform.mvp.client.PopupView; import com.gwtplatform.mvp.client.PresenterWidget; @@ -50,10 +50,13 @@ private static final Logger logger = Logger.getLogger(AbstractLoginPopupPresenterWidget.class.getName()); private final ClientStorage clientStorage; + private final LockInteractionManager lockInteractionManager; - public AbstractLoginPopupPresenterWidget(EventBus eventBus, V view, T loginModel, ClientStorage clientStorage) { + public AbstractLoginPopupPresenterWidget(EventBus eventBus, V view, T loginModel, + ClientStorage clientStorage, LockInteractionManager lockInteractionManager) { super(eventBus, view); this.clientStorage = clientStorage; + this.lockInteractionManager = lockInteractionManager; getView().edit(loginModel); } @@ -62,6 +65,16 @@ super.onBind(); final T loginModel = getView().flush(); + + final DeferredModelCommandInvoker commandInvoker = new DeferredModelCommandInvoker(loginModel) { + @Override + protected void executeCommand(UICommand command) { + if (command == loginModel.getLoginCommand()) { + lockInteractionManager.showLoadingIndicator(); + } + super.executeCommand(command); + } + }; loginModel.getLoggedInEvent().addListener(new IEventListener() { @Override @@ -82,12 +95,10 @@ registerHandler(getView().getLoginButton().addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { - getView().flush(); - getView().getLoginButton().getCommand().Execute(); + commandInvoker.invokeDefaultCommand(); } })); - final DeferredModelCommandInvoker commandInvoker = new DeferredModelCommandInvoker(loginModel); getView().setPopupKeyPressHandler(new PopupNativeKeyPressHandler() { @Override public void onKeyPress(NativeEvent event) { @@ -119,24 +130,7 @@ } } }); - - loginModel.getPropertyChangedEvent().addListener(new IEventListener() { - @Override - public void eventRaised(Event ev, Object sender, EventArgs args) { - PropertyChangedEventArgs pcArgs = (PropertyChangedEventArgs) args; - - if ("Progress".equals(pcArgs.PropertyName)) { //$NON-NLS-1$ - if (loginModel.getProgress() != null) { - RootPanel.getBodyElement().getStyle().setCursor(Cursor.WAIT); - } else { - RootPanel.getBodyElement().getStyle().clearCursor(); - } - } - } - }); } - - /** * Returns the key used to store and retrieve selected domain from {@link ClientStorage}. diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/BaseApplicationInit.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/BaseApplicationInit.java index c425836..dc6d4aa 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/BaseApplicationInit.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/BaseApplicationInit.java @@ -38,17 +38,21 @@ // Using Provider because any UiCommon model will fail before TypeResolver is initialized private final Provider<T> loginModelProvider; + private final LockInteractionManager lockInteractionManager; + public BaseApplicationInit(ITypeResolver typeResolver, FrontendEventsHandlerImpl frontendEventsHandler, FrontendFailureEventListener frontendFailureEventListener, - CurrentUser user, Provider<T> loginModelProvider, - EventBus eventBus) { + CurrentUser user, EventBus eventBus, + Provider<T> loginModelProvider, + LockInteractionManager lockInteractionManager) { this.typeResolver = typeResolver; this.frontendEventsHandler = frontendEventsHandler; this.frontendFailureEventListener = frontendFailureEventListener; this.user = user; - this.loginModelProvider = loginModelProvider; this.eventBus = eventBus; + this.loginModelProvider = loginModelProvider; + this.lockInteractionManager = lockInteractionManager; // Handle UI logout requests user.setLogoutHandler(this); @@ -99,6 +103,8 @@ // UI login actions user.onUserLogin(loggedUser.getUserName()); + + // Post-login actions clearPassword(loginModel); } @@ -155,6 +161,7 @@ Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { + lockInteractionManager.showLoadingIndicator(); getLoginModel().AutoLogin(vdcUser); } }); diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/LockInteractionManager.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/LockInteractionManager.java new file mode 100644 index 0000000..88b8fea --- /dev/null +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/LockInteractionManager.java @@ -0,0 +1,68 @@ +package org.ovirt.engine.ui.common.system; + +import org.ovirt.engine.ui.common.auth.CurrentUser; + +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.dom.client.Style.Cursor; +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.inject.Inject; +import com.gwtplatform.mvp.client.proxy.LockInteractionEvent; +import com.gwtplatform.mvp.client.proxy.LockInteractionHandler; +import com.gwtplatform.mvp.client.proxy.PlaceManager; + +/** + * Handles GWTP {@link LockInteractionEvent} by displaying progress indicator when the application is transitioning from + * one place to another. + * <p> + * The progress indicator provides visual feedback that the application is currently busy and any user interaction + * should be avoided. Note that the progress indicator might have different representations in different sections of the + * application. + */ +public class LockInteractionManager implements LockInteractionHandler { + + private final PlaceManager placeManager; + private final CurrentUser user; + + private boolean loadingIndicatorActive = false; + + @Inject + public LockInteractionManager(EventBus eventBus, PlaceManager placeManager, CurrentUser user) { + this.placeManager = placeManager; + this.user = user; + eventBus.addHandler(LockInteractionEvent.getType(), this); + } + + @Override + public void onLockInteraction(LockInteractionEvent event) { + // Allow progress indicator to be hidden regardless of the current (non-empty) place + boolean emptyPlace = placeManager.getCurrentPlaceRequest().getNameToken() == null; + if (!emptyPlace && !user.isAutoLogin() && !event.shouldLock()) { + // Use deferred command because some other initialization might happen + // right after place transition; therefore we want to hide the loading + // indicator only after the browser event loop returns + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + @Override + public void execute() { + hideLoadingIndicator(); + } + }); + } + } + + public void showLoadingIndicator() { + if (!loadingIndicatorActive) { + loadingIndicatorActive = true; + RootPanel.getBodyElement().getStyle().setCursor(Cursor.WAIT); + } + } + + public void hideLoadingIndicator() { + if (loadingIndicatorActive) { + loadingIndicatorActive = false; + RootPanel.getBodyElement().getStyle().clearCursor(); + } + } + +} diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/model/DeferredModelCommandInvoker.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/model/DeferredModelCommandInvoker.java index 2f76d15..ff96117 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/model/DeferredModelCommandInvoker.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/model/DeferredModelCommandInvoker.java @@ -40,7 +40,7 @@ @Override public void execute() { try { - command.Execute(); + executeCommand(command); } catch (Exception ex) { logger.log(Level.SEVERE, "UICommand execution failed", ex); //$NON-NLS-1$ commandFailed(command); @@ -52,6 +52,10 @@ } } + protected void executeCommand(UICommand command) { + command.Execute(); + } + protected void commandFailed(UICommand command) { // No-op, override as necessary } diff --git a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/login/presenter/LoginPopupPresenterWidget.java b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/login/presenter/LoginPopupPresenterWidget.java index f292792..5fb030f 100644 --- a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/login/presenter/LoginPopupPresenterWidget.java +++ b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/login/presenter/LoginPopupPresenterWidget.java @@ -2,6 +2,7 @@ import org.ovirt.engine.ui.common.presenter.AbstractLoginPopupPresenterWidget; import org.ovirt.engine.ui.common.system.ClientStorage; +import org.ovirt.engine.ui.common.system.LockInteractionManager; import org.ovirt.engine.ui.uicommonweb.models.userportal.UserPortalLoginModel; import com.google.gwt.event.shared.EventBus; @@ -15,11 +16,10 @@ private final ConnectAutomaticallyProvider connectAutomaticallyProvider; @Inject - public LoginPopupPresenterWidget(EventBus eventBus, ViewDef view, - UserPortalLoginModel loginModel, - ConnectAutomaticallyProvider connectAutomaticallyProvider, - ClientStorage clientStorage) { - super(eventBus, view, loginModel, clientStorage); + public LoginPopupPresenterWidget(EventBus eventBus, ViewDef view, UserPortalLoginModel loginModel, + ClientStorage clientStorage, LockInteractionManager lockInteractionManager, + ConnectAutomaticallyProvider connectAutomaticallyProvider) { + super(eventBus, view, loginModel, clientStorage, lockInteractionManager); this.connectAutomaticallyProvider = connectAutomaticallyProvider; } diff --git a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/system/ApplicationInit.java b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/system/ApplicationInit.java index 19290e2..98bda5a 100644 --- a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/system/ApplicationInit.java +++ b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/system/ApplicationInit.java @@ -5,6 +5,7 @@ import org.ovirt.engine.core.compat.IEventListener; import org.ovirt.engine.ui.common.auth.CurrentUser; import org.ovirt.engine.ui.common.system.BaseApplicationInit; +import org.ovirt.engine.ui.common.system.LockInteractionManager; import org.ovirt.engine.ui.common.uicommon.FrontendEventsHandlerImpl; import org.ovirt.engine.ui.common.uicommon.FrontendFailureEventListener; import org.ovirt.engine.ui.frontend.AsyncQuery; @@ -30,12 +31,12 @@ public ApplicationInit(ITypeResolver typeResolver, FrontendEventsHandlerImpl frontendEventsHandler, FrontendFailureEventListener frontendFailureEventListener, - CurrentUser user, + CurrentUser user, EventBus eventBus, Provider<UserPortalLoginModel> loginModelProvider, - EventBus eventBus, + LockInteractionManager lockInteractionManager, CurrentUserRole userRole, ApplicationConstants constants) { - super(typeResolver, frontendEventsHandler, frontendFailureEventListener, user, loginModelProvider, eventBus); + super(typeResolver, frontendEventsHandler, frontendFailureEventListener, user, eventBus, loginModelProvider, lockInteractionManager); this.userRole = userRole; Window.setTitle(constants.applicationTitle()); } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/login/presenter/LoginPopupPresenterWidget.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/login/presenter/LoginPopupPresenterWidget.java index f43b051..3a9b8a6 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/login/presenter/LoginPopupPresenterWidget.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/login/presenter/LoginPopupPresenterWidget.java @@ -2,6 +2,7 @@ import org.ovirt.engine.ui.common.presenter.AbstractLoginPopupPresenterWidget; import org.ovirt.engine.ui.common.system.ClientStorage; +import org.ovirt.engine.ui.common.system.LockInteractionManager; import org.ovirt.engine.ui.uicommonweb.models.LoginModel; import org.ovirt.engine.ui.webadmin.auth.SilentLoginData; @@ -16,9 +17,9 @@ private SilentLoginData silentLoginData; @Inject - public LoginPopupPresenterWidget(EventBus eventBus, ViewDef view, - LoginModel loginModel, ClientStorage clientStorage) { - super(eventBus, view, loginModel, clientStorage); + public LoginPopupPresenterWidget(EventBus eventBus, ViewDef view, LoginModel loginModel, + ClientStorage clientStorage, LockInteractionManager lockInteractionManager) { + super(eventBus, view, loginModel, clientStorage, lockInteractionManager); } public void setSilentLoginData(SilentLoginData silentLoginData) { diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/system/ApplicationInit.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/system/ApplicationInit.java index 8dda9b5..d02f8c4 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/system/ApplicationInit.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/system/ApplicationInit.java @@ -6,6 +6,7 @@ import org.ovirt.engine.core.compat.IEventListener; import org.ovirt.engine.ui.common.auth.CurrentUser; import org.ovirt.engine.ui.common.system.BaseApplicationInit; +import org.ovirt.engine.ui.common.system.LockInteractionManager; import org.ovirt.engine.ui.common.uicommon.FrontendEventsHandlerImpl; import org.ovirt.engine.ui.common.uicommon.FrontendFailureEventListener; import org.ovirt.engine.ui.common.uicommon.model.CommonModelManager; @@ -28,13 +29,12 @@ public ApplicationInit(ITypeResolver typeResolver, FrontendEventsHandlerImpl frontendEventsHandler, FrontendFailureEventListener frontendFailureEventListener, - CurrentUser user, + CurrentUser user, EventBus eventBus, Provider<LoginModel> loginModelProvider, - EventBus eventBus, + LockInteractionManager lockInteractionManager, ApplicationConstants constants) { - super(typeResolver, frontendEventsHandler, frontendFailureEventListener, user, loginModelProvider, eventBus); + super(typeResolver, frontendEventsHandler, frontendFailureEventListener, user, eventBus, loginModelProvider, lockInteractionManager); Window.setTitle(constants.applicationTitle()); - handleUiMode(); } -- To view, visit http://gerrit.ovirt.org/7720 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iecc4892e0848bfedf63a974b94acf2564241a0c7 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Vojtech Szocs <vsz...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches