Shubhendu Tripathi has uploaded a new change for review.

Change subject: webadmin: UI for gluster volume snapshot creation
......................................................................

webadmin: UI for gluster volume snapshot creation

Introduced UI dialog for gluster volume snapshot creation and scheduling 
snapshots.

Change-Id: I823580ecb127e48e075c437668bfb19ff8ec4467
Signed-off-by: Shubhendu Tripathi <[email protected]>
---
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GetGlusterVolumeSnapshotScheduleByVolumeIdQuery.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterQueriesCommandBase.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java
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/GlusterVolumeSnapshotListModel.java
A 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotModel.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.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/ApplicationConstants.java
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/VolumeModule.java
A 
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/GlusterVolumeSnapshotCreatePopupPresenterWidget.java
A 
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.java
A 
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.ui.xml
M 
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java
17 files changed, 1,277 insertions(+), 4 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/04/40004/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GetGlusterVolumeSnapshotScheduleByVolumeIdQuery.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GetGlusterVolumeSnapshotScheduleByVolumeIdQuery.java
new file mode 100644
index 0000000..ad04a35
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GetGlusterVolumeSnapshotScheduleByVolumeIdQuery.java
@@ -0,0 +1,14 @@
+package org.ovirt.engine.core.bll.gluster;
+
+import org.ovirt.engine.core.common.queries.IdQueryParameters;
+
+public class GetGlusterVolumeSnapshotScheduleByVolumeIdQuery<P extends 
IdQueryParameters> extends GlusterQueriesCommandBase<P> {
+    public GetGlusterVolumeSnapshotScheduleByVolumeIdQuery(P parameters) {
+        super(parameters);
+    }
+
+    @Override
+    public void executeQueryCommand() {
+        
getQueryReturnValue().setReturnValue(getGlusterVolumeSnapshotScheduleDao().getByVolumeId(getParameters().getId()));
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterQueriesCommandBase.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterQueriesCommandBase.java
index bcb600c..e08cef6 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterQueriesCommandBase.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterQueriesCommandBase.java
@@ -21,6 +21,7 @@
 import org.ovirt.engine.core.dao.gluster.GlusterVolumeDao;
 import org.ovirt.engine.core.dao.gluster.GlusterVolumeSnapshotConfigDao;
 import org.ovirt.engine.core.dao.gluster.GlusterVolumeSnapshotDao;
+import org.ovirt.engine.core.dao.gluster.GlusterVolumeSnapshotScheduleDao;
 
 public abstract class GlusterQueriesCommandBase<P extends 
VdcQueryParametersBase> extends QueriesCommandBase<P> {
     protected GlusterQueriesCommandBase(P parameters) {
@@ -72,6 +73,10 @@
         return DbFacade.getInstance().getGlusterVolumeSnapshotConfigDao();
     }
 
+    protected GlusterVolumeSnapshotScheduleDao 
getGlusterVolumeSnapshotScheduleDao() {
+        return DbFacade.getInstance().getGlusterVolumeSnapshotScheduleDao();
+    }
+
     protected Guid getUpServerId(Guid clusterId) {
         VDS vds = getClusterUtils().getUpServer(clusterId);
         if (vds == null) {
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
index e3593f2..f02f0e4 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
@@ -341,6 +341,7 @@
     GetGlusterVolumeSnapshotsByVolumeId,
     GetGlusterVolumeGeoRepConfigList,
     GetGlusterVolumeSnapshotConfig,
+    GetGlusterVolumeSnapshotScheduleByVolumeId,
 
     GetDefaultConfigurationVersion(VdcQueryAuthType.User),
     OsRepository(VdcQueryAuthType.User),
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java
index bd8a624..6c18633 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java
@@ -1592,6 +1592,18 @@
         
Frontend.getInstance().runQuery(VdcQueryType.GetGlusterVolumeGeoRepSessions, 
new IdQueryParameters(masterVolumeId), aQuery);
     }
 
+    public static void getVolumeSnapshotSchedule(AsyncQuery aQuery, Guid 
volumeId) {
+        aQuery.converterCallback = new IAsyncConverter() {
+            @Override
+            public Object Convert(Object source, AsyncQuery asyncQuery) {
+                return source;
+            }
+        };
+        
Frontend.getInstance().runQuery(VdcQueryType.GetGlusterVolumeSnapshotScheduleByVolumeId,
+                new IdQueryParameters(volumeId),
+                aQuery);
+     }
+
     public static void getGlusterHook(AsyncQuery aQuery, Guid hookId, boolean 
includeServerHooks) {
         aQuery.converterCallback = new IAsyncConverter() {
             @Override
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 a882ad4..d8006b8 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
@@ -328,6 +328,10 @@
 
     
configure_volume_snapshot_confirmation("configure_volume_snapshot_confirmation",
 HelpTagType.WEBADMIN, "Configure volume snapshot: confirmation dialog that 
appears when changing the volume snapshot configuration parameters."), 
//$NON-NLS-1$ //$NON-NLS-2$
 
+    new_volume_snapshot("new_volume_snapshot", HelpTagType.WEBADMIN, 
"[gluster] Volumes main tab -> Snapshot -> New"), //$NON-NLS-1$ //$NON-NLS-2$
+
+    edit_volume_snapshot_schedule("edit_volume_snapshot_schedule", 
HelpTagType.WEBADMIN, "[gluster] Volumes main tab -> Snapshot -> Edit 
Schedule"), //$NON-NLS-1$ //$NON-NLS-2$
+
     parameters("parameters", HelpTagType.UNKNOWN), //$NON-NLS-1$
 
     permissions("permissions", HelpTagType.UNKNOWN), //$NON-NLS-1$
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java
index ba42807..08ecd06 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java
@@ -1,16 +1,25 @@
 package org.ovirt.engine.ui.uicommonweb.models.gluster;
 
+import java.sql.Time;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 
 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.action.gluster.CreateGlusterVolumeSnapshotParameters;
 import org.ovirt.engine.core.common.action.gluster.GlusterVolumeParameters;
 import 
org.ovirt.engine.core.common.action.gluster.GlusterVolumeSnapshotActionParameters;
+import 
org.ovirt.engine.core.common.action.gluster.ScheduleGlusterVolumeSnapshotParameters;
 import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterSnapshotStatus;
+import org.ovirt.engine.core.common.businessentities.gluster.GlusterStatus;
 import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity;
 import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity;
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotSchedule;
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotScheduleRecurrence;
+import org.ovirt.engine.core.compat.DayOfWeek;
 import org.ovirt.engine.ui.frontend.AsyncQuery;
 import org.ovirt.engine.ui.frontend.Frontend;
 import org.ovirt.engine.ui.frontend.INewAsyncCallback;
@@ -20,13 +29,36 @@
 import org.ovirt.engine.ui.uicommonweb.help.HelpTag;
 import org.ovirt.engine.ui.uicommonweb.models.ConfirmationModel;
 import org.ovirt.engine.ui.uicommonweb.models.SearchableListModel;
+import 
org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotModel.EndDateOptions;
 import org.ovirt.engine.ui.uicompat.ConstantsManager;
 import org.ovirt.engine.ui.uicompat.FrontendActionAsyncResult;
 import org.ovirt.engine.ui.uicompat.FrontendMultipleActionAsyncResult;
 import org.ovirt.engine.ui.uicompat.IFrontendActionAsyncCallback;
 import org.ovirt.engine.ui.uicompat.IFrontendMultipleActionAsyncCallback;
+import org.ovirt.engine.ui.uicompat.UIConstants;
 
 public class GlusterVolumeSnapshotListModel extends SearchableListModel {
+
+    private UICommand createSnapshotCommand;
+
+    public UICommand getCreateSnapshotCommand() {
+        return createSnapshotCommand;
+    }
+
+    public void setCreateSnapshotCommand(UICommand value) {
+        this.createSnapshotCommand = value;
+    }
+
+    private UICommand editSnapshotScheduleCommand;
+
+    public UICommand getEditSnapshotScheduleCommand() {
+        return this.editSnapshotScheduleCommand;
+    }
+
+    public void setEditSnapshotScheduleCommand(UICommand command) {
+        this.editSnapshotScheduleCommand = command;
+    }
+
     @Override
     public String getListName() {
         return "GlusterVolumeSnapshotListModel"; //$NON-NLS-1$
@@ -42,6 +74,8 @@
         setDeleteAllSnapshotsCommand(new UICommand("deleteAll", this)); 
//$NON-NLS-1$
         setActivateSnapshotCommand(new UICommand("activate", this)); 
//$NON-NLS-1$
         setDeactivateSnapshotCommand(new UICommand("deactivate", this)); 
//$NON-NLS-1$
+        setCreateSnapshotCommand(new UICommand("createSnapshot", 
this));//$NON-NLS-1$
+        setEditSnapshotScheduleCommand(new UICommand("editSnapshotSchedule", 
this));//$NON-NLS-1$
     }
 
     @Override
@@ -115,6 +149,8 @@
         boolean allowDeleteAll = true;
         boolean allowActivate = false;
         boolean allowDeactivate = false;
+        boolean allowCreateSnapshot = true;
+        boolean allowEditSnapshotSchedule = false;
 
         if (getSelectedItems() == null || getSelectedItems().size() == 0) {
             allowDelete = false;
@@ -128,12 +164,23 @@
             }
         }
 
+        if (getEntity() == null || getEntity().getStatus() == 
GlusterStatus.DOWN) {
+            allowCreateSnapshot = false;
+        }
+
+        if (getEntity() != null && getEntity().getStatus() == GlusterStatus.UP 
&& getEntity().getSnapshotScheduled()) {
+            allowEditSnapshotSchedule = true;
+        }
+
         getRestoreSnapshotCommand().setIsExecutionAllowed(allowRestore);
         getDeleteSnapshotCommand().setIsExecutionAllowed(allowDelete);
         getDeleteAllSnapshotsCommand().setIsExecutionAllowed(allowDeleteAll);
         getActivateSnapshotCommand().setIsExecutionAllowed(allowActivate);
         getDeactivateSnapshotCommand().setIsExecutionAllowed(allowDeactivate);
+        getCreateSnapshotCommand().setIsExecutionAllowed(allowCreateSnapshot);
+        
getEditSnapshotScheduleCommand().setIsExecutionAllowed(allowEditSnapshotSchedule);
     }
+
 
     @Override
     protected void syncSearch() {
@@ -179,6 +226,16 @@
             onDeactivateSnapshot();
         } else if (command.getName().equals("cancelConfirmation")) { 
//$NON-NLS-1$
             setConfirmWindow(null);
+        } else if (command.equals(getCreateSnapshotCommand())) {
+            createSnapshot();
+        } else if (command.getName().equalsIgnoreCase("onCreateSnapshot")) 
{//$NON-NLS-1$
+            onCreateSnapshot();
+        } else if (command.getName().equalsIgnoreCase("cancel")) {//$NON-NLS-1$
+            setWindow(null);
+        } else if (command.equals(getEditSnapshotScheduleCommand())) {
+            editSnapshotSchedule();
+        } else if 
(command.getName().equalsIgnoreCase("onEditSnapshotSchedule")) {//$NON-NLS-1$
+            onEditSnapshotSchedule();
         }
     }
 
@@ -391,4 +448,274 @@
     public void setEntity(GlusterVolumeEntity value) {
         super.setEntity(value);
     }
+
+    private void createSnapshot() {
+        if (getWindow() != null) {
+            return;
+        }
+
+        GlusterVolumeEntity volumeEntity = getEntity();
+        GlusterVolumeSnapshotModel snapshotModel =
+                new GlusterVolumeSnapshotModel(true, 
!volumeEntity.getSnapshotScheduled());
+
+        snapshotModel.setHelpTag(HelpTag.new_volume_snapshot);
+        snapshotModel.setHashName("new_volume_snapshot"); //$NON-NLS-1$
+        
snapshotModel.setTitle(ConstantsManager.getInstance().getConstants().createScheduleVolumeSnapshotTitle());
+        setWindow(snapshotModel);
+
+        
snapshotModel.getClusterName().setEntity(volumeEntity.getVdsGroupName());
+        snapshotModel.getVolumeName().setEntity(volumeEntity.getName());
+
+        UICommand okCommand = 
UICommand.createDefaultOkUiCommand("onCreateSnapshot", this); //$NON-NLS-1$
+        snapshotModel.getCommands().add(okCommand);
+
+        UICommand cancelCommand = UICommand.createCancelUiCommand("cancel", 
this); //$NON-NLS-1$
+        snapshotModel.getCommands().add(cancelCommand);
+    }
+
+    private void onCreateSnapshot() {
+        final GlusterVolumeSnapshotModel snapshotModel = 
(GlusterVolumeSnapshotModel) getWindow();
+
+        if (!snapshotModel.validate()) {
+            return;
+        }
+
+        if (!snapshotModel.isScheduleTabVisible()
+                || snapshotModel.getRecurrence().getSelectedItem() == 
GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN) {
+            createNewSnapshot(snapshotModel);
+        } else {
+            scheduleSnapshot(snapshotModel, false);
+        }
+    }
+
+    private Time getExecutionTime(GlusterVolumeSnapshotModel model) {
+        int hours = model.getExecutionTime().getEntity().getHours();
+        int minutes = model.getExecutionTime().getEntity().getMinutes();
+
+        return new Time(hours, minutes, 0);
+    }
+
+    private void scheduleSnapshot(final GlusterVolumeSnapshotModel 
snapshotModel, boolean reschedule) {
+        GlusterVolumeEntity volumeEntity = getEntity();
+
+        final GlusterVolumeSnapshotSchedule schedule = new 
GlusterVolumeSnapshotSchedule();
+        
schedule.setSnapshotNamePrefix(snapshotModel.getSnapshotName().getEntity());
+        
schedule.setSnapshotDescription(snapshotModel.getDescription().getEntity());
+        schedule.setClusterId(volumeEntity.getClusterId());
+        schedule.setVolumeId(volumeEntity.getId());
+        switch (snapshotModel.getRecurrence().getSelectedItem()) {
+        case INTERVAL:
+            
schedule.setRecurrence(GlusterVolumeSnapshotScheduleRecurrence.INTERVAL);
+            
schedule.setInterval(Integer.valueOf(snapshotModel.getInterval().getSelectedItem()));
+            break;
+        case HOURLY:
+            
schedule.setRecurrence(GlusterVolumeSnapshotScheduleRecurrence.HOURLY);
+            break;
+        case DAILY:
+            
schedule.setRecurrence(GlusterVolumeSnapshotScheduleRecurrence.DAILY);
+            schedule.setExecutionTime(getExecutionTime(snapshotModel));
+            break;
+        case WEEKLY:
+            
schedule.setRecurrence(GlusterVolumeSnapshotScheduleRecurrence.WEEKLY);
+            schedule.setExecutionTime(getExecutionTime(snapshotModel));
+            StringBuilder sb = new StringBuilder();
+            for (DayOfWeek day : 
snapshotModel.getDaysOfTheWeek().getSelectedItem()) {
+                sb.append(day.name().substring(0, 3));
+                sb.append(',');//$NON-NLS-1$
+            }
+            schedule.setDays(sb.toString());
+            break;
+        case MONTHLY:
+            
schedule.setRecurrence(GlusterVolumeSnapshotScheduleRecurrence.MONTHLY);
+            schedule.setExecutionTime(getExecutionTime(snapshotModel));
+            schedule.setDays(snapshotModel.getDaysOfMonth().getSelectedItem());
+            break;
+        }
+
+        Date startAt = snapshotModel.getStartAt().getEntity();
+        schedule.setStartDate(startAt);
+        schedule.setTimeZone(snapshotModel.getTimeZones().getSelectedItem());
+
+        if (snapshotModel.getEndByOptions().getSelectedItem() == 
EndDateOptions.NoEndDate) {
+            schedule.setEndByDate(null);
+        } else {
+            schedule.setEndByDate(snapshotModel.getEndDate().getEntity());
+        }
+
+        ScheduleGlusterVolumeSnapshotParameters params =
+                new ScheduleGlusterVolumeSnapshotParameters(schedule, true);
+        snapshotModel.startProgress(null);
+
+        VdcActionType actionType = null;
+        if (reschedule) {
+            actionType = VdcActionType.RescheduleGlusterVolumeSnapshot;
+        } else {
+            actionType = VdcActionType.ScheduleGlusterVolumeSnapshot;
+        }
+
+        Frontend.getInstance().runAction(actionType,
+                params,
+                new IFrontendActionAsyncCallback() {
+                    @Override
+                    public void executed(FrontendActionAsyncResult result) {
+                        GlusterVolumeSnapshotListModel localModel =
+                                (GlusterVolumeSnapshotListModel) 
result.getState();
+                        localModel.stopProgress();
+                        localModel.postSnapshotAction(result.getReturnValue());
+                    }
+                },
+                this);
+    }
+
+    private void createNewSnapshot(final GlusterVolumeSnapshotModel 
snapshotModel) {
+        GlusterVolumeEntity volumeEntity = getEntity();
+
+        final GlusterVolumeSnapshotEntity snapshot = new 
GlusterVolumeSnapshotEntity();
+        snapshot.setClusterId(volumeEntity.getClusterId());
+        snapshot.setSnapshotName(snapshotModel.getSnapshotName().getEntity());
+        snapshot.setVolumeId(volumeEntity.getId());
+        snapshot.setDescription(snapshotModel.getDescription().getEntity());
+
+        CreateGlusterVolumeSnapshotParameters parameter =
+                new CreateGlusterVolumeSnapshotParameters(snapshot, true);
+
+        snapshotModel.startProgress(null);
+        
Frontend.getInstance().runAction(VdcActionType.CreateGlusterVolumeSnapshot,
+                parameter,
+                new IFrontendActionAsyncCallback() {
+                    @Override
+                    public void executed(FrontendActionAsyncResult result) {
+                        GlusterVolumeSnapshotListModel localModel =
+                                (GlusterVolumeSnapshotListModel) 
result.getState();
+                        localModel.stopProgress();
+                        localModel.postSnapshotAction(result.getReturnValue());
+                    }
+                },
+                this);
+    }
+
+    public void postSnapshotAction(VdcReturnValueBase returnValue) {
+        if (returnValue != null && returnValue.getSucceeded()) {
+            setWindow(null);
+        }
+    }
+
+    public void editSnapshotSchedule() {
+        if (getWindow() != null) {
+            return;
+        }
+
+        final UIConstants constants = 
ConstantsManager.getInstance().getConstants();
+
+        final GlusterVolumeSnapshotModel snapshotModel =
+                new GlusterVolumeSnapshotModel(true, true);
+        snapshotModel.setHelpTag(HelpTag.edit_volume_snapshot_schedule);
+        snapshotModel.setHashName("edit_volume_snapshot_schedule"); 
//$NON-NLS-1$
+        snapshotModel.setTitle(constants.editVolumeSnapshotScheduleTitle());
+        setWindow(snapshotModel);
+
+        snapshotModel.startProgress(null);
+
+        AsyncDataProvider.getVolumeSnapshotSchedule(new AsyncQuery(this, new 
INewAsyncCallback() {
+
+            @Override
+            public void onSuccess(Object model, Object returnValue) {
+                if (returnValue == null) {
+                    snapshotModel.setMessage(ConstantsManager.getInstance()
+                            .getConstants()
+                            .unableToFetchVolumeSnapshotSchedule());
+                    return;
+                }
+                GlusterVolumeSnapshotSchedule schedule = 
(GlusterVolumeSnapshotSchedule) returnValue;
+                
snapshotModel.getSnapshotName().setEntity(schedule.getSnapshotNamePrefix());
+                
snapshotModel.getDescription().setEntity(schedule.getSnapshotDescription());
+                
snapshotModel.getRecurrence().setSelectedItem(schedule.getRecurrence());
+                if (schedule.getEndByDate() == null) {
+                    
snapshotModel.getEndByOptions().setSelectedItem(EndDateOptions.NoEndDate);
+                } else {
+                    
snapshotModel.getEndByOptions().setSelectedItem(EndDateOptions.HasEndDate);
+                    
snapshotModel.getEndDate().setEntity(schedule.getEndByDate());
+                }
+
+                if (schedule.getRecurrence() == 
GlusterVolumeSnapshotScheduleRecurrence.DAILY
+                        || schedule.getRecurrence() == 
GlusterVolumeSnapshotScheduleRecurrence.WEEKLY
+                        || schedule.getRecurrence() == 
GlusterVolumeSnapshotScheduleRecurrence.MONTHLY) {
+                    
snapshotModel.getTimeZones().setSelectedItem(schedule.getTimeZone());
+                }
+                switch (schedule.getRecurrence()) {
+                case INTERVAL:
+                    
snapshotModel.getInterval().setSelectedItem(String.valueOf(schedule.getInterval()));
+                    break;
+                case HOURLY:
+                    break;
+                case DAILY:
+                    
snapshotModel.getExecutionTime().setEntity(getExecutionTimeValue(schedule));
+                    break;
+                case WEEKLY:
+                    List<DayOfWeek> daysList = new ArrayList<DayOfWeek>();
+                    for (String day : schedule.getDays().split(",")) 
{//$NON-NLS-1$
+                        daysList.add(getDayOfWeek(day));
+                    }
+                    snapshotModel.getDaysOfTheWeek().setSelectedItem(daysList);
+                    
snapshotModel.getExecutionTime().setEntity(getExecutionTimeValue(schedule));
+                    break;
+                case MONTHLY:
+                    
snapshotModel.getDaysOfMonth().setSelectedItem(schedule.getDays());
+                    
snapshotModel.getExecutionTime().setEntity(getExecutionTimeValue(schedule));
+                    break;
+                }
+
+                snapshotModel.getStartAt().setEntity(schedule.getStartDate());
+                snapshotModel.stopProgress();
+            }
+
+            private DayOfWeek getDayOfWeek(String day) {
+                if ("Sun".equals(day)) {//$NON-NLS-1$
+                    return DayOfWeek.Sunday;
+                } else if ("Mon".equals(day)) {//$NON-NLS-1$
+                    return DayOfWeek.Monday;
+                } else if ("Tue".equals(day)) {//$NON-NLS-1$
+                    return DayOfWeek.Tuesday;
+                } else if ("Wed".equals(day)) {//$NON-NLS-1$
+                    return DayOfWeek.Wednesday;
+                } else if ("Thu".equals(day)) {//$NON-NLS-1$
+                    return DayOfWeek.Thursday;
+                } else if ("Fri".equals(day)) {//$NON-NLS-1$
+                    return DayOfWeek.Friday;
+                } else if ("Sat".equals(day)) {//$NON-NLS-1$
+                    return DayOfWeek.Saturday;
+                } else {
+                    return null;
+                }
+            }
+
+            private Date getExecutionTimeValue(GlusterVolumeSnapshotSchedule 
schedule) {
+                Date dt = new Date();
+                dt.setHours(schedule.getExecutionTime().getHours());
+                dt.setMinutes(schedule.getExecutionTime().getMinutes());
+
+                return dt;
+            }
+        }),
+                getEntity().getId());
+
+        
snapshotModel.getClusterName().setEntity(getEntity().getVdsGroupName());
+        snapshotModel.getVolumeName().setEntity(getEntity().getName());
+
+        UICommand okCommand = 
UICommand.createDefaultOkUiCommand("onEditSnapshotSchedule", this); 
//$NON-NLS-1$
+        snapshotModel.getCommands().add(okCommand);
+
+        UICommand cancelCommand = UICommand.createCancelUiCommand("cancel", 
this); //$NON-NLS-1$
+        snapshotModel.getCommands().add(cancelCommand);
+    }
+
+    public void onEditSnapshotSchedule() {
+        final GlusterVolumeSnapshotModel snapshotModel = 
(GlusterVolumeSnapshotModel) getWindow();
+
+        if (!snapshotModel.validate()) {
+            return;
+        }
+
+        scheduleSnapshot(snapshotModel, true);
+    }
 }
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotModel.java
new file mode 100644
index 0000000..8f5ebf0
--- /dev/null
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotModel.java
@@ -0,0 +1,268 @@
+package org.ovirt.engine.ui.uicommonweb.models.gluster;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import org.ovirt.engine.core.common.TimeZoneType;
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotScheduleRecurrence;
+import org.ovirt.engine.core.compat.DayOfWeek;
+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.uicommonweb.validation.AsciiNameValidation;
+import org.ovirt.engine.ui.uicommonweb.validation.IValidation;
+import org.ovirt.engine.ui.uicommonweb.validation.LengthValidation;
+import org.ovirt.engine.ui.uicommonweb.validation.NotEmptyValidation;
+import org.ovirt.engine.ui.uicompat.ConstantsManager;
+
+public class GlusterVolumeSnapshotModel extends Model {
+    private EntityModel<String> dataCenter;
+    private EntityModel<String> clusterName;
+    private EntityModel<String> volumeName;
+    private EntityModel<String> snapshotName;
+    private EntityModel<String> description;
+    private ListModel<GlusterVolumeSnapshotScheduleRecurrence> recurrence;
+    private ListModel<String> interval;
+    private ListModel<EndDateOptions> endByOptions;
+    private EntityModel<Date> endDate;
+    private boolean generalTabVisible;
+    private boolean scheduleTabVisible;
+    private ListModel<String> timeZones;
+    private EntityModel<Date> startAt;
+    private EntityModel<Date> executionTime;
+    private ListModel<List<DayOfWeek>> daysOfWeek;
+    private ListModel<String> daysOfMonth;
+
+    public GlusterVolumeSnapshotModel(boolean generalTabVisible, boolean 
scheduleTabVisible) {
+        init();
+        setGeneralTabVisible(generalTabVisible);
+        setScheduleTabVisible(scheduleTabVisible);
+    }
+
+    private void init() {
+        setDataCenter(new EntityModel<String>());
+        setClusterName(new EntityModel<String>());
+        setVolumeName(new EntityModel<String>());
+        setSnapshotName(new EntityModel<String>());
+        setDescription(new EntityModel<String>());
+        setRecurrence(new 
ListModel<GlusterVolumeSnapshotScheduleRecurrence>());
+        setInterval(new ListModel<String>());
+        setEndByOptions(new ListModel<EndDateOptions>());
+        setTimeZones(new ListModel<String>());
+        setDaysOfMonth(new ListModel<String>());
+        setStartAt(new EntityModel<Date>(new Date()));
+        setEndDate(new EntityModel<Date>(new Date()));
+        setExecutionTime(new EntityModel<Date>(new Date()));
+        initIntervals();
+        initTimeZones();
+
+        
recurrence.setItems(Arrays.asList(GlusterVolumeSnapshotScheduleRecurrence.values()),
+                GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN);
+        endByOptions.setItems(Arrays.asList(EndDateOptions.values()));
+
+        List<String> values = new ArrayList<String>();
+        for (DayOfWeek day : DayOfWeek.values()) {
+            values.add(day.toString().substring(0, 3));
+        }
+        daysOfWeek = new ListModel<List<DayOfWeek>>();
+        List<DayOfWeek> daysList = Arrays.asList(DayOfWeek.values());
+        List<List<DayOfWeek>> list = new ArrayList<List<DayOfWeek>>();
+        list.add(daysList);
+        daysOfWeek.setItems(list, new ArrayList<DayOfWeek>());
+    }
+
+    private void initIntervals() {
+        List<String> intervals = new ArrayList<String>();
+        int mins = 0;
+        for (int nThMin = 1; mins < 55; nThMin++) {
+            mins = nThMin * 5;
+            intervals.add(String.valueOf(mins));
+        }
+        getInterval().setItems(intervals);
+    }
+
+    private void initTimeZones() {
+        Set<String> timeZoneTypes = 
TimeZoneType.GENERAL_TIMEZONE.getTimeZoneList().keySet();
+        getTimeZones().setItems(timeZoneTypes);
+    }
+
+    public EntityModel<String> getDataCenter() {
+        return this.dataCenter;
+    }
+
+    public void setDataCenter(EntityModel<String> dataCenter) {
+        this.dataCenter = dataCenter;
+    }
+
+    public EntityModel<String> getClusterName() {
+        return clusterName;
+    }
+
+    public void setClusterName(EntityModel<String> clusterName) {
+        this.clusterName = clusterName;
+    }
+
+    public EntityModel<String> getVolumeName() {
+        return volumeName;
+    }
+
+    public void setVolumeName(EntityModel<String> volumeName) {
+        this.volumeName = volumeName;
+    }
+
+    public EntityModel<String> getSnapshotName() {
+        return snapshotName;
+    }
+
+    public void setSnapshotName(EntityModel<String> snapshotName) {
+        this.snapshotName = snapshotName;
+    }
+
+    public EntityModel<String> getDescription() {
+        return description;
+    }
+
+    public void setDescription(EntityModel<String> description) {
+        this.description = description;
+    }
+
+    public ListModel<GlusterVolumeSnapshotScheduleRecurrence> getRecurrence() {
+        return recurrence;
+    }
+
+    public void 
setRecurrence(ListModel<GlusterVolumeSnapshotScheduleRecurrence> recurrence) {
+        this.recurrence = recurrence;
+    }
+
+    public ListModel<String> getInterval() {
+        return interval;
+    }
+
+    public void setInterval(ListModel<String> interval) {
+        this.interval = interval;
+    }
+
+    public ListModel<EndDateOptions> getEndByOptions() {
+        return endByOptions;
+    }
+
+    public void setEndByOptions(ListModel<EndDateOptions> endByOptions) {
+        this.endByOptions = endByOptions;
+    }
+
+    public EntityModel<Date> getEndDate() {
+        return endDate;
+    }
+
+    public void setEndDate(EntityModel<Date> endDate) {
+        this.endDate = endDate;
+    }
+
+    public boolean isGeneralTabVisible() {
+        return generalTabVisible;
+    }
+
+    public void setGeneralTabVisible(boolean generalTabVisible) {
+        this.generalTabVisible = generalTabVisible;
+    }
+
+    public boolean isScheduleTabVisible() {
+        return scheduleTabVisible;
+    }
+
+    public void setScheduleTabVisible(boolean scheduleTabVisible) {
+        this.scheduleTabVisible = scheduleTabVisible;
+    }
+
+    public ListModel<String> getTimeZones() {
+        return timeZones;
+    }
+
+    public void setTimeZones(ListModel<String> timeZones) {
+        this.timeZones = timeZones;
+    }
+
+    public EntityModel<Date> getStartAt() {
+        return this.startAt;
+    }
+
+    public void setStartAt(EntityModel<Date> value) {
+        this.startAt = value;
+    }
+
+    public EntityModel<Date> getExecutionTime() {
+        return this.executionTime;
+    }
+
+    public void setExecutionTime(EntityModel<Date> value) {
+        this.executionTime = value;
+    }
+
+    public ListModel<List<DayOfWeek>> getDaysOfTheWeek() {
+        return daysOfWeek;
+    }
+
+    public void setDaysOfTheWeek(ListModel<List<DayOfWeek>> daysOfTheWeek) {
+        this.daysOfWeek = daysOfTheWeek;
+    }
+
+    public ListModel<String> getDaysOfMonth() {
+        return daysOfMonth;
+    }
+
+    public void setDaysOfMonth(ListModel<String> daysOfMonth) {
+        this.daysOfMonth = daysOfMonth;
+    }
+
+    public boolean validate() {
+        boolean validWeekDays = true;
+        boolean validMonthDays = true;
+        boolean validEndDate = true;
+        getSnapshotName().validateEntity(new IValidation[] { new 
NotEmptyValidation(), new LengthValidation(128),
+                new AsciiNameValidation() });
+
+        if (getRecurrence().getSelectedItem() == 
GlusterVolumeSnapshotScheduleRecurrence.WEEKLY
+                && (getDaysOfTheWeek().getSelectedItem() == null || 
getDaysOfTheWeek().getSelectedItem().isEmpty())) {
+            
setMessage(ConstantsManager.getInstance().getConstants().noWeekDaysSelectedMessage());
+            validWeekDays = false;
+        }
+
+        if (getRecurrence().getSelectedItem() == 
GlusterVolumeSnapshotScheduleRecurrence.MONTHLY) {
+            if (getDaysOfMonth().getSelectedItem() == null || 
getDaysOfMonth().getSelectedItem().equals("")) {//$NON-NLS-1$
+                
setMessage(ConstantsManager.getInstance().getConstants().noMonthDaysSelectedMessage());
+                validMonthDays = false;
+            } else if (getDaysOfMonth().getSelectedItem().contains(",L") || 
getDaysOfMonth().getSelectedItem().contains("L,")) {//$NON-NLS-1$//$NON-NLS-2$
+                
setMessage(ConstantsManager.getInstance().getConstants().lastDayMonthCanBeSelectedAlone());
+                validMonthDays = false;
+            }
+        }
+
+        if (getEndByOptions().getSelectedItem() == EndDateOptions.HasEndDate
+                && 
getEndDate().getEntity().compareTo(getStartAt().getEntity()) < 0) {
+            
setMessage(ConstantsManager.getInstance().getConstants().endDateBeforeStartDate());
+            validEndDate = false;
+        }
+
+        return getSnapshotName().getIsValid() && 
getDaysOfTheWeek().getIsValid() && getDaysOfMonth().getIsValid()
+                && validWeekDays && validMonthDays && validEndDate;
+    }
+
+    public enum EndDateOptions {
+        
HasEndDate(ConstantsManager.getInstance().getConstants().endDateOptionText()),
+        
NoEndDate(ConstantsManager.getInstance().getConstants().noEndDateOptionText());
+
+        private String description;
+
+        private EndDateOptions(String description) {
+            this.description = description;
+        }
+
+        @Override
+        public String toString() {
+            return description;
+        }
+    }
+}
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java
index 1559d07..53a2d97 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java
@@ -113,6 +113,8 @@
     private UICommand stopVolumeProfilingCommand;
     private UICommand configureClusterSnapshotOptionsCommand;
     private UICommand configureVolumeSnapshotOptionsCommand;
+    private UICommand createSnapshotCommand;
+    private UICommand editSnapshotScheduleCommand;
 
     public UICommand getStartRebalanceCommand() {
         return startRebalanceCommand;
@@ -233,6 +235,22 @@
         this.configureVolumeSnapshotOptionsCommand = command;
     }
 
+    public UICommand getCreateSnapshotCommand() {
+        return this.createSnapshotCommand;
+    }
+
+    public void setCreateSnapshotCommand(UICommand command) {
+        this.createSnapshotCommand = command;
+    }
+
+    public UICommand getEditSnapshotScheduleCommand() {
+        return this.editSnapshotScheduleCommand;
+    }
+
+    public void setEditSnapshotScheduleCommand(UICommand command) {
+        this.editSnapshotScheduleCommand = command;
+    }
+
     public VolumeListModel() {
         setTitle(ConstantsManager.getInstance().getConstants().volumesTitle());
         setApplicationPlace(WebAdminApplicationPlaces.volumeMainTabPlace);
@@ -255,6 +273,8 @@
         setOptimizeForVirtStoreCommand(new UICommand("OptimizeForVirtStore", 
this)); //$NON-NLS-1$
         setConfigureClusterSnapshotOptionsCommand(new 
UICommand("configureClusterSnapshotOptions", this)); //$NON-NLS-1$
         setConfigureVolumeSnapshotOptionsCommand(new 
UICommand("configureVolumeSnapshotOptions", this)); //$NON-NLS-1$
+        setCreateSnapshotCommand(new UICommand("createSnapshot", this)); 
//$NON-NLS-1$
+        setEditSnapshotScheduleCommand(new UICommand("editSnapshotSchedule", 
this)); //$NON-NLS-1$
 
         getRemoveVolumeCommand().setIsExecutionAllowed(false);
         getStartCommand().setIsExecutionAllowed(false);
@@ -483,6 +503,8 @@
         boolean allowProfileStatisticsDetails = false;
         boolean allowConfigureClusterSnapshotOptions = true;
         boolean allowConfigureVolumeSnapshotOptions = false;
+        boolean allowCreateSnapshot = false;
+        boolean allowEditSnapshotSchedule = false;
 
         if (getSelectedItems() == null || getSelectedItems().size() == 0) {
             allowStart = false;
@@ -530,6 +552,8 @@
             }
             allowStatusRebalance = 
getRebalanceStatusAvailability(getSelectedItems());
             allowProfileStatisticsDetails = 
getProfileStatisticsAvailability(list);
+            allowCreateSnapshot = isCreateSnapshotAvailable(list);
+            allowEditSnapshotSchedule = isEditSnapshotScheduleAvailable(list);
         }
         getStartCommand().setIsExecutionAllowed(allowStart);
         getStopCommand().setIsExecutionAllowed(allowStop);
@@ -540,6 +564,8 @@
         getOptimizeForVirtStoreCommand().setIsExecutionAllowed(allowOptimize);
         
getConfigureClusterSnapshotOptionsCommand().setIsExecutionAllowed(allowConfigureClusterSnapshotOptions);
         
getConfigureVolumeSnapshotOptionsCommand().setIsExecutionAllowed(allowConfigureVolumeSnapshotOptions);
+        getCreateSnapshotCommand().setIsExecutionAllowed(allowCreateSnapshot);
+        
getEditSnapshotScheduleCommand().setIsExecutionAllowed(allowEditSnapshotSchedule);
 
         // System tree dependent actions.
         boolean isAvailable =
@@ -550,6 +576,15 @@
         
getStartVolumeProfilingCommand().setIsExecutionAllowed(allowStartProfiling);
         
getStopVolumeProfilingCommand().setIsExecutionAllowed(allowStopProfiling);
         
getShowVolumeProfileDetailsCommand().setIsExecutionAllowed(allowProfileStatisticsDetails);
+    }
+
+    private boolean isCreateSnapshotAvailable(List<GlusterVolumeEntity> list) {
+        return ((list.size() == 1) && (list.get(0).getStatus() == 
GlusterStatus.UP));
+    }
+
+    private boolean isEditSnapshotScheduleAvailable(List<GlusterVolumeEntity> 
list) {
+        return ((list.size() == 1) && (list.get(0).getStatus() == 
GlusterStatus.UP) && list.get(0)
+                .getSnapshotScheduled());
     }
 
     private boolean isStopProfileAvailable(List<GlusterVolumeEntity> list) {
@@ -676,6 +711,10 @@
             confirmConfigureVolumeSnapshotOptions();
         } else if 
(command.getName().equalsIgnoreCase("onConfigureVolumeSnapshotOptions")) 
{//$NON-NLS-1$
             onConfigureVolumeSnapshotOptions();
+        } else if (command.equals(getCreateSnapshotCommand())) {
+            getSnapshotListModel().getCreateSnapshotCommand().execute();
+        } else if (command.equals(getEditSnapshotScheduleCommand())) {
+            getSnapshotListModel().getEditSnapshotScheduleCommand().execute();
         }
     }
 
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 4d6b287..20181f2 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
@@ -2502,6 +2502,18 @@
     String geoRepForceHelp();
 
     // Gluster Volume Snapshots
+    @DefaultStringValue("Create/Schedule Snapshot")
+    String createScheduleVolumeSnapshotTitle();
+
+    @DefaultStringValue("Edit Snapshot Schedule")
+    String editVolumeSnapshotScheduleTitle();
+
+    @DefaultStringValue("Date")
+    String endDateOptionText();
+
+    @DefaultStringValue("No End Date")
+    String noEndDateOptionText();
+
     @DefaultStringValue("Volume Snapshot - Cluster Options")
     String configureClusterSnapshotOptionsTitle();
 
@@ -2569,5 +2581,20 @@
 
     @DefaultStringValue("Last Day")
     String lastDay();
+
+    @DefaultStringValue("No week days selected")
+    String noWeekDaysSelectedMessage();
+
+    @DefaultStringValue("No month days selected")
+    String noMonthDaysSelectedMessage();
+
+    @DefaultStringValue("Last day of month cannot be selected with other month 
days")
+    String lastDayMonthCanBeSelectedAlone();
+
+    @DefaultStringValue("End by date cannot be before start date")
+    String endDateBeforeStartDate();
+
+    @DefaultStringValue("Unable to fetch gluster volume snapshot schedule")
+    String unableToFetchVolumeSnapshotSchedule();
 }
 
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 8085d6b..dded460 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
@@ -2,6 +2,8 @@
 
 import java.util.List;
 
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotScheduleRecurrence;
+
 public interface UIMessages extends com.google.gwt.i18n.client.Messages {
 
     @DefaultMessage("One of the parameters isn''t supported (available 
parameter(s): {0})")
@@ -439,4 +441,15 @@
 
     @DefaultMessage("Below snapshots would be removed. Do you want to 
continue?\n\n {0}")
     String confirmVolumeSnapshotDeleteMessage(String snapshotNames);
+
+    @DefaultMessage("Incorrect enum")
+    @AlternateMessage({
+        "UNKNOWN", "None",
+        "INTERVAL", "Minutely",
+        "HOURLY", "Hourly",
+        "DAILY", "Daily",
+        "WEEKLY", "Weekly",
+        "MONTHLY", "Monthly"
+    })
+    String recurrenceType(@Select GlusterVolumeSnapshotScheduleRecurrence 
recurrence);
 }
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java
 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java
index fd60de5..b94ff9d 100644
--- 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java
+++ 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java
@@ -3929,6 +3929,57 @@
     String geoRepSlaveVolume();
 
     // Volume snapshots
+    @DefaultStringValue("New")
+    String newVolumeSnapshot();
+
+    @DefaultStringValue("Edit Schedule")
+    String editVolumeSnapshotSchedule();
+
+    @DefaultStringValue("Schedule")
+    String scheduleLabel();
+
+    @DefaultStringValue("Recurrence")
+    String recurrenceLabel();
+
+    @DefaultStringValue("Interval (mins)")
+    String intervalLabel();
+
+    @DefaultStringValue("End By")
+    String endByLabel();
+
+    @DefaultStringValue("End By Date")
+    String endByDateLabel();
+
+    @DefaultStringValue("Time Zone")
+    String timeZoneLabel();
+
+    @DefaultStringValue("Days Of month")
+    String daysOfMonthLabel();
+
+    @DefaultStringValue("Days Of Week")
+    String daysOfWeekLabel();
+
+    @DefaultStringValue("Start At")
+    String startAtLabel();
+
+    @DefaultStringValue("Execution Time")
+    String executionTimeLabel();
+
+    @DefaultStringValue("No End Date")
+    String noEndDateOption();
+
+    @DefaultStringValue("Date")
+    String endDateOption();
+
+    @DefaultStringValue("Snapshot Name Prefix")
+    String volumeSnapshotNamePrefixLabel();
+
+    @DefaultStringValue("Snapshot name would be formed in the format 
<prefix><timestamp>")
+    String snapshotNameInfo();
+
+    @DefaultStringValue("Description")
+    String volumeSnapshotDescriptionLabel();
+
     @DefaultStringValue("Name")
     String volumeSnapshotName();
 
@@ -3949,6 +4000,9 @@
 
     @DefaultStringValue("Snapshot")
     String volumeSnapshotMainTabTitle();
+
+    @DefaultStringValue("Snapshot Scheduled")
+    String snapshotScheduledLabel();
 
     @DefaultStringValue("Options - Cluster")
     String configureClusterSnapshotOptions();
@@ -3997,4 +4051,7 @@
 
     @DefaultStringValue("Reset")
     String resetGeoRepSessionConfig();
+
+    @DefaultStringValue("Frequent creation of snapshots would overload the 
cluster")
+    String criticalSnapshotIntervalNote();
 }
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 d7a626f..ed8d80e 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
@@ -42,8 +42,11 @@
 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.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;
 import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeGeoReplicationSessionConfigPopupPresenterWidget;
+import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotConfigureOptionsPopupPresenterWidget;
+import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotCreatePopupPresenterWidget;
 import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.RemoveBrickPopupPresenterWidget;
 import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.RemoveBrickStatusPopupPresenterWidget;
 import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.ReplaceBrickPopupPresenterWidget;
@@ -281,7 +284,10 @@
 import 
org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.BrickAdvancedDetailsPopupView;
 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;
 import 
org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GlusterVolumeGeoReplicationSessionConfigPopupView;
+import 
org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GlusterVolumeSnapshotConfigureOptionsPopupView;
+import 
org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GlusterVolumeSnapshotCreatePopupView;
 import 
org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.RemoveBrickPopupView;
 import 
org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.RemoveBrickStatusPopupView;
 import 
org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.ReplaceBrickPopupView;
@@ -771,6 +777,15 @@
                 SubTabClusterCpuProfilePresenter.ViewDef.class,
                 SubTabClusterCpuProfileView.class,
                 SubTabClusterCpuProfilePresenter.ProxyDef.class);
+        
bindPresenterWidget(GlusterVolumeSnapshotConfigureOptionsPopupPresenterWidget.class,
+                
GlusterVolumeSnapshotConfigureOptionsPopupPresenterWidget.ViewDef.class,
+                GlusterVolumeSnapshotConfigureOptionsPopupView.class);
+        
bindPresenterWidget(GlusterClusterSnapshotConfigureOptionsPopupPresenterWidget.class,
+                
GlusterClusterSnapshotConfigureOptionsPopupPresenterWidget.ViewDef.class,
+                GlusterClusterSnapshotConfigureOptionsPopupView.class);
+        
bindPresenterWidget(GlusterVolumeSnapshotCreatePopupPresenterWidget.class,
+                GlusterVolumeSnapshotCreatePopupPresenterWidget.ViewDef.class,
+                GlusterVolumeSnapshotCreatePopupView.class);
 
         // Host
         bindPresenter(HostSubTabPanelPresenter.class,
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java
 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java
index 85176bc..680eb9a 100644
--- 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java
+++ 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java
@@ -32,8 +32,11 @@
 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.GlusterClusterSnapshotConfigureOptionsPopupPresenterWidget;
 import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeGeoRepActionConfirmPopUpViewPresenterWidget;
 import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeGeoReplicationSessionConfigPopupPresenterWidget;
+import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotConfigureOptionsPopupPresenterWidget;
+import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotCreatePopupPresenterWidget;
 import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.RemoveBrickPopupPresenterWidget;
 import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.RemoveBrickStatusPopupPresenterWidget;
 import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.ReplaceBrickPopupPresenterWidget;
@@ -59,7 +62,9 @@
             final Provider<VolumePopupPresenterWidget> popupProvider,
             final Provider<RemoveConfirmationPopupPresenterWidget> 
removeConfirmPopupProvider,
             final Provider<VolumeRebalanceStatusPopupPresenterWidget> 
rebalanceStatusPopupProvider,
-            final Provider<VolumeProfileStatisticsPopupPresenterWidget> 
volumeProfileStatsPopupProvider) {
+            final Provider<VolumeProfileStatisticsPopupPresenterWidget> 
volumeProfileStatsPopupProvider,
+            final 
Provider<GlusterVolumeSnapshotConfigureOptionsPopupPresenterWidget> 
volumeSnapshotConfigOptionsPopupProvider,
+            final 
Provider<GlusterClusterSnapshotConfigureOptionsPopupPresenterWidget> 
clusterSnapshotConfigOptionsPopupProvider) {
         return new MainTabModelProvider<GlusterVolumeEntity, 
VolumeListModel>(eventBus, defaultConfirmPopupProvider, VolumeListModel.class) {
             @Override
             public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> 
getModelPopup(VolumeListModel source,
@@ -72,6 +77,12 @@
                 }
                 else if(lastExecutedCommand == 
getModel().getShowVolumeProfileDetailsCommand() || 
lastExecutedCommand.getName().equals("showProfileDetails")) {//$NON-NLS-1$
                     return volumeProfileStatsPopupProvider.get();
+                }
+                else if (lastExecutedCommand == 
getModel().getConfigureVolumeSnapshotOptionsCommand()) {
+                    return volumeSnapshotConfigOptionsPopupProvider.get();
+                }
+                else if (lastExecutedCommand == 
getModel().getConfigureClusterSnapshotOptionsCommand()) {
+                    return clusterSnapshotConfigOptionsPopupProvider.get();
                 }
                 else {
                     return super.getModelPopup(source, lastExecutedCommand, 
windowModel);
@@ -170,7 +181,8 @@
     @Provides
     @Singleton
     public SearchableDetailModelProvider<GlusterVolumeSnapshotEntity, 
VolumeListModel, GlusterVolumeSnapshotListModel> 
getVolumeSnapshotListProvider(EventBus eventBus,
-            Provider<DefaultConfirmationPopupPresenterWidget> 
defaultConfirmPopupProvider) {
+            Provider<DefaultConfirmationPopupPresenterWidget> 
defaultConfirmPopupProvider,
+            final Provider<GlusterVolumeSnapshotCreatePopupPresenterWidget> 
snapshotPopupProvider) {
         return new 
SearchableDetailTabModelProvider<GlusterVolumeSnapshotEntity, VolumeListModel, 
GlusterVolumeSnapshotListModel>(eventBus,
                 defaultConfirmPopupProvider,
                 VolumeListModel.class,
@@ -179,6 +191,11 @@
                     public AbstractModelBoundPopupPresenterWidget<? extends 
Model, ?> getModelPopup(GlusterVolumeSnapshotListModel source,
                             UICommand lastExecutedCommand,
                             Model windowModel) {
+                        if (lastExecutedCommand == 
getModel().getCreateSnapshotCommand()) {
+                            return snapshotPopupProvider.get();
+                        } else if (lastExecutedCommand == 
getModel().getEditSnapshotScheduleCommand()) {
+                            return snapshotPopupProvider.get();
+                        }
                         return super.getModelPopup(source, 
lastExecutedCommand, windowModel);
                     }
 
@@ -273,5 +290,4 @@
     @Override
     protected void configure() {
     }
-
 }
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/GlusterVolumeSnapshotCreatePopupPresenterWidget.java
 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/GlusterVolumeSnapshotCreatePopupPresenterWidget.java
new file mode 100644
index 0000000..5385e55
--- /dev/null
+++ 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/GlusterVolumeSnapshotCreatePopupPresenterWidget.java
@@ -0,0 +1,61 @@
+package org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster;
+
+import 
org.ovirt.engine.ui.common.presenter.AbstractModelBoundPopupPresenterWidget;
+import 
org.ovirt.engine.ui.common.presenter.popup.DefaultConfirmationPopupPresenterWidget;
+import org.ovirt.engine.ui.uicommonweb.models.ListModel;
+import 
org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotModel;
+import org.ovirt.engine.ui.uicompat.Event;
+import org.ovirt.engine.ui.uicompat.EventArgs;
+import org.ovirt.engine.ui.uicompat.IEventListener;
+
+import com.google.gwt.event.shared.EventBus;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+public class GlusterVolumeSnapshotCreatePopupPresenterWidget extends 
AbstractModelBoundPopupPresenterWidget<GlusterVolumeSnapshotModel, 
GlusterVolumeSnapshotCreatePopupPresenterWidget.ViewDef> {
+    @Inject
+    public GlusterVolumeSnapshotCreatePopupPresenterWidget(EventBus eventBus,
+            ViewDef view,
+            Provider<GlusterVolumeSnapshotCreatePopupPresenterWidget> 
snapshotPopupProvider,
+            Provider<DefaultConfirmationPopupPresenterWidget> 
defaultConfirmPopupPrivder) {
+        super(eventBus, view);
+    }
+
+    @Override
+    public void init(final GlusterVolumeSnapshotModel model) {
+        super.init(model);
+
+        model.getInterval().getSelectedItemChangedEvent().addListener(new 
IEventListener() {
+            @Override
+            public void eventRaised(Event ev, Object sender, EventArgs args) {
+                getView().setCriticalIntervalLabelVisibility(model,
+                        Integer.parseInt(((ListModel<String>) 
sender).getSelectedItem()));
+            }
+        });
+
+        model.getRecurrence().getSelectedItemChangedEvent().addListener(new 
IEventListener() {
+            @Override
+            public void eventRaised(Event ev, Object sender, EventArgs args) {
+                getView().updateVisibilities(model);
+                getView().setCriticalIntervalLabelVisibility(model,
+                        
Integer.parseInt(model.getInterval().getSelectedItem()));
+                getView().setMessage(null);
+            }
+        });
+
+        model.getEndByOptions().getSelectedItemChangedEvent().addListener(new 
IEventListener() {
+            @Override
+            public void eventRaised(Event ev, Object sender, EventArgs args) {
+                getView().setEndDateVisibility(model);
+            }
+        });
+    }
+
+    public interface ViewDef extends 
AbstractModelBoundPopupPresenterWidget.ViewDef<GlusterVolumeSnapshotModel> {
+        public void updateVisibilities(GlusterVolumeSnapshotModel object);
+
+        public void setEndDateVisibility(GlusterVolumeSnapshotModel object);
+
+        public void 
setCriticalIntervalLabelVisibility(GlusterVolumeSnapshotModel object, int 
value);
+    }
+}
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.java
 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.java
new file mode 100644
index 0000000..c5b998b
--- /dev/null
+++ 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.java
@@ -0,0 +1,274 @@
+package org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster;
+
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotScheduleRecurrence;
+import org.ovirt.engine.core.compat.DayOfWeek;
+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.InfoIcon;
+import org.ovirt.engine.ui.common.widget.dialog.SimpleDialogPanel;
+import org.ovirt.engine.ui.common.widget.dialog.tab.DialogTab;
+import org.ovirt.engine.ui.common.widget.editor.EntityModelDateTimeBoxEditor;
+import org.ovirt.engine.ui.common.widget.editor.ListModelCheckBoxGroupEditor;
+import 
org.ovirt.engine.ui.common.widget.editor.ListModelDaysOfMonthSelectorEditor;
+import org.ovirt.engine.ui.common.widget.editor.ListModelListBoxEditor;
+import org.ovirt.engine.ui.common.widget.editor.ListModelRadioGroupEditor;
+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.uicommonweb.models.gluster.GlusterVolumeSnapshotModel;
+import 
org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotModel.EndDateOptions;
+import org.ovirt.engine.ui.uicompat.ConstantsManager;
+import org.ovirt.engine.ui.webadmin.ApplicationConstants;
+import org.ovirt.engine.ui.webadmin.ApplicationResources;
+import org.ovirt.engine.ui.webadmin.ApplicationTemplates;
+import 
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotCreatePopupPresenterWidget;
+
+import com.google.gwt.core.shared.GWT;
+import com.google.gwt.editor.client.SimpleBeanEditorDriver;
+import com.google.gwt.event.shared.EventBus;
+import com.google.gwt.resources.client.CssResource;
+import com.google.gwt.text.shared.AbstractRenderer;
+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 GlusterVolumeSnapshotCreatePopupView extends
+        AbstractModelBoundPopupView<GlusterVolumeSnapshotModel> implements
+        GlusterVolumeSnapshotCreatePopupPresenterWidget.ViewDef {
+    interface Driver
+            extends
+            SimpleBeanEditorDriver<GlusterVolumeSnapshotModel, 
GlusterVolumeSnapshotCreatePopupView> {
+    }
+
+    interface ViewUiBinder extends
+            UiBinder<SimpleDialogPanel, GlusterVolumeSnapshotCreatePopupView> {
+        ViewUiBinder uiBinder = GWT.create(ViewUiBinder.class);
+    }
+
+    interface ViewIdHandler extends
+            ElementIdHandler<GlusterVolumeSnapshotCreatePopupView> {
+        ViewIdHandler idHandler = GWT.create(ViewIdHandler.class);
+    }
+
+    @UiField
+    WidgetStyle style;
+
+    @UiField
+    DialogTab generalTab;
+
+    @UiField
+    @Path(value = "clusterName.entity")
+    @WithElementId
+    StringEntityModelLabelEditor clusterNameEditor;
+
+    @UiField
+    @Path(value = "volumeName.entity")
+    @WithElementId
+    StringEntityModelLabelEditor volumeNameEditor;
+
+    @UiField
+    @Path(value = "snapshotName.entity")
+    @WithElementId
+    StringEntityModelTextBoxEditor snapshotNameEditor;
+
+    @UiField(provided = true)
+    InfoIcon snapshotNameInfoIcon;
+
+    @UiField
+    @Path(value = "description.entity")
+    @WithElementId
+    StringEntityModelTextBoxEditor snapshotDescriptionEditor;
+
+    @UiField
+    DialogTab scheduleTab;
+
+    @UiField(provided = true)
+    @Path(value = "recurrence.selectedItem")
+    @WithElementId
+    ListModelListBoxEditor<GlusterVolumeSnapshotScheduleRecurrence> 
recurrenceEditor;
+
+    @UiField
+    @Path(value = "timeZones.selectedItem")
+    @WithElementId
+    ListModelListBoxEditor<String> timeZoneEditor;
+
+    @UiField(provided = true)
+    @Path(value = "daysOfTheWeek.selectedItem")
+    @WithElementId
+    ListModelCheckBoxGroupEditor<DayOfWeek> daysOfWeekEditor;
+
+    @UiField
+    @Path(value = "interval.selectedItem")
+    @WithElementId
+    ListModelListBoxEditor<String> intervalEditor;
+
+    @UiField
+    @Path(value = "endByOptions.selectedItem")
+    @WithElementId
+    ListModelRadioGroupEditor<EndDateOptions> endByOptionsEditor;
+
+    @UiField(provided = true)
+    @Path(value = "endDate.entity")
+    @WithElementId
+    EntityModelDateTimeBoxEditor endDate;
+
+    @UiField(provided = true)
+    @Path(value = "startAt.entity")
+    @WithElementId
+    EntityModelDateTimeBoxEditor startAtEditor;
+
+    @UiField(provided = true)
+    @Path(value = "executionTime.entity")
+    @WithElementId
+    EntityModelDateTimeBoxEditor executionTimeEditor;
+
+    @UiField
+    @Path(value = "daysOfMonth.selectedItem")
+    @WithElementId
+    ListModelDaysOfMonthSelectorEditor daysOfMonthEditor;
+
+    @UiField
+    @Ignore
+    @WithElementId
+    Label criticalIntervalLabel;
+
+    @UiField
+    @Ignore
+    @WithElementId
+    Label errorMsgLabel;
+
+    private final ApplicationConstants constants;
+
+    private final Driver driver = GWT.create(Driver.class);
+
+    @Inject
+    public GlusterVolumeSnapshotCreatePopupView(EventBus eventBus,
+            ApplicationResources resources, ApplicationConstants constants,
+            ApplicationTemplates templates) {
+        super(eventBus, resources);
+        this.constants = constants;
+        initEditors(constants, resources, templates);
+        initWidget(ViewUiBinder.uiBinder.createAndBindUi(this));
+        ViewIdHandler.idHandler.generateAndSetIds(this);
+        localize();
+        setVisibilities();
+        driver.initialize(this);
+        daysOfWeekEditor.asCheckBoxGroup().clearAllSelections();
+    }
+
+    private void initEditors(ApplicationConstants constants,
+            ApplicationResources resources, ApplicationTemplates templates) {
+        snapshotNameInfoIcon = new 
InfoIcon(templates.italicText(constants.snapshotNameInfo()), resources);
+        startAtEditor = new EntityModelDateTimeBoxEditor();
+        daysOfWeekEditor = new ListModelCheckBoxGroupEditor<DayOfWeek>(new 
AbstractRenderer<DayOfWeek>() {
+            @Override
+            public String render(DayOfWeek object) {
+                return object.toString().substring(0, 3);
+            }
+        });
+        endDate = new EntityModelDateTimeBoxEditor();
+        executionTimeEditor = new EntityModelDateTimeBoxEditor();
+        executionTimeEditor.getContentWidget().setDateRequired(false);
+        recurrenceEditor =
+                new 
ListModelListBoxEditor<GlusterVolumeSnapshotScheduleRecurrence>(new 
AbstractRenderer<GlusterVolumeSnapshotScheduleRecurrence>() {
+                    @Override
+                    public String 
render(GlusterVolumeSnapshotScheduleRecurrence object) {
+                        return 
ConstantsManager.getInstance().getMessages().recurrenceType(object);
+                    }
+        });
+    }
+
+    private void localize() {
+        generalTab.setLabel(constants.generalLabel());
+
+        clusterNameEditor.setLabel(constants.volumeClusterLabel());
+        volumeNameEditor.setLabel(constants.volumeNameLabel());
+        snapshotNameEditor.setLabel(constants.volumeSnapshotNamePrefixLabel());
+        
snapshotDescriptionEditor.setLabel(constants.volumeSnapshotDescriptionLabel());
+
+        scheduleTab.setLabel(constants.scheduleLabel());
+
+        recurrenceEditor.setLabel(constants.recurrenceLabel());
+        intervalEditor.setLabel(constants.intervalLabel());
+        endByOptionsEditor.setLabel(constants.endByLabel());
+
+        timeZoneEditor.setLabel(constants.timeZoneLabel());
+        daysOfMonthEditor.setLabel(constants.daysOfMonthLabel());
+        daysOfWeekEditor.setLabel(constants.daysOfWeekLabel());
+        startAtEditor.setLabel(constants.startAtLabel());
+        endDate.setLabel(constants.endByDateLabel());
+        executionTimeEditor.setLabel(constants.executionTimeLabel());
+
+        
criticalIntervalLabel.setText(constants.criticalSnapshotIntervalNote());
+    }
+
+    private void setVisibilities() {
+        criticalIntervalLabel.setVisible(false);
+    }
+
+    @Override
+    public void edit(final GlusterVolumeSnapshotModel object) {
+        driver.edit(object);
+        updateVisibilities(object);
+        updateTabVisibilities(object);
+    }
+
+    @Override
+    public void updateVisibilities(GlusterVolumeSnapshotModel object) {
+        GlusterVolumeSnapshotScheduleRecurrence recurrenceOption = object
+                .getRecurrence().getSelectedItem();
+
+        intervalEditor.setVisible(recurrenceOption == 
GlusterVolumeSnapshotScheduleRecurrence.INTERVAL);
+        endByOptionsEditor.setVisible(recurrenceOption != 
GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN);
+        timeZoneEditor.setVisible(recurrenceOption == 
GlusterVolumeSnapshotScheduleRecurrence.DAILY
+                || recurrenceOption == 
GlusterVolumeSnapshotScheduleRecurrence.WEEKLY
+                || recurrenceOption == 
GlusterVolumeSnapshotScheduleRecurrence.MONTHLY);
+        daysOfWeekEditor.setVisible(recurrenceOption == 
GlusterVolumeSnapshotScheduleRecurrence.WEEKLY);
+        daysOfMonthEditor.setVisible(recurrenceOption == 
GlusterVolumeSnapshotScheduleRecurrence.MONTHLY);
+        startAtEditor.setVisible(recurrenceOption != 
GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN);
+        executionTimeEditor.setVisible(recurrenceOption == 
GlusterVolumeSnapshotScheduleRecurrence.DAILY
+                || recurrenceOption == 
GlusterVolumeSnapshotScheduleRecurrence.WEEKLY
+                || recurrenceOption == 
GlusterVolumeSnapshotScheduleRecurrence.MONTHLY);
+
+        setEndDateVisibility(object);
+    }
+
+    @Override
+    public void setEndDateVisibility(GlusterVolumeSnapshotModel object) {
+        endDate.setVisible(object.getRecurrence().getSelectedItem() != 
GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN
+                && object.getEndByOptions().getSelectedItem() == 
EndDateOptions.HasEndDate);
+    }
+
+    @Override
+    public void setCriticalIntervalLabelVisibility(GlusterVolumeSnapshotModel 
object, int interval) {
+        if (object.getRecurrence().getSelectedItem() == 
GlusterVolumeSnapshotScheduleRecurrence.INTERVAL) {
+            criticalIntervalLabel.setVisible(interval <= 30);
+        } else {
+            criticalIntervalLabel.setVisible(false);
+        }
+    }
+
+    @Override
+    public void setMessage(String msg) {
+        super.setMessage(msg);
+        errorMsgLabel.setText(msg);
+    }
+
+    private void updateTabVisibilities(GlusterVolumeSnapshotModel object) {
+        generalTab.setVisible(object.isGeneralTabVisible());
+        scheduleTab.setVisible(object.isScheduleTabVisible());
+        if (object.getRecurrence().getSelectedItem() != 
GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN) {
+            scheduleTab.activate();
+        }
+    }
+
+    @Override
+    public GlusterVolumeSnapshotModel flush() {
+        return driver.flush();
+    }
+
+    interface WidgetStyle extends CssResource {
+        String editorContentWidget();
+    }
+}
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.ui.xml
 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.ui.xml
new file mode 100644
index 0000000..bd18806
--- /dev/null
+++ 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.ui.xml
@@ -0,0 +1,111 @@
+<?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:ge="urn:import:org.ovirt.engine.ui.common.widget.editor.generic"
+       xmlns:e="urn:import:org.ovirt.engine.ui.common.widget.editor" 
xmlns:w="urn:import:org.ovirt.engine.ui.common.widget"
+       xmlns:t="urn:import:org.ovirt.engine.ui.common.widget.dialog.tab">
+
+       <ui:style
+               
type="org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GlusterVolumeSnapshotCreatePopupView.WidgetStyle">
+               .panelStyle {
+               width:470px;
+               height:500px;
+               }
+
+               .editorContentWidget{
+               width: 50px;
+               }
+
+               .criticalIntervalLabel {
+               width: 450px;
+               height:
+               50px;
+               font-size: 13px;
+               left: 10px;
+               padding-left: 15px;
+               padding-bottom:
+               10px;
+               color: #FF0000;
+               }
+
+               .errMsgLabel {
+               width: 450px;
+               height: 50px;
+               font-size: 13px;
+               left: 10px;
+               color: #FF0000;
+               }
+
+               .snapshotNameInfoIcon {
+               width: 15px;
+               }
+
+               .snapshotName{
+               width: 470px;
+               }
+
+               .daysOfMonthEditor {
+               padding-bottom: 10px;
+               }
+
+               .endDate {
+               padding-bottom: 10px;
+               }
+
+       </ui:style>
+
+       <d:SimpleDialogPanel width="700px" height="500px">
+               <d:content>
+                       <t:DialogTabPanel height="100%" width="100%">
+                               <t:tab>
+                                       <t:DialogTab ui:field="generalTab">
+                                               <t:content>
+                                                       <g:FlowPanel 
addStyleNames="{style.panelStyle}">
+                                                               
<ge:StringEntityModelLabelEditor
+                                                                       
ui:field="clusterNameEditor" />
+                                                               
<ge:StringEntityModelLabelEditor
+                                                                       
ui:field="volumeNameEditor" />
+                                                               
<g:HorizontalPanel>
+                                                                       
<ge:StringEntityModelTextBoxEditor
+                                                                               
ui:field="snapshotNameEditor" addStyleNames="{style.snapshotName}" />
+                                                                       
<d:InfoIcon ui:field="snapshotNameInfoIcon"
+                                                                               
addStyleNames="{style.snapshotNameInfoIcon}" />
+                                                               
</g:HorizontalPanel>
+                                                               
<ge:StringEntityModelTextBoxEditor
+                                                                       
ui:field="snapshotDescriptionEditor" />
+                                                       </g:FlowPanel>
+                                               </t:content>
+                                       </t:DialogTab>
+                               </t:tab>
+                               <t:tab>
+                                       <t:DialogTab ui:field="scheduleTab">
+                                               <t:content>
+                                                       <g:FlowPanel 
addStyleNames="{style.panelStyle}">
+                                                               
<e:ListModelListBoxEditor ui:field="recurrenceEditor" />
+                                                               
<e:ListModelListBoxEditor ui:field="intervalEditor" />
+                                                               
<e:ListModelListBoxEditor ui:field="timeZoneEditor" />
+                                                               
<e:EntityModelDateTimeBoxEditor
+                                                                       
ui:field="startAtEditor" />
+                                                               
<e:EntityModelDateTimeBoxEditor
+                                                                       
ui:field="executionTimeEditor" />
+                                                               
<e:ListModelCheckBoxGroupEditor
+                                                                       
ui:field="daysOfWeekEditor" />
+                                                               
<e:ListModelDaysOfMonthSelectorEditor
+                                                                       
ui:field="daysOfMonthEditor" addStyleNames="{style.daysOfMonthEditor}" />
+                                                               
<e:ListModelRadioGroupEditor
+                                                                       
ui:field="endByOptionsEditor" />
+                                                               
<e:EntityModelDateTimeBoxEditor
+                                                                       
ui:field="endDate" addStyleNames="{style.endDate}"/>
+                                                               <g:Label 
ui:field="criticalIntervalLabel"
+                                                                       
addStyleNames="{style.criticalIntervalLabel}" />
+                                                               <g:Label 
ui:field="errorMsgLabel"
+                                                                       
addStyleNames="{style.errMsgLabel}" />
+                                                       </g:FlowPanel>
+                                               </t:content>
+                                       </t:DialogTab>
+                               </t:tab>
+                       </t:DialogTabPanel>
+               </d:content>
+       </d:SimpleDialogPanel>
+</ui:UiBinder>
\ No newline at end of file
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java
 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java
index 7ce2797..96d32e2 100644
--- 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java
+++ 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java
@@ -165,6 +165,16 @@
         snapshotCountColumn.makeSortable();
         getTable().addColumn(snapshotCountColumn, 
constants.noOfSnapshotsLabel(), "100px"); //$NON-NLS-1$
 
+        TextColumnWithTooltip<GlusterVolumeEntity> snapshotScheduledColumn =
+                new TextColumnWithTooltip<GlusterVolumeEntity>() {
+            @Override
+            public String getValue(GlusterVolumeEntity object) {
+                return object.getSnapshotScheduled().toString();
+            }
+        };
+        snapshotScheduledColumn.makeSortable();
+        getTable().addColumn(snapshotScheduledColumn, 
constants.snapshotScheduledLabel(), "100px"); //$NON-NLS-1$
+
         getTable().addActionButton(new 
WebAdminButtonDefinition<GlusterVolumeEntity>(constants.newVolume()) {
             @Override
             protected UICommand resolveCommand() {
@@ -232,7 +242,25 @@
     }
 
     private List<ActionButtonDefinition<GlusterVolumeEntity>> 
getVolumeSnapshotMenu(ApplicationConstants constants) {
-        List<ActionButtonDefinition<GlusterVolumeEntity>> snapshotMenu = new 
ArrayList<ActionButtonDefinition<GlusterVolumeEntity>>();
+        List<ActionButtonDefinition<GlusterVolumeEntity>> snapshotMenu =
+                new ArrayList<ActionButtonDefinition<GlusterVolumeEntity>>();
+
+        WebAdminButtonDefinition<GlusterVolumeEntity> newSnapshotButton =
+                new 
WebAdminButtonDefinition<GlusterVolumeEntity>(constants.newVolumeSnapshot()) {
+                    @Override
+                    protected UICommand resolveCommand() {
+                        return getMainModel().getCreateSnapshotCommand();
+                    }
+                };
+        snapshotMenu.add(newSnapshotButton);
+        WebAdminButtonDefinition<GlusterVolumeEntity> 
editSnapshotScheduleButton =
+                new 
WebAdminButtonDefinition<GlusterVolumeEntity>(constants.editVolumeSnapshotSchedule())
 {
+                    @Override
+                    protected UICommand resolveCommand() {
+                        return getMainModel().getEditSnapshotScheduleCommand();
+                    }
+                };
+        snapshotMenu.add(editSnapshotScheduleButton);
 
         WebAdminButtonDefinition<GlusterVolumeEntity> 
configureClusterSnapshotOptionsButton = new 
WebAdminButtonDefinition<GlusterVolumeEntity>(constants.configureClusterSnapshotOptions())
 {
             @Override
@@ -249,6 +277,7 @@
 
         snapshotMenu.add(configureClusterSnapshotOptionsButton);
         snapshotMenu.add(configureVolumeSnapshotOptionsButton);
+
         return snapshotMenu;
     }
 


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I823580ecb127e48e075c437668bfb19ff8ec4467
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: ovirt-engine-3.5-gluster
Gerrit-Owner: Shubhendu Tripathi <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to