diff options
author | Selvasundaram <selvam@gluster.com> | 2011-11-07 18:24:41 +0530 |
---|---|---|
committer | Selvasundaram <selvam@gluster.com> | 2011-11-07 18:24:41 +0530 |
commit | 3222bf63755b6e8f0685a84be999915c58b15f20 (patch) | |
tree | 6fddd515729b453ef2fd1101f3808501a0b05315 | |
parent | 42c8f489c680b6028c0849551422a2fddaa1e936 (diff) | |
parent | 8c12e81986ec073ae3edc66fd18ae9d5651623d2 (diff) |
Merge branch 'master' of github.com:gluster/console
33 files changed, 353 insertions, 79 deletions
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java index f85afd4d..ec8d0212 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java @@ -87,19 +87,20 @@ public class VolumesClient extends AbstractClient { postRequest(form); } - private void performOperation(String volumeName, String operation) { + private void performOperation(String volumeName, String operation, Boolean force) { Form form = new Form(); form.add(RESTConstants.FORM_PARAM_OPERATION, operation); + form.add(RESTConstants.FORM_PARAM_FORCE, force); putRequest(volumeName, form); } - public void startVolume(String volumeName) { - performOperation(volumeName, RESTConstants.TASK_START); + public void startVolume(String volumeName, Boolean forceStart) { + performOperation(volumeName, RESTConstants.TASK_START, forceStart); } - public void stopVolume(String volumeName) { - performOperation(volumeName, RESTConstants.TASK_STOP); + public void stopVolume(String volumeName, Boolean forceStop) { + performOperation(volumeName, RESTConstants.TASK_STOP, forceStop); } public void setCifsConfig(String volumeName, Boolean isCifsEnabled, String cifsUsers) { diff --git a/src/com.gluster.storage.management.console/icons/tango/22x22/offline-volume.png b/src/com.gluster.storage.management.console/icons/tango/22x22/offline-volume.png Binary files differnew file mode 100644 index 00000000..fa3a64f9 --- /dev/null +++ b/src/com.gluster.storage.management.console/icons/tango/22x22/offline-volume.png diff --git a/src/com.gluster.storage.management.console/icons/tango/32x32/log-rotate.png b/src/com.gluster.storage.management.console/icons/tango/32x32/log-rotate.png Binary files differnew file mode 100644 index 00000000..a1ceebbf --- /dev/null +++ b/src/com.gluster.storage.management.console/icons/tango/32x32/log-rotate.png diff --git a/src/com.gluster.storage.management.console/plugin.xml b/src/com.gluster.storage.management.console/plugin.xml index 6983b9dd..543b3571 100644 --- a/src/com.gluster.storage.management.console/plugin.xml +++ b/src/com.gluster.storage.management.console/plugin.xml @@ -419,7 +419,7 @@ </property> <property name="appName" - value="about"> + value="Gluster Management Console"> </property> <property name="preferenceCustomization" @@ -526,9 +526,20 @@ label="Volume Actions" visible="false"> <action + class="com.gluster.storage.management.console.actions.ForceStartVolumeAction" + definitionId="com.gluster.storage.management.console.commands.ForceStartVolume" + icon="icons/tango/32x32/start-volume.png" + id="com.gluster.storage.management.console.actions.ForceStartVolumeAction" + label="Start Offline Bricks" + menubarPath="com.gluster.storage.management.console.menu.volume/volume" + style="push" + toolbarPath="Normal" + tooltip="Start all Offline Bricks of the selected Volume"> + </action> + <action class="com.gluster.storage.management.console.actions.VolumeLogRotateAction" definitionId="com.gluster.storage.management.console.commands.LogRotate" - icon="icons/tango/32x32/download-log.png" + icon="icons/tango/32x32/log-rotate.png" id="com.gluster.storage.management.console.actions.LogRotateAction" label="L&og Rotate" menubarPath="com.gluster.storage.management.console.menu.volume/volume" diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/AlertsManager.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/AlertsManager.java index 40a64498..a5b3a4e6 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/AlertsManager.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/AlertsManager.java @@ -191,6 +191,9 @@ public class AlertsManager { for (Volume volume : cluster.getVolumes()) { if (volume.getStatus() == VOLUME_STATUS.OFFLINE) { + volumeAlerts.add(new Alert(ALERT_TYPES.OFFLINE_VOLUME_ALERT, volume.getName(), + Alert.ALERT_TYPE_STR[ALERT_TYPES.OFFLINE_VOLUME_ALERT.ordinal()] + " [" + volume.getName() + + "]")); continue; } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/IImageKeys.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/IImageKeys.java index 89b19f3f..cecdb002 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/IImageKeys.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/IImageKeys.java @@ -42,6 +42,7 @@ public interface IImageKeys { public static final String BRICKS_16x16 = "icons/tango/16x16/bricks.png"; public static final String BRICK_ONLINE_16x16 = "icons/tango/16x16/online-brick.png"; public static final String BRICK_OFFLINE_16x16 = "icons/tango/16x16/offline-brick.png"; + public static final String VOLUME_OFFLINE_22x22 = "icons/tango/22x22/offline-volume.png"; public static final String SERVERS_16x16 = "icons/tango/16x16/servers.png"; public static final String SERVER_16x16 = "icons/tango/16x16/server.png"; diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java index 3de3f945..f5f7d209 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java @@ -87,7 +87,7 @@ public class DeleteVolumeAction extends AbstractMonitoredActionDelegate { try { monitor.setTaskName("Deleting volume [" + volume.getName() + "]"); if (volume.getStatus() == VOLUME_STATUS.ONLINE) { // stop if online volume - vc.stopVolume(volume.getName()); + vc.stopVolume(volume.getName(), false); } vc.deleteVolume(volume.getName(), confirmDeleteDir); modelManager.deleteVolume(volume); diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/ForceStartVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/ForceStartVolumeAction.java new file mode 100644 index 00000000..101b7982 --- /dev/null +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/ForceStartVolumeAction.java @@ -0,0 +1,71 @@ +package com.gluster.storage.management.console.actions; + +import java.util.Set; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchPart; + +import com.gluster.storage.management.client.VolumesClient; +import com.gluster.storage.management.console.utils.GUIHelper; +import com.gluster.storage.management.console.views.VolumeBricksView; +import com.gluster.storage.management.core.model.Brick; +import com.gluster.storage.management.core.model.Brick.BRICK_STATUS; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.utils.StringUtil; + +public class ForceStartVolumeAction extends AbstractActionDelegate { + + private Volume volume; + private GUIHelper guiHelper = GUIHelper.getInstance(); + private Set<Brick> bricks; + + @Override + public void dispose() { + + } + + @Override + protected void performAction(IAction action) { + // volume brick service will be started, do you want to continue? + final String actionDesc = action.getDescription(); + boolean confirmed = showConfirmDialog( + actionDesc, + "The offline Bricks [" + StringUtil.collectionToString(bricks, ", ") + "] of Volume [" + + volume.getName() + "] will be started. Are you sure you want to continue?"); + if (!confirmed) { + return; + } + try { + new VolumesClient().startVolume(volume.getName(), true); + showInfoDialog(actionDesc, "Offline Bricks of Volume [" + volume.getName() + "] started successfully!"); + } catch (Exception e) { + showErrorDialog(actionDesc, e.getMessage()); + } + } + + @Override + public void selectionChanged(IAction action, ISelection selection) { + super.selectionChanged(action, selection); + + volume = guiHelper.getSelectedEntity(window, Volume.class); + if (volume != null) { + // a volume is selected on navigation tree. Let's check if the currently open view is volume bricks view + IWorkbenchPart view = guiHelper.getActiveView(); + if (view instanceof VolumeBricksView) { + // volume bricks view is open. check if any offline brick is selected + bricks = GUIHelper.getInstance().getSelectedEntities(getWindow(), Brick.class); + for (Brick brick : bricks) { + if (brick.getStatus() == BRICK_STATUS.OFFLINE) { + action.setEnabled(true); + } else { + // if any one of the selected brick is online, the disable the button + action.setEnabled(false); + break; + } + } + } + } + } + +} diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/RemoveBrickAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/RemoveBrickAction.java index 4b747294..105ab0da 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/RemoveBrickAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/RemoveBrickAction.java @@ -71,10 +71,10 @@ public class RemoveBrickAction extends AbstractActionDelegate { action.setEnabled(false); volume = guiHelper.getSelectedEntity(window, Volume.class); if (volume != null) { - // a volume is selected on navigation tree. Let's check if the currently open view is volume disks view + // a volume is selected on navigation tree. Let's check if the currently open view is volume bricks view IWorkbenchPart view = guiHelper.getActiveView(); if (view instanceof VolumeBricksView) { - // volume disks view is open. check if any brick is selected + // volume bricks view is open. check if any brick is selected bricks = GUIHelper.getInstance().getSelectedEntities(getWindow(), Brick.class); action.setEnabled(bricks.size() > 0); } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/ResetVolumeOptionsAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/ResetVolumeOptionsAction.java index 99a7c887..cd2b3ff5 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/ResetVolumeOptionsAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/ResetVolumeOptionsAction.java @@ -53,6 +53,10 @@ public class ResetVolumeOptionsAction extends AbstractActionDelegate { @Override public void selectionChanged(IAction action, ISelection selection) { volume = GUIHelper.getInstance().getSelectedEntity(getWindow(), Volume.class); - action.setEnabled(volume.getOptions().size() > 0); + if (volume != null) { + action.setEnabled(volume.getOptions().size() > 0); + } else { + action.setEnabled(false); + } } } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java index 0df91ab8..6407b322 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java @@ -84,7 +84,7 @@ public class StartVolumeAction extends AbstractMonitoredActionDelegate { } try { monitor.setTaskName("Starting volume [" + volume.getName() + "]"); - vc.startVolume(volume.getName()); + vc.startVolume(volume.getName(), false); startedVolumes.add(volume.getName()); } catch (Exception e) { failedVolumes.add(volume.getName()); diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java index 31f8d164..dad5d4ac 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java @@ -94,7 +94,7 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { } try { monitor.setTaskName("Stopping volume [" + volume.getName() + "]"); - vc.stopVolume(volume.getName()); + vc.stopVolume(volume.getName(), false); // modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE); stoppedVolumes.add(volume.getName()); } catch (Exception e) { diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/dialogs/CreateVolumeWizard.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/dialogs/CreateVolumeWizard.java index 227c60b7..1558749c 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/dialogs/CreateVolumeWizard.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/dialogs/CreateVolumeWizard.java @@ -99,7 +99,7 @@ public class CreateVolumeWizard extends Wizard { boolean warning = false; if (page.startVolumeAfterCreation()) { try { - volumesClient.startVolume(newVolume.getName()); + volumesClient.startVolume(newVolume.getName(), false); newVolume.setStatus(VOLUME_STATUS.ONLINE); message = "Volume created and started successfully!"; } catch(Exception e) { @@ -127,7 +127,7 @@ public class CreateVolumeWizard extends Wizard { + errMsg + CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Do you still want to start the volume [" + newVolume.getName() + "]?")) { try { - volumesClient.startVolume(newVolume.getName()); + volumesClient.startVolume(newVolume.getName(), false); newVolume.setStatus(VOLUME_STATUS.ONLINE); message1 = "Volume [" + newVolume.getName() + "] started successfully!"; // Only start operation } catch(Exception e1) { diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/preferences/PreferenceInitializer.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/preferences/PreferenceInitializer.java index 3c192f62..72e62447 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/preferences/PreferenceInitializer.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/preferences/PreferenceInitializer.java @@ -42,13 +42,13 @@ public class PreferenceInitializer extends AbstractPreferenceInitializer { store.setDefault(PreferenceConstants.P_DATA_SYNC_INTERVAL, 300); // Default CPU utilisation threshold - store.setDefault(PreferenceConstants.P_SERVER_CPU_CRITICAL_THRESHOLD, 95); + store.setDefault(PreferenceConstants.P_SERVER_CPU_CRITICAL_THRESHOLD, 80); // Default Memory threshold - store.setDefault(PreferenceConstants.P_SERVER_MEMORY_USAGE_THRESHOLD, 90); + store.setDefault(PreferenceConstants.P_SERVER_MEMORY_USAGE_THRESHOLD, 80); // Default disk free space threshold - store.setDefault(PreferenceConstants.P_DISK_SPACE_USAGE_THRESHOLD, 90); + store.setDefault(PreferenceConstants.P_DISK_SPACE_USAGE_THRESHOLD, 80); // Default period for server statistics charts store.setDefault(PreferenceConstants.P_CPU_CHART_PERIOD, "1d"); diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/utils/ChartViewerComposite.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/utils/ChartViewerComposite.java index 8da32a60..9e67ed29 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/utils/ChartViewerComposite.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/utils/ChartViewerComposite.java @@ -37,6 +37,8 @@ import org.eclipse.birt.chart.model.attribute.Bounds; import org.eclipse.birt.chart.model.attribute.ChartDimension; import org.eclipse.birt.chart.model.attribute.LineAttributes; import org.eclipse.birt.chart.model.attribute.LineStyle; +import org.eclipse.birt.chart.model.attribute.Position; +import org.eclipse.birt.chart.model.attribute.Text; import org.eclipse.birt.chart.model.attribute.TickStyle; import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl; import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl; @@ -307,6 +309,9 @@ public final class ChartViewerComposite extends Composite implements PaintListen */ public static final Chart createPieChart(String[] categories, Double[] values) { ChartWithoutAxes pieChart = ChartWithoutAxesImpl.create(); + + // script hook to NOT show the label if value is zero + pieChart.setScript("function beforeDrawDataPointLabel( dph, label, icsc ){ if (dph.getOrthogonalValue() == 0){ label.setVisible(false); } } "); // Plot pieChart.setSeriesThickness(10); @@ -350,8 +355,13 @@ public final class ChartViewerComposite extends Composite implements PaintListen sePie.setDataSet(seriesOneValues); sePie.setSeriesIdentifier("Chart");//$NON-NLS-1$ sePie.getTitle().setVisible(false); // no title - sePie.getLabel().setVisible(false); // no label (values) + sePie.getLabel().setVisible(true); // show label (values) sePie.setExplosion(0); // no gap between the pie slices + sePie.setLabelPosition(Position.INSIDE_LITERAL); + Text labelCaption = sePie.getLabel().getCaption(); + labelCaption.setColor(ColorDefinitionImpl.CYAN()); + labelCaption.getFont().setSize(8); + labelCaption.getFont().setBold(true); SeriesDefinition seriesDefinition = SeriesDefinitionImpl.create(); seriesDefinition.getQuery().setDefinition("query.definition");//$NON-NLS-1$ diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/utils/GUIHelper.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/utils/GUIHelper.java index ab846e74..b8f8d83e 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/utils/GUIHelper.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/utils/GUIHelper.java @@ -34,7 +34,6 @@ import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; -import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ColumnLayoutData; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ICheckStateListener; @@ -44,8 +43,6 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; @@ -348,24 +345,6 @@ public class GUIHelper { } /** - * Sets properties for alignment and weight of given column of given table - * - * @param table - * @param columnIndex - * @param alignment - * @param weight - * - * @return The table viewer column created - */ - public TableViewerColumn setColumnProperties(TableViewer tableViewer, int columnIndex, int style, int weight) { - TableViewerColumn column = new TableViewerColumn(tableViewer, style, columnIndex); - TableColumnLayout tableColumnLayout = (TableColumnLayout) tableViewer.getTable().getParent().getLayout(); - tableColumnLayout.setColumnData(column.getColumn(), new ColumnWeightData(weight)); - column.setLabelProvider(new ColumnLabelProvider()); - return column; - } - - /** * Fetches the currently selected objects from the workbench site and returns the one of given type. If none of the * selected objects are of given type, returns null * diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/utils/TableViewerComparator.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/utils/TableViewerComparator.java new file mode 100644 index 00000000..7e11cc6f --- /dev/null +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/utils/TableViewerComparator.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.console.utils; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; + +/** + * Comparator for sorting contents of a table viewer + */ +public class TableViewerComparator extends ViewerComparator { + private int column = -1; + private static final int ASCENDING = 0; + private static final int DESCENDING = 1; + private static final int NONE = -1; + private int direction = DESCENDING; + + public TableViewerComparator() { + this(NONE); + } + + public TableViewerComparator(int direction) { + this.direction = direction; + } + + public int getDirection() { + return direction == DESCENDING ? SWT.DOWN : (direction == ASCENDING ? SWT.UP : SWT.NONE); + } + + public void setColumn(int column) { + if (column == this.column) { + // Same column as last sort; toggle the direction + direction = 1 - direction; + } else { + // first column selection or new column; do an ascending sort + direction = ASCENDING; + this.column = column; + } + } + + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + if(direction == NONE) { + // no sorting + return 0; + } + + int result = super.compare(viewer, e1, e2); + // If descending order, flip the direction + if (direction == DESCENDING) { + result = -result; + } + + return result; + } +} diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/ClusterSummaryView.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/ClusterSummaryView.java index 6187d5ad..6be9f8d9 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/ClusterSummaryView.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/ClusterSummaryView.java @@ -22,6 +22,7 @@ package com.gluster.storage.management.console.views; import java.util.List; +import org.eclipse.jface.fieldassist.ControlDecoration; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; @@ -64,7 +65,6 @@ import com.gluster.storage.management.core.model.Server.SERVER_STATUS; import com.gluster.storage.management.core.model.ServerStats; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.TaskInfo; -import com.gluster.storage.management.core.utils.NumberUtil; /** * @@ -229,18 +229,17 @@ public class ClusterSummaryView extends ViewPart { double totalDiskSpace = cluster.getTotalDiskSpace(); double diskSpaceInUse = cluster.getDiskSpaceInUse(); - Double[] values = new Double[] { diskSpaceInUse, totalDiskSpace - diskSpaceInUse }; + Double[] values = new Double[] { diskSpaceInUse / 1024, (totalDiskSpace - diskSpaceInUse) / 1024 }; createDiskSpaceChart(section, values); } private void createDiskSpaceChart(Composite section, Double[] values) { - String[] categories = new String[] { "Used Space: " + NumberUtil.formatNumber((values[0] / 1024)) + " GB", - "Free Space: " + NumberUtil.formatNumber((values[1] / 1024)) + " GB" }; + String[] categories = new String[] { "Used Space (GB)", "Free Space (GB)" }; ChartViewerComposite chartViewerComposite = new ChartViewerComposite(section, SWT.NONE, categories, values); GridData data = new GridData(SWT.FILL, SWT.FILL, false, false); data.widthHint = 400; - data.heightHint = 170; + data.heightHint = 180; data.verticalAlignment = SWT.CENTER; chartViewerComposite.setLayoutData(data); } @@ -261,6 +260,11 @@ public class ClusterSummaryView extends ViewPart { private void addAlertLabel(Composite section, Alert alert) { CLabel lblAlert = new CLabel(section, SWT.FLAT); + GridData layoutData = new GridData(); + layoutData.widthHint = 400; + layoutData.horizontalIndent = 20; + lblAlert.setLayoutData(layoutData); + Image alertImage = null; switch (alert.getType()) { case OFFLINE_VOLUME_BRICKS_ALERT: @@ -278,9 +282,13 @@ public class ClusterSummaryView extends ViewPart { case CPU_USAGE_ALERT: alertImage = guiHelper.getImage(IImageKeys.SERVER_WARNING_22x22); break; + case OFFLINE_VOLUME_ALERT: + alertImage = guiHelper.getImage(IImageKeys.VOLUME_OFFLINE_22x22); + break; } - lblAlert.setImage(alertImage); lblAlert.setText(alert.getMessage()); + ControlDecoration dec = new ControlDecoration(lblAlert, SWT.LEFT); + dec.setImage(alertImage); lblAlert.redraw(); } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java index b5604643..376345e6 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java @@ -22,6 +22,7 @@ package com.gluster.storage.management.console.views; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; @@ -102,6 +103,7 @@ public class VolumesSummaryView extends ViewPart { public void volumeChanged(Volume volume, Event event) { super.volumeChanged(volume, event); updateSummarySection(); + updateAlertSection(); } private void updateSummarySection() { @@ -140,6 +142,11 @@ public class VolumesSummaryView extends ViewPart { guiHelper.clearSection(tasksSection); populateTasks(); } + + private void updateAlertSection() { + guiHelper.clearSection(alertsSection); + populateAlertSection(); + } }; GlusterDataModelManager.getInstance().addClusterListener(clusterListener); } @@ -166,7 +173,8 @@ public class VolumesSummaryView extends ViewPart { private void populateAlertSection() { for (Alert alert : cluster.getAlerts()) { - if (alert.getType() == Alert.ALERT_TYPES.OFFLINE_VOLUME_BRICKS_ALERT) { + if (alert.getType() == Alert.ALERT_TYPES.OFFLINE_VOLUME_BRICKS_ALERT + || alert.getType() == Alert.ALERT_TYPES.OFFLINE_VOLUME_ALERT) { addAlertLabel(alertsSection, alert); } } @@ -176,8 +184,17 @@ public class VolumesSummaryView extends ViewPart { private void addAlertLabel(Composite section, Alert alert) { CLabel lblAlert = new CLabel(section, SWT.NONE); - lblAlert.setImage((alert.getType() == Alert.ALERT_TYPES.DISK_USAGE_ALERT) ? guiHelper - .getImage(IImageKeys.LOW_DISK_SPACE_22x22) : guiHelper.getImage(IImageKeys.BRICK_OFFLINE_22x22)); + + Image alertImage = null; + switch (alert.getType()) { + case OFFLINE_VOLUME_BRICKS_ALERT: + alertImage = guiHelper.getImage(IImageKeys.BRICK_OFFLINE_22x22); + break; + case OFFLINE_VOLUME_ALERT: + alertImage = guiHelper.getImage(IImageKeys.VOLUME_OFFLINE_22x22); + break; + } + lblAlert.setImage(alertImage); lblAlert.setText(alert.getMessage()); lblAlert.redraw(); } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/AbstractTableViewerPage.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/AbstractTableViewerPage.java index 06b9ed95..c80740f3 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/AbstractTableViewerPage.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/AbstractTableViewerPage.java @@ -28,17 +28,21 @@ import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchPart; @@ -49,6 +53,7 @@ import org.eclipse.ui.forms.widgets.Hyperlink; import com.gluster.storage.management.console.GlusterDataModelManager; import com.gluster.storage.management.console.utils.GUIHelper; +import com.gluster.storage.management.console.utils.TableViewerComparator; import com.gluster.storage.management.core.model.ClusterListener; public abstract class AbstractTableViewerPage<T> extends Composite implements ISelectionListener { @@ -223,8 +228,32 @@ public abstract class AbstractTableViewerPage<T> extends Composite implements IS // Create a case insensitive filter for the table viewer using the filter text field guiHelper.createFilter(tableViewer, filterText, false); + + tableViewer.setComparator(createViewerComparator()); + for (int columnIndex = 0; columnIndex < tableViewer.getTable().getColumnCount(); columnIndex++) { + TableColumn column = tableViewer.getTable().getColumn(columnIndex); + column.addSelectionListener(getColumnSelectionAdapter(column, columnIndex)); + } + } + + private SelectionAdapter getColumnSelectionAdapter(final TableColumn column, final int columnIndex) { + return new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + ViewerComparator viewerComparator = tableViewer.getComparator(); + if(viewerComparator instanceof TableViewerComparator) { + TableViewerComparator comparator = (TableViewerComparator)viewerComparator; + comparator.setColumn(columnIndex); + tableViewer.getTable().setSortDirection(comparator.getDirection()); + tableViewer.getTable().setSortColumn(column); + tableViewer.refresh(); + } + } + }; } + protected abstract ViewerComparator createViewerComparator(); + /* (non-Javadoc) * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) */ diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/BricksPage.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/BricksPage.java index 5d526c32..674074c3 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/BricksPage.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/BricksPage.java @@ -25,6 +25,7 @@ import java.util.Map; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; @@ -114,4 +115,9 @@ public class BricksPage extends AbstractTableViewerPage<Brick> { protected List<Brick> getAllEntities() { return bricks; } + + @Override + protected ViewerComparator createViewerComparator() { + return null; + } }
\ No newline at end of file diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/GlusterServersPage.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/GlusterServersPage.java index 8be17b24..3ef05a2a 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/GlusterServersPage.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/GlusterServersPage.java @@ -24,6 +24,7 @@ import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; @@ -32,6 +33,7 @@ import org.eclipse.ui.IWorkbenchSite; import com.gluster.storage.management.console.EntityGroupContentProvider; import com.gluster.storage.management.console.GlusterServerTableLabelProvider; +import com.gluster.storage.management.console.utils.TableViewerComparator; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.model.ClusterListener; import com.gluster.storage.management.core.model.DefaultClusterListener; @@ -54,6 +56,11 @@ public class GlusterServersPage extends AbstractTableViewerPage<GlusterServer> { super(site, parent, style, true, true, servers); this.glusterServers = servers.getEntities(); } + + @Override + protected ViewerComparator createViewerComparator() { + return new TableViewerComparator(); + } @Override protected ClusterListener createClusterListener() { diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/ServersPage.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/ServersPage.java index 99945b31..d97827c6 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/ServersPage.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/ServersPage.java @@ -24,6 +24,7 @@ import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; @@ -128,4 +129,10 @@ public class ServersPage extends AbstractTableViewerPage<Server> { TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout(); tableColumnLayout.setColumnData(column, new ColumnWeightData(weight)); } + + @Override + protected ViewerComparator createViewerComparator() { + // TODO Auto-generated method stub + return null; + } } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/TasksPage.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/TasksPage.java index d54b501d..c166af0f 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/TasksPage.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/TasksPage.java @@ -27,6 +27,7 @@ import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; @@ -141,4 +142,10 @@ public class TasksPage extends AbstractTableViewerPage<TaskInfo> { } } } + + @Override + protected ViewerComparator createViewerComparator() { + // TODO Auto-generated method stub + return null; + } } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/VolumesPage.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/VolumesPage.java index 01d3e7b0..484f91b0 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/VolumesPage.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/VolumesPage.java @@ -24,6 +24,7 @@ import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; @@ -125,4 +126,10 @@ public class VolumesPage extends AbstractTableViewerPage<Volume> { protected List<Volume> getAllEntities() { return volumes; } + + @Override + protected ViewerComparator createViewerComparator() { + // TODO Auto-generated method stub + return null; + } } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java index 22d7e3dc..ea0e723f 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java @@ -86,6 +86,7 @@ public class RESTConstants { public static final String FORM_PARAM_FORCED_DATA_MIGRATE = "forcedDataMigrate"; public static final String FORM_PARAM_OLD_PASSWORD = "oldPassword"; public static final String FORM_PARAM_NEW_PASSWORD = "newPassword"; + public static final String FORM_PARAM_FORCE = "force"; public static final String PATH_PARAM_FORMAT = "format"; public static final String PATH_PARAM_VOLUME_NAME = "volumeName"; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java index a29c150b..ceb3e77e 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java @@ -5,11 +5,11 @@ import org.eclipse.osgi.internal.signedcontent.Base64; public class Alert extends Entity { public enum ALERT_TYPES { - CPU_USAGE_ALERT, MEMORY_USAGE_ALERT, DISK_USAGE_ALERT, OFFLINE_VOLUME_BRICKS_ALERT, OFFLINE_SERVERS_ALERT + CPU_USAGE_ALERT, MEMORY_USAGE_ALERT, DISK_USAGE_ALERT, OFFLINE_VOLUME_BRICKS_ALERT, OFFLINE_SERVERS_ALERT, OFFLINE_VOLUME_ALERT }; public static final String[] ALERT_TYPE_STR = { "High CPU Usage", "High Memory Usage", "Low Disk Space", - "Offline Brick", "Offline Server" }; + "Offline Brick", "Offline Server", "Offline Volume" }; // protected String id; protected ALERT_TYPES type; diff --git a/src/com.gluster.storage.management.gateway.scripts/src/backend/get_server_details.py b/src/com.gluster.storage.management.gateway.scripts/src/backend/get_server_details.py index b3181111..be1e38e6 100755 --- a/src/com.gluster.storage.management.gateway.scripts/src/backend/get_server_details.py +++ b/src/com.gluster.storage.management.gateway.scripts/src/backend/get_server_details.py @@ -44,7 +44,10 @@ def getDiskDom(): raidDiskTag.appendChild(diskDom.createTag("interface")) raidDiskTag.appendChild(diskDom.createTag("fsVersion")) raidDiskTag.appendChild(diskDom.createTag("size", diskInfo[raidDiskName]['Size'] / 1024.0)) - raidDiskTag.appendChild(diskDom.createTag("spaceInUse", diskInfo[raidDiskName]['SpaceInUse'])) + if not diskInfo[raidDiskName]['SpaceInUse']: + raidDiskTag.appendChild(diskDom.createTag("spaceInUse", None)) + else: + raidDiskTag.appendChild(diskDom.createTag("spaceInUse", diskInfo[raidDiskName]['SpaceInUse'] / 1024.0)) raidDiskTag.appendChild(raidDisksTag) disksTag.appendChild(raidDiskTag) for raidMember in raidDisk['Member']: @@ -70,7 +73,10 @@ def getDiskDom(): diskTag.appendChild(diskDom.createTag("fsType", diskInfo[raidMember]["FsType"])) diskTag.appendChild(diskDom.createTag("fsVersion", diskInfo[raidMember]["FsVersion"])) diskTag.appendChild(diskDom.createTag("size", diskInfo[raidMember]["Size"] / 1024.0)) - diskTag.appendChild(diskDom.createTag("spaceInUse", diskInfo[raidMember]["SpaceInUse"])) + if not diskInfo[raidMember]["SpaceInUse"]: + diskTag.appendChild(diskDom.createTag("spaceInUse", None)) + else: + diskTag.appendChild(diskDom.createTag("spaceInUse", diskInfo[raidMember]["SpaceInUse"] / 1024.0)) raidDisksTag.appendChild(diskTag) del diskInfo[raidMember] continue @@ -90,7 +96,10 @@ def getDiskDom(): diskTag.appendChild(diskDom.createTag("fsType", item["FsType"])) diskTag.appendChild(diskDom.createTag("fsVersion", item["FsVersion"])) diskTag.appendChild(diskDom.createTag("size", item["Size"] / 1024.0)) - diskTag.appendChild(diskDom.createTag("spaceInUse", item["SpaceInUse"])) + if not item["SpaceInUse"]: + diskTag.appendChild(diskDom.createTag("spaceInUse", None)) + else: + diskTag.appendChild(diskDom.createTag("spaceInUse", item["SpaceInUse"] / 1024.0)) partitionsTag = diskDom.createTag("partitions", None) diskTag.appendChild(partitionsTag) raidDisksTag.appendChild(diskTag) @@ -110,7 +119,10 @@ def getDiskDom(): partitionTag.appendChild(diskDom.createTag("type", "UNKNOWN")) partitionTag.appendChild(diskDom.createTag("mountPoint", item['Partitions'][raidMember]['MountPoint'])) partitionTag.appendChild(diskDom.createTag("size", item['Partitions'][raidMember]["Size"] / 1024.0)) - partitionTag.appendChild(diskDom.createTag("spaceInUse", item['Partitions'][raidMember]["SpaceInUse"])) + if not item['Partitions'][raidMember]["SpaceInUse"]: + partitionTag.appendChild(diskDom.createTag("spaceInUse", None)) + else: + partitionTag.appendChild(diskDom.createTag("spaceInUse", item['Partitions'][raidMember]["SpaceInUse"] / 1024.0)) diskTagDict[disk]['partitionsTag'].appendChild(partitionTag) # deleting partition entry of a raid member from diskInfo (item['Partitions']) del item['Partitions'][raidMember] @@ -140,7 +152,10 @@ def getDiskDom(): diskTag.appendChild(diskDom.createTag("fsVersion", value["FsVersion"])) diskTag.appendChild(diskDom.createTag("mountPoint", value["MountPoint"])) diskTag.appendChild(diskDom.createTag("size", value["Size"] / 1024.0)) - diskTag.appendChild(diskDom.createTag("spaceInUse", value["SpaceInUse"])) + if not value["SpaceInUse"]: + diskTag.appendChild(diskDom.createTag("spaceInUse", None)) + else: + diskTag.appendChild(diskDom.createTag("spaceInUse", value["SpaceInUse"] / 1024.0)) partitionsTag = diskDom.createTag("partitions", None) diskTag.appendChild(partitionsTag) for partName, partValues in value['Partitions'].iteritems(): @@ -156,7 +171,10 @@ def getDiskDom(): partitionTag.appendChild(diskDom.createTag("type", "UNKNOWN")) partitionTag.appendChild(diskDom.createTag("mountPoint", partValues['MountPoint'])) partitionTag.appendChild(diskDom.createTag("size", partValues["Size"] / 1024.0)) - partitionTag.appendChild(diskDom.createTag("spaceInUse", partValues["SpaceInUse"])) + if not partValues["SpaceInUse"]: + partitionTag.appendChild(diskDom.createTag("spaceInUse", None)) + else: + partitionTag.appendChild(diskDom.createTag("spaceInUse", partValues["SpaceInUse"] / 1024.0)) partitionsTag.appendChild(partitionTag) continue disksTag.appendChild(diskTag) diff --git a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/resources/v1_0/VolumesResource.java b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/resources/v1_0/VolumesResource.java index 4303aa63..14e7be8c 100644 --- a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/resources/v1_0/VolumesResource.java +++ b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/resources/v1_0/VolumesResource.java @@ -37,6 +37,7 @@ import static com.gluster.storage.management.core.constants.RESTConstants.FORM_P import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VOLUME_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VOLUME_OPTIONS; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VOLUME_TYPE; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_FORCE; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_VOLUME_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_BRICKS; @@ -195,7 +196,7 @@ public class VolumesResource extends AbstractResource { @FormParam(FORM_PARAM_MIGRATE_DATA) Boolean isMigrateData, @FormParam(FORM_PARAM_FORCED_DATA_MIGRATE) Boolean isForcedDataMigrate, @FormParam(FORM_PARAM_CIFS_ENABLE) Boolean enableCifs, @FormParam(FORM_PARAM_CIFS_USERS) String cifsUsers, - @FormParam(FORM_PARAM_BRICKS) String bricks) { + @FormParam(FORM_PARAM_BRICKS) String bricks, @FormParam(FORM_PARAM_FORCE) Boolean force) { if (clusterName == null || clusterName.isEmpty()) { throw new GlusterValidationException("Cluster name must not be empty!"); } @@ -234,7 +235,10 @@ public class VolumesResource extends AbstractResource { List<String> brickList = Arrays.asList(bricks.split(",")); volumeService.logRotate(clusterName, volumeName, brickList); } else { - volumeService.performVolumeOperation(clusterName, volumeName, operation); + if (force == null) { + force = false; + } + volumeService.performVolumeOperation(clusterName, volumeName, operation, force); } return noContentResponse(); } catch(Exception e) { diff --git a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/Gluster323InterfaceService.java b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/Gluster323InterfaceService.java index fba64352..9b093baf 100644 --- a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/Gluster323InterfaceService.java +++ b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/Gluster323InterfaceService.java @@ -79,16 +79,17 @@ public class Gluster323InterfaceService extends AbstractGlusterInterface { * @see com.gluster.storage.management.gateway.utils.GlusterInterface#startVolume(java.lang.String, java.lang.String) */ @Override - public void startVolume(String volumeName, String knownServer) { - serverUtil.executeOnServer(knownServer, "gluster volume start " + volumeName); + public void startVolume(String volumeName, String knownServer, Boolean force) { + serverUtil.executeOnServer(knownServer, "gluster volume start " + volumeName + ((force) ? " force" : "")); } /* (non-Javadoc) * @see com.gluster.storage.management.gateway.utils.GlusterInterface#stopVolume(java.lang.String, java.lang.String) */ @Override - public void stopVolume(String volumeName, String knownServer) { - serverUtil.executeOnServer(knownServer, "gluster --mode=script volume stop " + volumeName); + public void stopVolume(String volumeName, String knownServer, Boolean force) { + serverUtil.executeOnServer(knownServer, "gluster --mode=script volume stop " + volumeName + + ((force) ? " force" : "")); } /* (non-Javadoc) diff --git a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/GlusterInterface.java b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/GlusterInterface.java index 2df24497..c282bb45 100644 --- a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/GlusterInterface.java +++ b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/GlusterInterface.java @@ -52,8 +52,12 @@ public interface GlusterInterface { * @param serverName * Server on which the Gluster command is to be executed. This server must be part of the cluster to * which the volume belongs. + * @param force + * Flag indicating whether the "force" option should be used for starting the Volume. This is typically + * used when Volume is already started, but at least one of its bricks is offline, and results in + * bringing up the offline bricks. */ - public abstract void startVolume(String volumeName, String serverName); + public abstract void startVolume(String volumeName, String serverName, Boolean force); /** * Stops the given volume by executing appropriate Gluster command on given server. @@ -63,8 +67,12 @@ public interface GlusterInterface { * @param serverName * Server on which the Gluster command is to be executed. This server must be part of the cluster to * which the volume belongs. + * @param force + * Flag indicating whether the Volume should be stopped forcefully. This is typically used if the regular + * stop option fails because of issues like rebalance / brick migration / geo-replication being in + * progress. This results in forcefully stopping the volume, leaving the other processes intact. */ - public abstract void stopVolume(String volumeName, String serverName); + public abstract void stopVolume(String volumeName, String serverName, Boolean force); /** * Resets volume options on the given volume by executing appropriate Gluster command on given server. diff --git a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/GlusterInterfaceService.java b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/GlusterInterfaceService.java index 8d1760fd..4baca5d9 100644 --- a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/GlusterInterfaceService.java +++ b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/GlusterInterfaceService.java @@ -72,16 +72,16 @@ public class GlusterInterfaceService extends AbstractGlusterInterface { * @see com.gluster.storage.management.gateway.utils.GlusterInterface#startVolume(java.lang.String, java.lang.String) */ @Override - public void startVolume(String volumeName, String knownServer) { - getGlusterInterface(knownServer).startVolume(volumeName, knownServer); + public void startVolume(String volumeName, String knownServer, Boolean force) { + getGlusterInterface(knownServer).startVolume(volumeName, knownServer, force); } /* (non-Javadoc) * @see com.gluster.storage.management.gateway.utils.GlusterInterface#stopVolume(java.lang.String, java.lang.String) */ @Override - public void stopVolume(String volumeName, String knownServer) { - getGlusterInterface(knownServer).stopVolume(volumeName, knownServer); + public void stopVolume(String volumeName, String knownServer, Boolean force) { + getGlusterInterface(knownServer).stopVolume(volumeName, knownServer, force); } public void logRotate(String volumeName, List<String> brickList, String knownServer) { diff --git a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/VolumeService.java b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/VolumeService.java index df33d7ba..1a86b9cd 100644 --- a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/VolumeService.java +++ b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/VolumeService.java @@ -670,8 +670,8 @@ public class VolumeService { taskResource.getTask(clusterName, taskId).stop(); } - public void startVolume(String clusterName, GlusterServer onlineServer, Volume volume) { - glusterUtil.startVolume(volume.getName(), onlineServer.getName()); + public void startVolume(String clusterName, GlusterServer onlineServer, Volume volume, Boolean force) { + glusterUtil.startVolume(volume.getName(), onlineServer.getName(), force); // call the start_volume_cifs.py script only if the volume is cifs enabled if (volume.isCifsEnable()) { @@ -679,8 +679,8 @@ public class VolumeService { } } - public void stopVolume(String clusterName, GlusterServer onlineServer, Volume volume) { - glusterUtil.stopVolume(volume.getName(), onlineServer.getName()); + public void stopVolume(String clusterName, GlusterServer onlineServer, Volume volume, Boolean force) { + glusterUtil.stopVolume(volume.getName(), onlineServer.getName(), force); // call the stop_volume_cifs.py script only if the volume is cifs enabled if (volume.isCifsEnable()) { @@ -708,27 +708,28 @@ public class VolumeService { } } - public void performVolumeOperation(String clusterName, String volumeName, String operation) { + public void performVolumeOperation(String clusterName, String volumeName, String operation, Boolean force) { GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); try { if (onlineServer == null) { throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); } - performOperation(clusterName, volumeName, operation, onlineServer); + performOperation(clusterName, volumeName, operation, onlineServer, force); } catch (Exception e) { // check if online server has gone offline. If yes, try again one more time. if (e instanceof ConnectionException || serverUtil.isServerOnline(onlineServer) == false) { // online server has gone offline! try with a different one. onlineServer = clusterService.getNewOnlineServer(clusterName); - performOperation(clusterName, volumeName, operation, onlineServer); + performOperation(clusterName, volumeName, operation, onlineServer, force); } else { throw new GlusterRuntimeException(e.getMessage()); } } } - private void performOperation(String clusterName, String volumeName, String operation, GlusterServer onlineServer) { + private void performOperation(String clusterName, String volumeName, String operation, GlusterServer onlineServer, + Boolean force) { Volume volume = null; try { volume = getVolume(clusterName, volumeName); @@ -738,9 +739,9 @@ public class VolumeService { } if (operation.equals(TASK_START)) { - startVolume(clusterName, onlineServer, volume); + startVolume(clusterName, onlineServer, volume, force); } else if (operation.equals(TASK_STOP)) { - stopVolume(clusterName, onlineServer, volume); + stopVolume(clusterName, onlineServer, volume, force); } else { throw new GlusterValidationException("Invalid operation code [" + operation + "]"); } |