summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorShireesh Anjal <shireesh@gluster.com>2011-06-10 20:13:55 +0530
committerShireesh Anjal <shireesh@gluster.com>2011-06-10 20:13:55 +0530
commit84b76fc94d2591af6507da452b7cc1c4d240a1b8 (patch)
tree1255477004a3ddf2ecea5c4f23508ce39eada600 /src
parent26cdbc3ba32f8963b0ff533b2f19873c6ef11191 (diff)
Introduced select all/none links in discovered servers and gluster servers views, removed redundant classes and performed some refactoring.
Diffstat (limited to 'src')
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/EntityGroup.java13
-rw-r--r--src/com.gluster.storage.management.gui/plugin.xml2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java4
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/GlusterServerTableLabelProvider.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeOptionsTableLabelProvider.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java15
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java23
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java5
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterAdapterFactory.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/navigator/ClusterAdapterFactory.java)2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DisksView.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerDisksView.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerLogsView.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/NavigationTreeLabelDecorator.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/navigator/NavigationTreeLabelDecorator.java)2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/NavigationView.java1
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeBricksView.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeLogsView.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeOptionsView.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreator.java49
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactory.java32
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactoryImpl.java72
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractBricksPage.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/AbstractBricksPage.java)2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/AbstractDisksPage.java)2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java)137
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/BricksPage.java)2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/DisksPage.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/DisksPage.java)2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java126
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionKeyEditingSupport.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/OptionKeyEditingSupport.java)2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionValueEditingSupport.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/OptionValueEditingSupport.java)2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerDisksPage.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/ServerDisksPage.java)2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerLogsPage.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/ServerLogsPage.java)2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java144
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeLogsPage.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java)2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java (renamed from src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java)2
-rw-r--r--src/com.gluster.storage.management.server/WebContent/scripts/Protocol.py438
-rw-r--r--src/com.gluster.storage.management.server/WebContent/scripts/Utils.py705
-rw-r--r--src/com.gluster.storage.management.server/WebContent/scripts/XmlHandler.py346
40 files changed, 1782 insertions, 378 deletions
diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/EntityGroup.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/EntityGroup.java
index 0fc0f507..8e0311f5 100644
--- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/EntityGroup.java
+++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/EntityGroup.java
@@ -20,20 +20,21 @@ package com.gluster.storage.management.core.model;
import java.util.List;
-public class EntityGroup<T> extends Entity {
- private Class<? extends Entity> type;
+public class EntityGroup<T extends Entity> extends Entity {
+ private Class<T> type;
- public EntityGroup(String name, Class<? extends Entity> type, Cluster cluster) {
+ public EntityGroup(String name, Class<T> type, Cluster cluster) {
this(name, type, cluster, null);
}
- public EntityGroup(String name, Class<? extends Entity> type, Cluster cluster, List<T> entities) {
+ @SuppressWarnings("unchecked")
+ public EntityGroup(String name, Class<T> type, Cluster cluster, List<T> entities) {
super(name, cluster, (List<Entity>)entities);
this.type = type;
}
- public List<? extends Entity> getEntities() {
- return children;
+ public List<T> getEntities() {
+ return (List<T>)children;
}
public void setEntities(List<T> entities) {
diff --git a/src/com.gluster.storage.management.gui/plugin.xml b/src/com.gluster.storage.management.gui/plugin.xml
index 56f08793..af065b7d 100644
--- a/src/com.gluster.storage.management.gui/plugin.xml
+++ b/src/com.gluster.storage.management.gui/plugin.xml
@@ -1012,7 +1012,7 @@
point="org.eclipse.ui.decorators">
<decorator
adaptable="false"
- class="com.gluster.storage.management.gui.views.navigator.NavigationTreeLabelDecorator"
+ class="com.gluster.storage.management.gui.views.NavigationTreeLabelDecorator"
id="com.gluster.storage.management.gui.views.navigator.decorator"
label="Navigation Tree Decorator"
lightweight="true"
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java
index aeea7c90..2d64782b 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java
@@ -27,8 +27,8 @@ import com.gluster.storage.management.core.model.Disk;
import com.gluster.storage.management.core.model.Disk.DISK_STATUS;
import com.gluster.storage.management.core.utils.NumberUtil;
import com.gluster.storage.management.gui.utils.GUIHelper;
-import com.gluster.storage.management.gui.views.details.BricksPage.BRICK_TABLE_COLUMN_INDICES;
-import com.gluster.storage.management.gui.views.details.DisksPage.DISK_TABLE_COLUMN_INDICES;
+import com.gluster.storage.management.gui.views.pages.BricksPage.BRICK_TABLE_COLUMN_INDICES;
+import com.gluster.storage.management.gui.views.pages.DisksPage.DISK_TABLE_COLUMN_INDICES;
public class BrickTableLabelProvider extends TableLabelProviderAdapter {
private GUIHelper guiHelper = GUIHelper.getInstance();
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java
index c09331fa..c355ac50 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java
@@ -26,7 +26,7 @@ import com.gluster.storage.management.core.model.Disk;
import com.gluster.storage.management.core.model.Disk.DISK_STATUS;
import com.gluster.storage.management.core.utils.NumberUtil;
import com.gluster.storage.management.gui.utils.GUIHelper;
-import com.gluster.storage.management.gui.views.details.DisksPage.DISK_TABLE_COLUMN_INDICES;
+import com.gluster.storage.management.gui.views.pages.DisksPage.DISK_TABLE_COLUMN_INDICES;
public class DiskTableLabelProvider extends TableLabelProviderAdapter {
private GUIHelper guiHelper = GUIHelper.getInstance();
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/GlusterServerTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/GlusterServerTableLabelProvider.java
index 61e98cb8..03b2d978 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/GlusterServerTableLabelProvider.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/GlusterServerTableLabelProvider.java
@@ -24,7 +24,7 @@ import com.gluster.storage.management.core.model.GlusterServer;
import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS;
import com.gluster.storage.management.core.utils.NumberUtil;
import com.gluster.storage.management.gui.utils.GUIHelper;
-import com.gluster.storage.management.gui.views.details.GlusterServersPage.GLUSTER_SERVER_TABLE_COLUMN_INDICES;
+import com.gluster.storage.management.gui.views.pages.GlusterServersPage.GLUSTER_SERVER_TABLE_COLUMN_INDICES;
public class GlusterServerTableLabelProvider extends TableLabelProviderAdapter {
private GUIHelper guiHelper = GUIHelper.getInstance();
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java
index ecff0ca7..57a7b312 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java
@@ -27,7 +27,7 @@ import com.gluster.storage.management.core.model.Disk;
import com.gluster.storage.management.core.model.Disk.DISK_STATUS;
import com.gluster.storage.management.core.utils.NumberUtil;
import com.gluster.storage.management.gui.utils.GUIHelper;
-import com.gluster.storage.management.gui.views.details.ServerDisksPage.SERVER_DISK_TABLE_COLUMN_INDICES;
+import com.gluster.storage.management.gui.views.pages.ServerDisksPage.SERVER_DISK_TABLE_COLUMN_INDICES;
public class ServerDiskTableLabelProvider extends TableLabelProviderAdapter {
private GUIHelper guiHelper = GUIHelper.getInstance();
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java
index 396d1821..39eea7ba 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java
@@ -21,7 +21,7 @@ package com.gluster.storage.management.gui;
import com.gluster.storage.management.core.model.VolumeLogMessage;
import com.gluster.storage.management.core.utils.DateUtil;
-import com.gluster.storage.management.gui.views.details.VolumeLogsPage.LOG_TABLE_COLUMN_INDICES;
+import com.gluster.storage.management.gui.views.pages.VolumeLogsPage.LOG_TABLE_COLUMN_INDICES;
public class VolumeLogTableLabelProvider extends TableLabelProviderAdapter {
@Override
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeOptionsTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeOptionsTableLabelProvider.java
index cf1ceaf7..007c7adb 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeOptionsTableLabelProvider.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeOptionsTableLabelProvider.java
@@ -21,7 +21,7 @@ package com.gluster.storage.management.gui;
import java.util.Map.Entry;
import com.gluster.storage.management.gui.utils.GUIHelper;
-import com.gluster.storage.management.gui.views.details.VolumeOptionsPage.OPTIONS_TABLE_COLUMN_INDICES;
+import com.gluster.storage.management.gui.views.pages.VolumeOptionsPage.OPTIONS_TABLE_COLUMN_INDICES;
public class VolumeOptionsTableLabelProvider extends TableLabelProviderAdapter {
private GUIHelper guiHelper = GUIHelper.getInstance();
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java
index 4fd99cc7..67948fb8 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java
@@ -23,6 +23,7 @@ import java.util.Set;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
import com.gluster.storage.management.client.GlusterDataModelManager;
@@ -34,10 +35,11 @@ import com.gluster.storage.management.core.response.GlusterServerResponse;
import com.gluster.storage.management.gui.utils.GUIHelper;
public class AddServerAction extends AbstractActionDelegate {
+ private GUIHelper guiHelper = GUIHelper.getInstance();
+
@Override
protected void performAction(final IAction action) {
- Display.getDefault().asyncExec(new Runnable() {
-
+ final Runnable addServerThread = new Runnable() {
@Override
public void run() {
GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance();
@@ -49,6 +51,7 @@ public class AddServerAction extends AbstractActionDelegate {
String errMsg = "";
String partErrMsg = "";
for (Server server : selectedServers) {
+ guiHelper.setStatusMessage("Adding server [" + server.getName() + "]...");
GlusterServerResponse response = glusterServersClient.addServer(server);
Status status = response.getStatus();
if (status.isSuccess()) {
@@ -65,8 +68,16 @@ public class AddServerAction extends AbstractActionDelegate {
}
}
+ guiHelper.clearStatusMessage();
showStatusMessage(action.getDescription(), selectedServers, successServers, partSuccessServers, errMsg, partErrMsg);
}
+ };
+
+ BusyIndicator.showWhile(Display.getDefault(), new Runnable() {
+ @Override
+ public void run() {
+ Display.getDefault().asyncExec(addServerThread);
+ }
});
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java
index f8f611fb..83489c37 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java
@@ -18,7 +18,6 @@
*******************************************************************************/
package com.gluster.storage.management.gui.actions;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -28,29 +27,31 @@ import java.util.Set;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.PlatformUI;
import com.gluster.storage.management.client.GlusterDataModelManager;
import com.gluster.storage.management.client.GlusterServersClient;
import com.gluster.storage.management.core.constants.CoreConstants;
-import com.gluster.storage.management.core.model.Brick;
-import com.gluster.storage.management.core.model.Cluster;
import com.gluster.storage.management.core.model.GlusterServer;
import com.gluster.storage.management.core.model.Status;
-import com.gluster.storage.management.core.model.Volume;
import com.gluster.storage.management.gui.utils.GUIHelper;
+import com.gluster.storage.management.gui.views.NavigationView;
public class RemoveServerAction extends AbstractActionDelegate {
private GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance();
+ private GUIHelper guiHelper = GUIHelper.getInstance();
@Override
protected void performAction(final IAction action) {
- Display.getDefault().asyncExec(new Runnable() {
+ final Runnable removeServerThread = new Runnable() {
@Override
public void run() {
final String actionDesc = action.getDescription();
- Set<GlusterServer> selectedServers = GUIHelper.getInstance().getSelectedEntities(getWindow(),
+ Set<GlusterServer> selectedServers = guiHelper.getSelectedEntities(getWindow(),
GlusterServer.class);
if (!validate(action, selectedServers)) {
@@ -66,6 +67,8 @@ public class RemoveServerAction extends AbstractActionDelegate {
Set<GlusterServer> successServers = new HashSet<GlusterServer>();
String errMsg = "";
for (GlusterServer server : selectedServers) {
+ guiHelper.setStatusMessage("Removing server [" + server.getName() + "]...");
+
GlusterServersClient client = new GlusterServersClient();
Status status = client.removeServer(server.getName());
if (status.isSuccess()) {
@@ -77,8 +80,16 @@ public class RemoveServerAction extends AbstractActionDelegate {
}
}
+ guiHelper.clearStatusMessage();
showStatusMessage(action.getDescription(), selectedServers, successServers, errMsg);
}
+ };
+
+ BusyIndicator.showWhile(Display.getDefault(), new Runnable() {
+ @Override
+ public void run() {
+ Display.getDefault().asyncExec(removeServerThread);
+ }
});
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java
index 9e2ec9e0..ac29ecf0 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java
@@ -290,15 +290,16 @@ public class GUIHelper {
final String tooltipMessage = "Start typing to filter table contents.";
final Text filterText = toolkit.createText(parent, "", SWT.FLAT);
- GridData data = new GridData(SWT.LEFT, SWT.CENTER, false, false);
+ GridData data = new GridData(SWT.RIGHT, SWT.CENTER, false, false);
data.widthHint = 300;
filterText.setLayoutData(data);
- ControlDecoration searchDecoration = new ControlDecoration(filterText, SWT.RIGHT);
+ ControlDecoration searchDecoration = new ControlDecoration(filterText, SWT.LEFT);
searchDecoration.setImage(getImage(IImageKeys.SEARCH));
searchDecoration.show();
searchDecoration.setShowHover(true);
searchDecoration.setDescriptionText(tooltipMessage);
+ searchDecoration.setMarginWidth(5);
filterText.setToolTipText(tooltipMessage);
return filterText;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/navigator/ClusterAdapterFactory.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterAdapterFactory.java
index d7ef44ac..95c16a3c 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/navigator/ClusterAdapterFactory.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterAdapterFactory.java
@@ -16,7 +16,7 @@
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
-package com.gluster.storage.management.gui.views.navigator;
+package com.gluster.storage.management.gui.views;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.jface.resource.ImageDescriptor;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DisksView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DisksView.java
index 260d0d4c..0910c080 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DisksView.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DisksView.java
@@ -11,7 +11,7 @@ import com.gluster.storage.management.core.model.Disk;
import com.gluster.storage.management.core.model.EntityGroup;
import com.gluster.storage.management.core.model.GlusterServer;
import com.gluster.storage.management.gui.utils.GUIHelper;
-import com.gluster.storage.management.gui.views.details.DisksPage;
+import com.gluster.storage.management.gui.views.pages.DisksPage;
public class DisksView extends ViewPart {
public static final String ID = DisksView.class.getName();
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerDisksView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerDisksView.java
index 624d968d..2a240706 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerDisksView.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerDisksView.java
@@ -26,7 +26,7 @@ import org.eclipse.ui.part.ViewPart;
import com.gluster.storage.management.core.model.GlusterServer;
import com.gluster.storage.management.gui.utils.GUIHelper;
-import com.gluster.storage.management.gui.views.details.ServerDisksPage;
+import com.gluster.storage.management.gui.views.pages.ServerDisksPage;
public class GlusterServerDisksView extends ViewPart {
public static final String ID = GlusterServerDisksView.class.getName();
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerLogsView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerLogsView.java
index acc8144d..84568ca6 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerLogsView.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerLogsView.java
@@ -26,7 +26,7 @@ import org.eclipse.ui.part.ViewPart;
import com.gluster.storage.management.core.model.GlusterServer;
import com.gluster.storage.management.gui.utils.GUIHelper;
-import com.gluster.storage.management.gui.views.details.ServerLogsPage;
+import com.gluster.storage.management.gui.views.pages.ServerLogsPage;
public class GlusterServerLogsView extends ViewPart {
public static final String ID = GlusterServerLogsView.class.getName();
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java
index dfaf904a..05bf6778 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java
@@ -31,7 +31,7 @@ import com.gluster.storage.management.core.model.Entity;
import com.gluster.storage.management.core.model.EntityGroup;
import com.gluster.storage.management.core.model.GlusterServer;
import com.gluster.storage.management.gui.utils.GUIHelper;
-import com.gluster.storage.management.gui.views.details.GlusterServersPage;
+import com.gluster.storage.management.gui.views.pages.GlusterServersPage;
/**
* @author root
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/navigator/NavigationTreeLabelDecorator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/NavigationTreeLabelDecorator.java
index 4cdc2e66..241b6967 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/navigator/NavigationTreeLabelDecorator.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/NavigationTreeLabelDecorator.java
@@ -16,7 +16,7 @@
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
-package com.gluster.storage.management.gui.views.navigator;
+package com.gluster.storage.management.gui.views;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.ILabelProviderListener;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/NavigationView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/NavigationView.java
index a5da2f62..f737ea9d 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/NavigationView.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/NavigationView.java
@@ -41,7 +41,6 @@ import com.gluster.storage.management.core.model.Event;
import com.gluster.storage.management.core.model.GlusterDataModel;
import com.gluster.storage.management.core.model.Volume;
import com.gluster.storage.management.gui.toolbar.GlusterToolbarManager;
-import com.gluster.storage.management.gui.views.navigator.ClusterAdapterFactory;
public class NavigationView extends ViewPart implements ISelectionListener {
public static final String ID = NavigationView.class.getName();
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeBricksView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeBricksView.java
index e6b9bec3..712882ee 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeBricksView.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeBricksView.java
@@ -7,7 +7,7 @@ import org.eclipse.ui.part.ViewPart;
import com.gluster.storage.management.client.GlusterDataModelManager;
import com.gluster.storage.management.core.model.Volume;
import com.gluster.storage.management.gui.utils.GUIHelper;
-import com.gluster.storage.management.gui.views.details.BricksPage;
+import com.gluster.storage.management.gui.views.pages.BricksPage;
public class VolumeBricksView extends ViewPart {
public static final String ID = VolumeBricksView.class.getName();
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeLogsView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeLogsView.java
index b6c98ad3..89c343d7 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeLogsView.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeLogsView.java
@@ -6,7 +6,7 @@ import org.eclipse.ui.part.ViewPart;
import com.gluster.storage.management.core.model.Volume;
import com.gluster.storage.management.gui.utils.GUIHelper;
-import com.gluster.storage.management.gui.views.details.VolumeLogsPage;
+import com.gluster.storage.management.gui.views.pages.VolumeLogsPage;
public class VolumeLogsView extends ViewPart {
VolumeLogsPage logsPage;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeOptionsView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeOptionsView.java
index e8695737..0780cf6a 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeOptionsView.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeOptionsView.java
@@ -6,7 +6,7 @@ import org.eclipse.ui.part.ViewPart;
import com.gluster.storage.management.core.model.Volume;
import com.gluster.storage.management.gui.utils.GUIHelper;
-import com.gluster.storage.management.gui.views.details.VolumeOptionsPage;
+import com.gluster.storage.management.gui.views.pages.VolumeOptionsPage;
public class VolumeOptionsView extends ViewPart {
public static final String ID = VolumeOptionsView.class.getName();
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreator.java
deleted file mode 100644
index 1f5f8a15..00000000
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreator.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*******************************************************************************
- * 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.gui.views.details;
-
-import org.eclipse.swt.widgets.TabFolder;
-import org.eclipse.ui.IWorkbenchSite;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-
-import com.gluster.storage.management.core.model.Entity;
-
-/**
- * For every entity that can be selected from the navigation view (cluster tree), a set of tabs are created on the
- * details view. Each entity has a corresponding tab creator that creates these tabs. These tab creators must implement
- * this interface.
- * <p>
- * <b>Important:</b> Tab creators are cached for performance reasons. Hence they should not store any state information
- * in class level variables.
- */
-public interface TabCreator {
- /**
- * Creates tabs for the given entity
- *
- * @param entity
- * Entity for which tabs are to be created
- * @param tabFolder
- * The tab folder in which the tabs are to be created
- * @param toolkit
- * The form toolkit that can be used for create components using Forms API
- * @param site
- * The workbench site that can be used to register as a selection provider
- */
- public void createTabs(Entity entity, TabFolder tabFolder, FormToolkit toolkit, IWorkbenchSite site);
-}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactory.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactory.java
deleted file mode 100644
index f5098af5..00000000
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactory.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*******************************************************************************
- * 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.gui.views.details;
-
-import com.gluster.storage.management.core.model.Entity;
-
-/**
- * Interface for tab creator factory.
- */
-public interface TabCreatorFactory {
- /**
- * @param entity The entity for which tab creator factory is to be returned
- * @return A tab creator factory for given entity
- */
- public TabCreator getTabCreator(Entity entity);
-}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactoryImpl.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactoryImpl.java
deleted file mode 100644
index 28d3d4aa..00000000
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactoryImpl.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*******************************************************************************
- * 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.gui.views.details;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.gluster.storage.management.core.exceptions.GlusterRuntimeException;
-import com.gluster.storage.management.core.model.Entity;
-import com.gluster.storage.management.core.model.EntityGroup;
-
-public class TabCreatorFactoryImpl implements TabCreatorFactory {
-
- private Map<String, TabCreator> tabCreatorCache = new HashMap<String, TabCreator>();
-
- /**
- * Returns tab creator for given entity. The logic is as follows: <br>
- * 1) Check if an tab creator is already created for the "class" of the entity. In case of {@link EntityGroup},
- * append the class name with entity type <br>
- * 2) If the tab creator is found in the cache, return it <br>
- * 3) If not found, create one by instantiating the class "<current package>.tabcreators.<class name>TabCreator".
- * Again, "class name" includes "entity type" in case of {@link EntityGroup} <br>
- * 4) Add the newly created tab creator to the cache and return it
- */
- @SuppressWarnings("rawtypes")
- @Override
- public TabCreator getTabCreator(Entity entity) {
- Class entityClass = entity.getClass();
- String key = entityClass.getSimpleName();
- if (entityClass == EntityGroup.class) {
- // If it's an entity group, add the entity type to the key
- key += ((EntityGroup) entity).getEntityType().getSimpleName();
- }
-
- TabCreator tabCreator = tabCreatorCache.get(key);
- if (tabCreator == null) {
- // Not created yet. Create one and add to the cache
- String className = getClass().getPackage().getName() + ".tabcreators." + key + "TabCreator";
- try {
- Class<TabCreator> creatorFactoryClass = (Class<TabCreator>) Class.forName(className);
- tabCreator = creatorFactoryClass.newInstance();
- tabCreatorCache.put(key, tabCreator);
- } catch (ClassNotFoundException e) {
- throw new GlusterRuntimeException("Could not load creator factory class [" + className + "]", e);
- } catch (InstantiationException e) {
- throw new GlusterRuntimeException("Could not create instance of creator factory class [" + className
- + "]", e);
- } catch (IllegalAccessException e) {
- throw new GlusterRuntimeException("Could not create instance of creator factory class [" + className
- + "]", e);
- }
- }
-
- return tabCreator;
- }
-}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/AbstractBricksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractBricksPage.java
index 412a1ef2..baa6cbe9 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/AbstractBricksPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractBricksPage.java
@@ -16,7 +16,7 @@
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
-package com.gluster.storage.management.gui.views.details;
+package com.gluster.storage.management.gui.views.pages;
import java.util.List;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/AbstractDisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java
index 105fa824..55283c7a 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/AbstractDisksPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java
@@ -16,7 +16,7 @@
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
-package com.gluster.storage.management.gui.views.details;
+package com.gluster.storage.management.gui.views.pages;
import java.util.List;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java
index 36f60998..a8a98bbd 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java
@@ -16,12 +16,16 @@
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
-package com.gluster.storage.management.gui.views.details;
+package com.gluster.storage.management.gui.views.pages;
+
+import java.util.List;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.CheckboxTableViewer;
-import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
@@ -33,50 +37,69 @@ 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.IWorkbenchSite;
+import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Hyperlink;
import com.gluster.storage.management.client.GlusterDataModelManager;
import com.gluster.storage.management.core.model.ClusterListener;
-import com.gluster.storage.management.core.model.DefaultClusterListener;
-import com.gluster.storage.management.core.model.EntityGroup;
-import com.gluster.storage.management.core.model.Event;
-import com.gluster.storage.management.core.model.GlusterServer;
-import com.gluster.storage.management.gui.EntityGroupContentProvider;
-import com.gluster.storage.management.gui.GlusterServerTableLabelProvider;
import com.gluster.storage.management.gui.utils.GUIHelper;
-public class GlusterServersPage extends Composite {
-
- private final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
- private CheckboxTableViewer tableViewer;
- private GUIHelper guiHelper = GUIHelper.getInstance();
+public abstract class AbstractTableViewerPage<T> extends Composite {
- public enum GLUSTER_SERVER_TABLE_COLUMN_INDICES {
- NAME, IP_ADDRESSES, NUM_OF_CPUS, TOTAL_MEMORY, TOTAL_DISK_SPACE, AVAILABLE_DISK_SPACE, STATUS // Removed PREFERRED_NETWORK
- };
+ protected final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
+ protected CheckboxTableViewer tableViewer;
+ protected GUIHelper guiHelper = GUIHelper.getInstance();
+ private Hyperlink linkAll, linkNone;
+ protected Composite parent;
- private static final String[] GLUSTER_SERVER_TABLE_COLUMN_NAMES = new String[] { "Name",
- "IP Address(es)", "Number\nof CPUs", "Total\nMemory (GB)", "Space (GB)", "Space\nAvailable (GB)", "Status" }; // Removed "Preferred\nNetwork",
-
- public GlusterServersPage(IWorkbenchSite site, final Composite parent, int style, EntityGroup<GlusterServer> servers) {
+ public AbstractTableViewerPage(IWorkbenchSite site, final Composite parent, int style, Object model) {
super(parent, style);
+ this.parent = parent;
toolkit.adapt(this);
toolkit.paintBordersFor(this);
setupPageLayout();
+
+ createCheckboxSelectionLinks();
+
Text filterText = guiHelper.createFilterText(toolkit, this);
+
setupServerTableViewer(site, filterText);
- tableViewer.setInput(servers);
+ tableViewer.setInput(model);
parent.layout(); // Important - this actually paints the table
createListeners(parent);
}
+ public void createCheckboxSelectionLinks() {
+ // create the "select all/none" links
+ toolkit.createLabel(this, "Select");
+ linkAll = toolkit.createHyperlink(this, "all", SWT.NONE);
+ linkAll.addHyperlinkListener(new HyperlinkAdapter() {
+ @Override
+ public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
+ tableViewer.setAllChecked(true);
+ tableViewer.setSelection(new StructuredSelection(getAllEntities()));
+ }
+ });
+
+ toolkit.createLabel(this, " / ");
+
+ linkNone = toolkit.createHyperlink(this, "none", SWT.NONE);
+ linkNone.addHyperlinkListener(new HyperlinkAdapter() {
+ @Override
+ public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
+ tableViewer.setAllChecked(false);
+ tableViewer.setSelection(null);
+ }
+ });
+ }
+
private void createListeners(final Composite parent) {
/**
* Ideally not required. However the table viewer is not getting laid out properly on performing
@@ -90,23 +113,7 @@ public class GlusterServersPage extends Composite {
}
});
- final ClusterListener clusterListener = new DefaultClusterListener() {
-
- @Override
- public void serverAdded(GlusterServer server) {
- tableViewer.refresh();
- }
-
- @Override
- public void serverRemoved(GlusterServer server) {
- tableViewer.refresh();
- }
-
- @Override
- public void serverChanged(GlusterServer server, Event event) {
- tableViewer.update(server, null);
- }
- };
+ final ClusterListener clusterListener = createClusterListener();
final GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance();
modelManager.addClusterListener(clusterListener);
@@ -119,12 +126,19 @@ public class GlusterServersPage extends Composite {
});
}
+ protected abstract ClusterListener createClusterListener();
+ protected abstract String[] getColumnNames();
+ protected abstract void setColumnProperties(Table table);
+ protected abstract IBaseLabelProvider getLabelProvider();
+ protected abstract IContentProvider getContentProvider();
+ protected abstract List<T> getAllEntities();
+
public void addDoubleClickListener(IDoubleClickListener listener) {
tableViewer.addDoubleClickListener(listener);
}
private void setupPageLayout() {
- final GridLayout layout = new GridLayout(1, false);
+ final GridLayout layout = new GridLayout(5, false);
layout.verticalSpacing = 10;
layout.marginTop = 10;
setLayout(layout);
@@ -134,26 +148,17 @@ public class GlusterServersPage extends Composite {
table.setHeaderVisible(true);
table.setLinesVisible(false);
- TableColumnLayout tableColumnLayout = guiHelper.createTableColumnLayout(table, GLUSTER_SERVER_TABLE_COLUMN_NAMES);
+ TableColumnLayout tableColumnLayout = guiHelper.createTableColumnLayout(table, getColumnNames());
parent.setLayout(tableColumnLayout);
- setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.NAME, SWT.CENTER, 100);
- setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.STATUS, SWT.CENTER, 70);
- // setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.PREFERRED_NETWORK, SWT.CENTER, 90);
- setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.NUM_OF_CPUS, SWT.CENTER, 90);
- //setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.CPU_USAGE, SWT.CENTER, 90);
- setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.TOTAL_MEMORY, SWT.CENTER, 90);
- //setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.MEMORY_IN_USE, SWT.CENTER, 90);
- setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.TOTAL_DISK_SPACE, SWT.CENTER, 90);
- setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.AVAILABLE_DISK_SPACE, SWT.CENTER, 90);
- //setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.DISK_SPACE_IN_USE, SWT.CENTER, 90);
+ setColumnProperties(table);
}
private CheckboxTableViewer createServerTableViewer(Composite parent) {
CheckboxTableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI);
- //TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI);
- tableViewer.setLabelProvider(new GlusterServerTableLabelProvider());
- tableViewer.setContentProvider(new EntityGroupContentProvider<GlusterServer>());
+
+ tableViewer.setLabelProvider(getLabelProvider());
+ tableViewer.setContentProvider(getContentProvider());
setupServerTable(parent, tableViewer.getTable());
@@ -164,6 +169,14 @@ public class GlusterServersPage extends Composite {
Composite tableViewerComposite = new Composite(this, SWT.NO);
tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL));
tableViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ GridData layoutData = new GridData();
+ layoutData.horizontalSpan=5;
+ layoutData.grabExcessHorizontalSpace = true;
+ layoutData.horizontalAlignment = SWT.FILL;
+ layoutData.verticalAlignment = SWT.FILL;
+ tableViewerComposite.setLayoutData(layoutData);
+
return tableViewerComposite;
}
@@ -178,20 +191,4 @@ public class GlusterServersPage extends Composite {
// Create a case insensitive filter for the table viewer using the filter text field
guiHelper.createFilter(tableViewer, filterText, false);
}
-
- /**
- * Sets properties for alignment and weight of given column of given table
- *
- * @param table
- * @param columnIndex
- * @param alignment
- * @param weight
- */
- public void setColumnProperties(Table table, GLUSTER_SERVER_TABLE_COLUMN_INDICES columnIndex, int alignment, int weight) {
- TableColumn column = table.getColumn(columnIndex.ordinal());
- column.setAlignment(alignment);
-
- TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout();
- tableColumnLayout.setColumnData(column, new ColumnWeightData(weight));
- }
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/BricksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java
index 51425174..a6bc6f94 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/BricksPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java
@@ -16,7 +16,7 @@
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
-package com.gluster.storage.management.gui.views.details;
+package com.gluster.storage.management.gui.views.pages;
import java.util.List;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/DisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/DisksPage.java
index 9076d498..1df74481 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/DisksPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/DisksPage.java
@@ -16,7 +16,7 @@
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
-package com.gluster.storage.management.gui.views.details;
+package com.gluster.storage.management.gui.views.pages;
import java.util.List;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java
new file mode 100644
index 00000000..efa2eaaa
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * 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.gui.views.pages;
+
+import java.util.List;
+
+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.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.IWorkbenchSite;
+
+import com.gluster.storage.management.core.model.ClusterListener;
+import com.gluster.storage.management.core.model.DefaultClusterListener;
+import com.gluster.storage.management.core.model.EntityGroup;
+import com.gluster.storage.management.core.model.Event;
+import com.gluster.storage.management.core.model.GlusterServer;
+import com.gluster.storage.management.gui.EntityGroupContentProvider;
+import com.gluster.storage.management.gui.GlusterServerTableLabelProvider;
+
+public class GlusterServersPage extends AbstractTableViewerPage<GlusterServer> {
+ private List<GlusterServer> glusterServers;
+
+ public enum GLUSTER_SERVER_TABLE_COLUMN_INDICES {
+ NAME, IP_ADDRESSES, NUM_OF_CPUS, TOTAL_MEMORY, TOTAL_DISK_SPACE, AVAILABLE_DISK_SPACE, STATUS // Removed PREFERRED_NETWORK
+ };
+
+ private static final String[] GLUSTER_SERVER_TABLE_COLUMN_NAMES = new String[] { "Name",
+ "IP Address(es)", "Number\nof CPUs", "Total\nMemory (GB)", "Space (GB)", "Space\nAvailable (GB)", "Status" }; // Removed "Preferred\nNetwork",
+
+ public GlusterServersPage(IWorkbenchSite site, final Composite parent, int style, final EntityGroup<GlusterServer> servers) {
+ super(site, parent, style, servers);
+ this.glusterServers = servers.getEntities();
+ }
+
+ @Override
+ protected ClusterListener createClusterListener() {
+ return new DefaultClusterListener() {
+
+ @Override
+ public void serverAdded(GlusterServer server) {
+ tableViewer.refresh();
+ }
+
+ @Override
+ public void serverRemoved(GlusterServer server) {
+ tableViewer.refresh();
+ }
+
+ @Override
+ public void serverChanged(GlusterServer server, Event event) {
+ tableViewer.update(server, null);
+ }
+ };
+ }
+
+ @Override
+ protected void setColumnProperties(Table table) {
+ setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.NAME, SWT.CENTER, 100);
+ setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.STATUS, SWT.CENTER, 70);
+ // setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.PREFERRED_NETWORK, SWT.CENTER, 90);
+ setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.NUM_OF_CPUS, SWT.CENTER, 90);
+ //setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.CPU_USAGE, SWT.CENTER, 90);
+ setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.TOTAL_MEMORY, SWT.CENTER, 90);
+ //setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.MEMORY_IN_USE, SWT.CENTER, 90);
+ setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.TOTAL_DISK_SPACE, SWT.CENTER, 90);
+ setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.AVAILABLE_DISK_SPACE, SWT.CENTER, 90);
+ //setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.DISK_SPACE_IN_USE, SWT.CENTER, 90);
+ }
+
+ @Override
+ protected IBaseLabelProvider getLabelProvider() {
+ return new GlusterServerTableLabelProvider();
+ }
+
+ @Override
+ protected IContentProvider getContentProvider() {
+ return new EntityGroupContentProvider<GlusterServer>();
+ }
+
+ @Override
+ protected String[] getColumnNames() {
+ return GLUSTER_SERVER_TABLE_COLUMN_NAMES;
+ }
+
+ @Override
+ protected List<GlusterServer> getAllEntities() {
+ return glusterServers;
+ }
+
+ /**
+ * Sets properties for alignment and weight of given column of given table
+ *
+ * @param table
+ * @param columnIndex
+ * @param alignment
+ * @param weight
+ */
+ public void setColumnProperties(Table table, GLUSTER_SERVER_TABLE_COLUMN_INDICES columnIndex, int alignment, int weight) {
+ TableColumn column = table.getColumn(columnIndex.ordinal());
+ column.setAlignment(alignment);
+
+ TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout();
+ tableColumnLayout.setColumnData(column, new ColumnWeightData(weight));
+ }
+}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/OptionKeyEditingSupport.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionKeyEditingSupport.java
index 27dc8d4b..87bd1154 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/OptionKeyEditingSupport.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionKeyEditingSupport.java
@@ -1,7 +1,7 @@
/**
*
*/
-package com.gluster.storage.management.gui.views.details;
+package com.gluster.storage.management.gui.views.pages;
import java.util.ArrayList;
import java.util.Iterator;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/OptionValueEditingSupport.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionValueEditingSupport.java
index ca222dd0..a5edd7cb 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/OptionValueEditingSupport.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionValueEditingSupport.java
@@ -1,7 +1,7 @@
/**
*
*/
-package com.gluster.storage.management.gui.views.details;
+package com.gluster.storage.management.gui.views.pages;
import java.util.List;
import java.util.Map.Entry;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/ServerDisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerDisksPage.java
index bace2af9..3621afe1 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/ServerDisksPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerDisksPage.java
@@ -16,7 +16,7 @@
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
-package com.gluster.storage.management.gui.views.details;
+package com.gluster.storage.management.gui.views.pages;
import java.util.List;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/ServerLogsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerLogsPage.java
index a499caf3..7cde38bb 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/ServerLogsPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerLogsPage.java
@@ -16,7 +16,7 @@
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
-package com.gluster.storage.management.gui.views.details;
+package com.gluster.storage.management.gui.views.pages;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java
index 20c3cbd4..48b8892c 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java
@@ -18,41 +18,28 @@
*******************************************************************************/
package com.gluster.storage.management.gui.views.pages;
+import java.util.List;
+
import org.eclipse.jface.layout.TableColumnLayout;
-import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
-import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.IContentProvider;
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.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.IWorkbenchSite;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import com.gluster.storage.management.client.GlusterDataModelManager;
import com.gluster.storage.management.core.model.ClusterListener;
import com.gluster.storage.management.core.model.DefaultClusterListener;
import com.gluster.storage.management.core.model.EntityGroup;
import com.gluster.storage.management.core.model.Server;
import com.gluster.storage.management.gui.EntityGroupContentProvider;
import com.gluster.storage.management.gui.ServerTableLabelProvider;
-import com.gluster.storage.management.gui.utils.GUIHelper;
-
-public class ServersPage extends Composite {
-
- private final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
- private CheckboxTableViewer tableViewer;
- private GUIHelper guiHelper = GUIHelper.getInstance();
+public class ServersPage extends AbstractTableViewerPage<Server> {
+ private List<Server> servers;
+
public enum SERVER_TABLE_COLUMN_INDICES {
NAME, IP_ADDRESSES, NUM_OF_DISKS, TOTAL_DISK_SPACE
};
@@ -67,39 +54,14 @@ public class ServersPage extends Composite {
// "Number\nof CPUs", "CPU\nUsage (%)", "Total\nMemory (GB)", "Memory\nIn Use (GB)",
// "Total Disk\n Space (GB)", "Disk Space\nin Use (GB)"};
- public ServersPage(final Composite parent, IWorkbenchSite site, EntityGroup<Server> servers) {
- super(parent, SWT.NONE);
-
- addDisposeListener(new DisposeListener() {
- public void widgetDisposed(DisposeEvent e) {
- toolkit.dispose();
- }
- });
-
- toolkit.adapt(this);
- toolkit.paintBordersFor(this);
-
- setupPageLayout();
- setupPage(site, servers);
- parent.layout(); // Important - this actually paints the table
-
- createListeners(parent);
+ public ServersPage(final Composite parent, IWorkbenchSite site, EntityGroup<Server> serversGroup) {
+ super(site, parent, SWT.NONE, serversGroup);
+ this.servers = serversGroup.getEntities();
}
- private void createListeners(final Composite parent) {
- /**
- * Ideally not required. However the table viewer is not getting laid out properly on performing
- * "maximize + restore" So this is a hack to make sure that the table is laid out again on re-size of the window
- */
- addPaintListener(new PaintListener() {
-
- @Override
- public void paintControl(PaintEvent e) {
- parent.layout();
- }
- });
-
- final ClusterListener clusterListener = new DefaultClusterListener() {
+ @Override
+ protected ClusterListener createClusterListener() {
+ return new DefaultClusterListener() {
@Override
public void discoveredServerRemoved(Server server) {
refreshViewer();
@@ -115,16 +77,6 @@ public class ServersPage extends Composite {
parent.update();
}
};
-
- final GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance();
- modelManager.addClusterListener(clusterListener);
- addDisposeListener(new DisposeListener() {
- @Override
- public void widgetDisposed(DisposeEvent e) {
- toolkit.dispose();
- modelManager.removeClusterListener(clusterListener);
- }
- });
}
public void setInput(EntityGroup<Server> servers) {
@@ -132,24 +84,8 @@ public class ServersPage extends Composite {
tableViewer.refresh();
}
- public void addDoubleClickListener(IDoubleClickListener listener) {
- tableViewer.addDoubleClickListener(listener);
- }
-
- private void setupPageLayout() {
- final GridLayout layout = new GridLayout(1, false);
- layout.verticalSpacing = 10;
- layout.marginTop = 10;
- setLayout(layout);
- }
-
- private void setupServerTable(Composite parent, Table table) {
- table.setHeaderVisible(true);
- table.setLinesVisible(false);
-
- TableColumnLayout tableColumnLayout = guiHelper.createTableColumnLayout(table, SERVER_TABLE_COLUMN_NAMES);
- parent.setLayout(tableColumnLayout);
-
+ @Override
+ protected void setColumnProperties(Table table) {
setColumnProperties(table, SERVER_TABLE_COLUMN_INDICES.NAME, SWT.CENTER, 70);
setColumnProperties(table, SERVER_TABLE_COLUMN_INDICES.IP_ADDRESSES, SWT.CENTER, 100);
setColumnProperties(table, SERVER_TABLE_COLUMN_INDICES.NUM_OF_DISKS, SWT.CENTER, 70);
@@ -160,40 +96,26 @@ public class ServersPage extends Composite {
// setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.MEMORY_IN_USE, SWT.CENTER, 90);
// setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.DISK_SPACE_IN_USE, SWT.CENTER, 90);
}
-
- private CheckboxTableViewer createServerTableViewer(Composite parent) {
- final CheckboxTableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI);
- // TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI);
- tableViewer.setLabelProvider(new ServerTableLabelProvider());
- tableViewer.setContentProvider(new EntityGroupContentProvider<Server>());
-
- setupServerTable(parent, tableViewer.getTable());
-
- // make sure that table selection is driven by checkbox selection
- guiHelper.configureCheckboxTableViewer(tableViewer);
-
- return tableViewer;
+
+ @Override
+ protected String[] getColumnNames() {
+ return SERVER_TABLE_COLUMN_NAMES;
}
-
- private Composite createTableViewerComposite() {
- Composite tableViewerComposite = new Composite(this, SWT.NONE);
- tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL));
- tableViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- return tableViewerComposite;
+
+ @Override
+ protected IBaseLabelProvider getLabelProvider() {
+ return new ServerTableLabelProvider();
}
-
- private void setupPage(IWorkbenchSite site, EntityGroup<Server> servers) {
- Text filterText = guiHelper.createFilterText(toolkit, this);
-
- Composite tableViewerComposite = createTableViewerComposite();
- tableViewer = createServerTableViewer(tableViewerComposite);
- site.setSelectionProvider(tableViewer);
-
- // Create a case insensitive filter for the table viewer using the filter text field
- guiHelper.createFilter(tableViewer, filterText, false);
-
- tableViewer.setInput(servers);
+
+ @Override
+ protected IContentProvider getContentProvider() {
+ return new EntityGroupContentProvider<Server>();
}
+
+ @Override
+ protected List<Server> getAllEntities() {
+ return servers;
+ }
/**
* Sets properties for alignment and weight of given column of given table
@@ -209,5 +131,5 @@ public class ServersPage extends Composite {
TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout();
tableColumnLayout.setColumnData(column, new ColumnWeightData(weight));
- }
+ }
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeLogsPage.java
index 9eb7357e..ab1b353d 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeLogsPage.java
@@ -16,7 +16,7 @@
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
-package com.gluster.storage.management.gui.views.details;
+package com.gluster.storage.management.gui.views.pages;
import java.util.Calendar;
import java.util.Date;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java
index 22d38e50..bd003f3b 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java
@@ -16,7 +16,7 @@
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
-package com.gluster.storage.management.gui.views.details;
+package com.gluster.storage.management.gui.views.pages;
import java.util.List;
import java.util.Map.Entry;
diff --git a/src/com.gluster.storage.management.server/WebContent/scripts/Protocol.py b/src/com.gluster.storage.management.server/WebContent/scripts/Protocol.py
new file mode 100644
index 00000000..ff073593
--- /dev/null
+++ b/src/com.gluster.storage.management.server/WebContent/scripts/Protocol.py
@@ -0,0 +1,438 @@
+# Copyright (C) 2009 Gluster, Inc. <http://www.gluster.com>
+# This file is part of Gluster Storage Platform.
+#
+# Gluster Storage Platform is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 3 of
+# the License, or (at your option) any later version.
+#
+# Gluster Storage Platform 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+import xml
+import xml.parsers.expat
+import xml.dom.minidom as MDOM
+import os
+import Globals
+import copy
+import Utils
+
+XML_STRING = 0
+XML_FILE = 1
+
+class XDOM:
+ _domObj = None
+
+ def __init__(self):
+ self._domObj = MDOM.Document()
+ return
+
+ @classmethod
+ def getText(self, nodeList):
+ rc = ""
+ for node in nodeList:
+ if node.nodeType == node.TEXT_NODE:
+ rc = rc + node.data
+ return rc.strip()
+
+ def parseString(self, requestString):
+ try:
+ self._domObj = MDOM.parseString(requestString)
+ except xml.parsers.expat.ExpatError, e:
+ Utils.log("XML string parse error: %s" % str(e))
+ return False
+ return True
+
+ def parseFile(self, fileName):
+ try:
+ self._domObj = MDOM.parse(fileName)
+ except IOError, e:
+ Utils.log("error reading file: %s" % str(e))
+ return False
+ except xml.parsers.expat.ExpatError, e:
+ Utils.log("XML file %s parse error: %s" % (fileName, str(e)))
+ return False
+ return True
+
+ def setDomObj(self, dom):
+ if dom and type(dom) != type([]):
+ self._domObj = dom
+ return True
+ return False
+
+ def createTextNode(self, text):
+ if not self._domObj:
+ return False
+ if not text:
+ return False
+ return self._domObj.createTextNode(str(text))
+
+ def createTag(self, tag, text=None):
+ if not self._domObj:
+ return None
+ if tag == None:
+ return None
+
+ tagE = self._domObj.createElement(str(tag))
+ if text:
+ tagEText = self._domObj.createTextNode(str(text))
+ tagE.appendChild(tagEText)
+ return tagE
+
+ def addTag(self, tag):
+ if not self._domObj:
+ return False
+ if not tag:
+ return False
+
+ self._domObj.appendChild(tag)
+ return True
+
+ def createTagRoute(self, tagRoute, text=None):
+ if not tagRoute:
+ return False
+
+ tagList = tagRoute.split(".")
+ tag = None
+ previousTag = None
+ for tagName in tagList[:-1]:
+ newTag = self.createTag(tagName, None)
+ if not tag:
+ tag = newTag
+ previousTag = newTag
+ continue
+ previousTag.appendChild(newTag)
+ previousTag = newTag
+
+ if previousTag:
+ previousTag.appendChild(self.createTag(tagList[-1], text))
+ else:
+ tag = self.createTag(tagList[-1], text)
+ return tag
+
+ def appendTagRoute(self, tagRoute, value=None):
+ if not self._domObj:
+ return False
+ if not tagRoute:
+ return False
+
+ parentTagE = self._domObj
+
+ tagNameList = tagRoute.split(".")
+ newTagRoute = tagNameList.pop(-1)
+
+ for i in range(len(tagNameList), 0, -1):
+ tagE = self.getElementsByTagRoute(".".join(tagNameList[:i]))
+ if tagE:
+ parentTagE = tagE[0]
+ break
+ newTagRoute = tagNameList[i-1] + "." + newTagRoute
+
+ newTagE = self.createTagRoute(newTagRoute, value)
+ if not newTagE:
+ return False
+ try:
+ parentTagE.appendChild(newTagE)
+ except xml.dom.HierarchyRequestErr, e:
+ Utils.log("error occured. %s" + str(e))
+ return False
+ return True
+
+ def setTextByTagRoute(self, tagRoute, tagValue):
+ if not self._domObj:
+ return None
+
+ if not tagRoute:
+ return None
+
+ tagE = self.getElementsByTagRoute(tagRoute)
+ if not tagE:
+ return False
+
+ parentTagE = self.getElementsByTagRoute(".".join(tagRoute.split(".")[:-1]))
+ if not parentTagE:
+ return False
+
+ parentTagE[0].childNodes.remove(tagE[0])
+ parentTagE[0].appendChild(self.createTag(tagRoute.split(".")[-1], tagValue))
+ return True
+
+ def getElementsByTagRoute(self, tagRoute):
+ if not self._domObj:
+ return None
+
+ if not tagRoute:
+ return None
+
+ x = None
+ for tag in tagRoute.split("."):
+ if x is None:
+ x = self._domObj.getElementsByTagName(tag)
+ continue
+ if x == []:
+ break
+ x = x[0].getElementsByTagName(tag)
+ return x
+
+ def getTextByTagRoute(self, tagRoute):
+ if not self._domObj:
+ return None
+
+ x = self.getElementsByTagRoute(tagRoute)
+ if x:
+ return self.getText(x[0].childNodes)
+ return None
+
+ def getElementsByTagName(self, name):
+ if not self._domObj:
+ return None
+ return self._domObj.getElementsByTagName(name)
+
+ def writexml(self, fileName, indent="", addindent="", newl=""):
+ if not self._domObj:
+ return None
+ try:
+ fp = open(fileName, "w")
+ self._domObj.writexml(fp, indent, addindent, newl)
+ fp.close()
+ return True
+ except IOError:
+ return False
+
+ def toString(self, indent=" ", newl="\n", encoding = None):
+ if not self._domObj:
+ return None
+ return self._domObj.toprettyxml(indent, newl, encoding)
+
+ def toxml(self, encoding = None):
+ if not self._domObj:
+ return None
+ return self._domObj.toxml(encoding)
+
+ def toprettyxml(self, indent=" ", newl="\n", encoding = None):
+ return self.toString(indent, newl, encoding)
+
+ def getAttribute(self, attributeName):
+ if not attributeName:
+ return None
+ try:
+ return self.getElementsByTagName("command")[0].getAttribute(attributeName)
+ except IndexError:
+ return False
+
+ def setAttribute(self, attributeName, attributeValue):
+ if not (attributeName and attributeValue):
+ return None
+ try:
+ return self.getElementsByTagName("command")[0].setAttribute(attributeName, attributeValue)
+ except IndexError:
+ return False
+
+ def getRequestCommand(self):
+ return self.getAttribute("request")
+
+ def getResponseCommand(self):
+ return self.getAttribute("response")
+
+ def getResponseCode(self):
+ return self.getAttribute("response-code")
+
+ def getMessageId(self):
+ return self.getAttribute("id")
+
+ def getVersion(self):
+ return self.getAttribute("version")
+
+ def getRequestAction(self):
+ return self.getAttribute("action")
+
+ def setVersion(self, value):
+ return self.setAttribute("version", value)
+
+ def setRequestAction(self, value):
+ return self.setAttribute("action", value)
+
+ def createCommandTag(self, command, responseCode, id, version=Globals.GLUSTER_PLATFORM_VERSION):
+ commandTag = self._domObj.createElement("command")
+ commandTag.setAttribute("response", command)
+ commandTag.setAttribute("response-code", responseCode)
+ commandTag.setAttribute("id", id)
+ commandTag.setAttribute("version", version)
+ return commandTag
+##--end of XDOM
+
+class RequestXml(XDOM):
+ def __init__(self, requestString, type=None):
+ if None == requestString:
+ XDOM.__init__(self)
+ return
+ try:
+ if None == type:
+ if os.path.isfile(requestString):
+ self._domObj = MDOM.parse(requestString)
+ else:
+ self._domObj = MDOM.parseString(requestString)
+ elif XML_FILE == type:
+ self._domObj = MDOM.parse(requestString)
+ elif XML_STRING == type:
+ self._domObj = MDOM.parseString(requestString)
+ except IOError:
+ XDOM.__init__(self)
+ except xml.parsers.expat.ExpatError:
+ XDOM.__init__(self)
+
+##--end of RequestXML
+
+class ResponseXml(XDOM):
+ _commandTag = None
+ def __init__(self, command, responseCode, id, version=Globals.GLUSTER_PLATFORM_VERSION):
+ XDOM.__init__(self)
+ if command and responseCode and id:
+ self._commandTag = self.createCommandTag(command, responseCode, id, version)
+ self._domObj.appendChild(self._commandTag)
+
+ def appendCommand(self, command, responseCode, id, version=Globals.GLUSTER_PLATFORM_VERSION):
+ if command and responseCode and id:
+ self._commandTag = self.createCommandTag(command, responseCode, id, version)
+ self._domObj.appendChild(self._commandTag)
+ return True
+ return False
+
+ def append(self, tagName, tagValue=None):
+ if not self._commandTag:
+ return False
+ tag = self.createTag(tagName, tagValue)
+ if tag:
+ self._commandTag.appendChild(tag)
+ return True
+ return False
+
+ def appendTag(self, tag):
+ if not tag:
+ return False
+ if not self._commandTag:
+ return False
+ self._commandTag.appendChild(tag)
+ return True
+
+ def appendTagRoute(self, tagRoute, value=None):
+ if not self._commandTag:
+ return False
+ if not tagRoute:
+ return False
+
+ parentTagE = self._commandTag
+
+ tagNameList = tagRoute.split(".")
+ newTagRoute = tagNameList.pop(-1)
+
+ for i in range(len(tagNameList), 0, -1):
+ tagE = self.getElementsByTagRoute(".".join(["command"] + tagNameList[:i]))
+ if tagE:
+ parentTagE = tagE[0]
+ break
+ newTagRoute = tagNameList[i-1] + "." + newTagRoute
+
+ newTagE = self.createTagRoute(newTagRoute, value)
+ if not newTagE:
+ return False
+ try:
+ parentTagE.appendChild(newTagE)
+ except xml.dom.HierarchyRequestErr, e:
+ Utils.log("error occured. %s" + str(e))
+ return False
+ return True
+
+ def appendTagRouteOld(self, tagRoute, value=None):
+ if not tagRoute:
+ return False
+ if not self._commandTag:
+ return False
+
+ tmpTagRoute = ""
+ previousTagE = self._commandTag
+ tagE = None
+ for tagName in tagRoute.split("."):
+ if not tmpTagRoute:
+ tagE = self.getElementsByTagRoute("command." + tagName)
+ else:
+ tagE = self.getElementsByTagRoute("command." + tmpTagRoute + "." + tagName)
+ if not tagE:
+ break
+ if len(tagE) != 1:
+ return False
+ previousTagE = tagE[0]
+ if not tmpTagRoute:
+ tmpTagRoute = tagName
+ else:
+ tmpTagRoute = tmpTagRoute + "." + tagName
+
+ if tmpTagRoute == tagRoute:
+ return False
+ newTagRoute = tagRoute[len(tmpTagRoute):]
+ if newTagRoute[0] == '.':
+ newTagRoute = newTagRoute[1:]
+
+ if previousTagE.childNodes and previousTagE.childNodes[0].nodeType == previousTagE.TEXT_NODE:
+ return False
+ previousTagE.appendChild(self.createTagRoute(newTagRoute, value))
+ return True
+##--end of ResponseXml
+
+def test():
+ #volumes = RequestXml(VolumeFile, XML_FILE).getElementsByTagRoute("volume-list.volume")
+ requestStr = '''<command request="create-volume" id="123" version="3.1">
+<volume>
+<name>movies1</name>
+<type>cluster mirror</type>
+<start>512000</start>
+<server>zresearch</server>
+<vacl>192.168.20.*</vacl>
+<vacl>192.168.30.*</vacl>
+<nfs>
+<export>no</export>
+</nfs>
+<cifs>
+<export>no</export>
+</cifs>
+<webdav>
+<export>no</export>
+</webdav>
+</volume>
+</command>'''
+
+ requestXml = RequestXml(requestStr)
+ print requestXml.getAttribute("")
+
+def test1():
+ rs = ResponseXml("create-volume", "OK", "xyz")
+ rs.appendTagRoute("volume.detail.name", "music")
+ print rs.toprettyxml()
+ rs.append("volume", "data")
+ print rs.toprettyxml()
+ rs.appendTagRoute("volume.detail.ipaddr", "192.168.10.1")
+ print rs.toprettyxml()
+ print rs.appendTagRoute("volume.detail.ipaddr.v6", "ff:ff::ff::")
+ print rs.toprettyxml()
+
+ print rs.getTextByTagRoute("command.volume.detail")
+
+def test2():
+ rs = ResponseXml("download-volume-logs", "OK", "xyz")
+ te = rs.createTag("interface", None)
+ te.appendChild(rs.createTag("device", "DEVICE1"))
+ te.appendChild(rs.createTag("description", "my device one"))
+ rs.appendTag(te)
+
+ te = rs.createTag("interface", None)
+ te.appendChild(rs.createTag("device", "DEVICE2"))
+ te.appendChild(rs.createTag("description", "my device two"))
+ rs.appendTag(te)
+ print rs.toprettyxml()
+
diff --git a/src/com.gluster.storage.management.server/WebContent/scripts/Utils.py b/src/com.gluster.storage.management.server/WebContent/scripts/Utils.py
new file mode 100644
index 00000000..f9b3254b
--- /dev/null
+++ b/src/com.gluster.storage.management.server/WebContent/scripts/Utils.py
@@ -0,0 +1,705 @@
+# Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+# This file is part of Gluster Storage Platform.
+#
+# Gluster Storage Platform is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 3 of
+# the License, or (at your option) any later version.
+#
+# Gluster Storage Platform 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+import sys
+import os
+import re
+import socket
+import struct
+import syslog
+import subprocess
+#import spwd
+import time
+#import uuid
+import tempfile
+import grp
+import pwd
+import inspect
+from datetime import datetime
+import urllib
+
+import Globals
+import Protocol
+from Common import *
+
+RUN_COMMAND_ERROR = -1024
+LOG_SYSLOG = 1
+SYSLOG_REQUIRED = False
+LOG_FILE_NAME = None
+LOG_FILE_OBJ = None
+
+
+def _getLogCode(priority):
+ if syslog.LOG_EMERG == priority:
+ return "M"
+ elif syslog.LOG_ALERT == priority:
+ return "A"
+ elif syslog.LOG_CRIT == priority:
+ return "C"
+ elif syslog.LOG_ERR == priority:
+ return "E"
+ elif syslog.LOG_WARNING == priority:
+ return "W"
+ elif syslog.LOG_NOTICE == priority:
+ return "N"
+ elif syslog.LOG_INFO == priority:
+ return "I"
+ elif syslog.LOG_DEBUG == priority:
+ return "D"
+ else: # UNKNOWN
+ return "X"
+
+
+def setLogFile(fileName):
+ global LOG_FILE_NAME
+
+ if fileName:
+ LOG_FILE_NAME = fileName
+ return True
+ return False
+
+
+def closeLog():
+ global LOG_FILE_OBJ
+ global SYSLOG_REQUIRED
+
+ if SYSLOG_REQUIRED:
+ syslog.closelog()
+ SYSLOG_REQUIRED = False
+ return True
+
+ if LOG_FILE_OBJ:
+ try:
+ LOG_FILE_OBJ.close()
+ LOG_FILE_OBJ = None
+ except IOError, e:
+ sys.stderr.write("Failed to close file: %s\n" % e)
+ return False
+ return True
+
+
+def openLog(fileName=None):
+ global LOG_FILE_NAME
+ global LOG_FILE_OBJ
+ global SYSLOG_REQUIRED
+
+ if fileName == LOG_SYSLOG:
+ syslog.openlog(os.path.basename(sys.argv[0]))
+ SYSLOG_REQUIRED = True
+ return True
+
+ if fileName:
+ LOG_FILE_NAME = fileName
+
+ if not LOG_FILE_NAME:
+ return False
+
+ closeLog()
+
+ try:
+ LOG_FILE_OBJ = open(LOG_FILE_NAME, "a")
+ except IOError, e:
+ sys.stderr.write("Failed to open file %s: %s\n" % (LOG_FILE_NAME, e))
+ return False
+ return True
+
+def record(priority, message=None):
+ global LOG_FILE_OBJ
+ global SYSLOG_REQUIRED
+
+ stack = inspect.stack()[1]
+ if stack[3] == "<module>":
+ prefix = "%s:%s:%s" % (stack[1], stack[2], stack[3])
+ else:
+ prefix = "%s:%s:%s()" % (stack[1], stack[2], stack[3])
+
+ if type(priority) == type("") or type(priority) == type(u""):
+ logPriority = syslog.LOG_INFO
+ logMessage = priority
+ else:
+ logPriority = priority
+ logMessage = message
+
+ if SYSLOG_REQUIRED:
+ syslog.syslog(logPriority, "[%s]: %s" % (prefix, logMessage))
+ return
+
+ fp = sys.stderr
+ if LOG_FILE_OBJ:
+ fp = LOG_FILE_OBJ
+
+ fp.write("[%s] %s [%s]: %s" % (str(datetime.now()), _getLogCode(logPriority), prefix, logMessage))
+ if logMessage[-1] != '\n':
+ fp.write("\n")
+ fp.flush()
+ return
+
+
+def trace(message):
+ if message:
+ log(syslog.LOG_DEBUG, message)
+
+
+def isString(value):
+ return (type(value) == type("") or type(value) == type(u""))
+
+
+def getTempFileName():
+ filedesc, filename = tempfile.mkstemp(prefix="GSP_")
+ os.close(filedesc)
+ return filename
+
+
+def runCommandBG(command, stdinFileObj=None, stdoutFileObj=None, stderrFileObj=None,
+ shell=False, root=None):
+ log("runCommandBG(): Trying to execute command [%s]" % command)
+
+ if shell:
+ if not isString(command):
+ return None
+ else:
+ if isString(command):
+ command = command.split()
+
+ if root == True:
+ if shell:
+ command = "sudo " + command
+ else:
+ command = ['sudo'] + command
+ elif isString(root):
+ if shell:
+ command = "sudo -u " + root + " " + command
+ else:
+ command = ['sudo', '-u', root] + command
+
+ if not stdinFileObj:
+ stdinFileObj=subprocess.PIPE
+ if not stdoutFileObj:
+ stdoutFileObj=subprocess.PIPE
+ if not stderrFileObj:
+ stderrFileObj=subprocess.PIPE
+
+ try:
+ process = subprocess.Popen(command,
+ bufsize=-1,
+ stdin=stdinFileObj,
+ stdout=stdoutFileObj,
+ stderr=stderrFileObj,
+ shell=shell)
+ return process
+ except OSError, e:
+ log("runCommandBG(): Failed to run command [%s]: %s" % (command, e))
+ return None
+
+
+def runCommand(command,
+ input='', output=False,
+ shell=False, root=None):
+ rv = {}
+ rv["Status"] = RUN_COMMAND_ERROR
+ rv["Stdout"] = None
+ rv["Stderr"] = None
+
+ try:
+ stdinFileName = getTempFileName()
+ stdinFileObj = open(stdinFileName, "w")
+ stdinFileObj.write(input)
+ stdinFileObj.close()
+ stdinFileObj = open(stdinFileName, "r")
+
+ stdoutFileName = getTempFileName()
+ stdoutFileObj = open(stdoutFileName, "w")
+
+ stderrFileName = getTempFileName()
+ stderrFileObj = open(stderrFileName, "w")
+ except IOError, e:
+ log("Failed to create temporary file for executing command [%s]: %s" % (command, e))
+ if output:
+ return rv
+ return rv["Status"]
+
+ stdoutContent = None
+ stderrContent = None
+
+ process = runCommandBG(command,
+ stdinFileObj=stdinFileObj,
+ stdoutFileObj=stdoutFileObj,
+ stderrFileObj=stderrFileObj,
+ shell=shell, root=root)
+ if process:
+ rv['Status'] = process.wait()
+ rv['Stdout'] = open(stdoutFileName).read()
+ rv['Stderr'] = open(stderrFileName).read()
+
+ os.remove(stdinFileName)
+ os.remove(stdoutFileName)
+ os.remove(stderrFileName)
+
+ log("runCommand(): execution status of command [%s] = [%s]" % (command, rv))
+
+ if output:
+ return rv
+ return rv["Status"]
+
+
+def runCommandFG(command, stdout=False, stderr=False,
+ shell=False, root=None):
+ if stdout or stderr:
+ output = True
+ else:
+ output = False
+ return runCommand(command, output=output, shell=shell, root=root)
+
+
+def IP2Number(ipString):
+ try:
+ return socket.htonl(struct.unpack("I", socket.inet_aton(ipString))[0])
+ except socket.error:
+ return None
+ except TypeError:
+ return None
+ except struct.error:
+ return None
+
+
+def Number2IP(number):
+ try:
+ return socket.inet_ntoa(struct.pack("I", socket.ntohl(number)))
+ except socket.error:
+ return None
+ except AttributeError:
+ return None
+ except ValueError:
+ return None
+
+
+def computeHostName(hostName):
+ if not hostName:
+ return False
+
+ hostPrefix = ""
+ for i in range(len(hostName), 0, -1):
+ pos = i - 1
+ if hostName[pos].isdigit():
+ continue
+ break
+ hostPrefix = hostName[:pos+1]
+ try:
+ hostIndex = int(hostName[pos+1:])
+ except ValueError:
+ hostIndex = 0
+ # TODO: Check the availablity of the (server) name
+ return "%s%s" % (hostPrefix, hostIndex + 1)
+
+
+def daemonize():
+ try:
+ pid = os.fork()
+ if pid > 0:
+ # exit first parent
+ sys.exit(0)
+ except OSError, e:
+ #sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
+ return False
+
+ # decouple from parent environment
+ os.chdir("/")
+ os.setsid()
+ os.umask(0)
+
+ # do second fork
+ try:
+ pid = os.fork()
+ if pid > 0:
+ # exit from second parent
+ sys.exit(0)
+ except OSError, e:
+ #sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
+ return False
+
+ # redirect standard file descriptors
+ sys.stdout.flush()
+ sys.stderr.flush()
+ si = file("/dev/null", 'r')
+ so = file("/dev/null", 'a+')
+ se = file("/dev/null", 'a+', 0)
+ os.dup2(si.fileno(), sys.stdin.fileno())
+ os.dup2(so.fileno(), sys.stdout.fileno())
+ os.dup2(se.fileno(), sys.stderr.fileno())
+ return True
+
+
+def getDownloadStatus(fileName):
+ try:
+ lines = [line for line in open(fileName)
+ if "saved" in line or "%" in line]
+ except IOError:
+ return 0
+ if not lines:
+ return 0
+ if "saved" in lines[-1]:
+ return 100
+ return lines[-1].split("%")[0].split()[-1]
+
+
+def getMeminfo():
+ """-> dict of data from meminfo (str:int).
+ Values are in kilobytes.
+ """
+ import re
+ re_parser = re.compile(r'^(?P<key>\S*):\s*(?P<value>\d*)\s*kB' )
+ result = {}
+ for line in open('/proc/meminfo'):
+ match = re_parser.match(line)
+ if not match:
+ continue # skip lines that don't parse
+ key, value = match.groups(['key', 'value'])
+ result[key] = int(value)
+ return result
+
+
+def getCpuUsage():
+ """-> dict of cpuid : (usertime, nicetime, systemtime, idletime)
+ cpuid "cpu" means the total for all CPUs.
+ cpuid "cpuN" means the value for CPU N.
+ """
+ wanted_records = [line for line in open('/proc/stat') if
+ line.startswith('cpu')]
+ result = {}
+ for cpuline in wanted_records:
+ fields = cpuline.split()[:5]
+ data = map(int, fields[1:])
+ result[fields[0]] = tuple(data)
+ return result
+
+
+def getLoadavg():
+ """-> 5-tuple containing the following numbers in order:
+ - 1-minute load average (float)
+ - 5-minute load average (float)
+ - 15-minute load average (float)
+ - Number of threads/processes currently executing (<= number of
+ CPUs) (int)
+ - Number of threads/processes that exist on the system (int)
+ - The PID of the most recently-created process on the system (int)
+ """
+ loadavgstr = open('/proc/loadavg', 'r').readline().strip()
+ data = loadavgstr.split()
+ avg1, avg5, avg15 = map(float, data[:3])
+ threads_and_procs_running, threads_and_procs_total = map(int,
+ data[3].split('/'))
+ most_recent_pid = int(data[4])
+ ncpus = 1
+ final_avg = ""
+ if hasattr(os, "sysconf"):
+ if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"):
+ # Linux
+ ncpus = os.sysconf("SC_NPROCESSORS_ONLN")
+ if isinstance(ncpus, int) and ncpus > 0:
+ final_avg = "%.2f" % (1.0 * avg1 / ncpus)
+
+ # Future return everything when needed
+ # Commenting this for the time being
+ # avg5, avg15, threads_and_procs_running, threads_and_procs_total, most_recent_pid
+ return final_avg
+
+
+def getInfinibandPortStatus():
+
+ """ Check for availability of infiniband port
+ and return which port is active in a key pair value
+ """
+
+ # Check for existence of infiniband ports
+ value = os.popen ("ls /sys/class/infiniband").readline().strip()
+
+ if not value:
+ return None
+
+ portlist = os.popen ("echo /sys/class/infiniband/*/ports/*").readline().split()
+
+ portkeys = {}
+
+ for port in portlist:
+ value = os.popen ("cat %s/state" %
+ port.strip()).readline().split(':')[1].strip()
+ portkeys[port.strip()] = value
+
+ return portkeys
+
+
+def getServerCount():
+ try:
+ return int(open(Globals.SERVER_COUNT_FILE).read().strip())
+ except IOError:
+ log("failed to read file %s" % Globals.SERVER_COUNT_FILE)
+ return 1
+ except ValueError:
+ log("invalid number format in file %s" % Globals.SERVER_COUNT_FILE)
+ return 1
+
+
+def setServerCount(count):
+ try:
+ open(Globals.SERVER_COUNT_FILE, "w").write("%s\n" % count)
+ return True
+ except IOError:
+ log("failed to write file %s" % Globals.SERVER_COUNT_FILE)
+ return False
+
+
+def getInstalledServerCount():
+ try:
+ return int(open(Globals.INSTALLED_SERVER_COUNT_FILE).read().strip())
+ except IOError:
+ log("failed to read file %s" % Globals.INSTALLED_SERVER_COUNT_FILE)
+ return 1
+ except ValueError:
+ log("invalid number format in file %s" % Globals.INSTALLED_SERVER_COUNT_FILE)
+ return 1
+
+
+def setInstalledServerCount(count):
+ try:
+ open(Globals.INSTALLED_SERVER_COUNT_FILE, "w").write("%s\n" % count)
+ return True
+ except IOError:
+ log("failed to write file %s" % Globals.INSTALLED_SERVER_COUNT_FILE)
+ return False
+
+
+def getLastInstalledServerIpList():
+ ipList = {}
+ networkDom = Protocol.XDOM()
+ if not networkDom.parseFile(Globals.GLOBAL_NETWORK_FILE):
+ log("failed to parse file %s" % Globals.GLOBAL_NETWORK_FILE)
+ for tagE in networkDom.getElementsByTagRoute("server.interface"):
+ interfaceDom = Protocol.XDOM()
+ interfaceDom.setDomObj(tagE)
+ ipAddress = interfaceDom.getTextByTagRoute("ipaddr")
+ if ipAddress:
+ ipList[interfaceDom.getTextByTagRoute("device")] = ipAddress
+ return ipList
+
+
+def getFreeIpAddress(device=None):
+ serverCount = getServerCount()
+ installedServerCount = getInstalledServerCount()
+ if serverCount == installedServerCount:
+ return None
+
+ availableServerCount = serverCount - installedServerCount
+ ipList = getLastInstalledServerIpList()
+
+ if not ipList:
+ return None
+
+ if device:
+ if device not in ipList.keys():
+ return None
+ deviceIpAddress = ipList[device]
+ else:
+ deviceIpAddress = ipList.values()[0]
+ ipNumber = IP2Number(deviceIpAddress)
+
+ for i in range((ipNumber + availableServerCount), ipNumber, -1):
+ ipAddress = Number2IP(i)
+ if runCommandFG(["ping", "-qnc", "1", ipAddress]) != 0:
+ return ipAddress
+ return None
+
+
+def getPasswordHash(userName):
+ try:
+ #return spwd.getspnam(userName).sp_pwd
+ return "Not implimented"
+ except KeyError:
+ return None
+
+
+def getTransactionKey():
+ try:
+ tokens = open(Globals.TRANSACTION_KEY_FILE).read().split(',')
+ except IOError:
+ return None, None
+ return tokens
+
+
+def generateSignature():
+ #return str(uuid.uuid4()) + ('--%f' % time.time())
+ return ('--%f' % time.time())
+
+
+def getSignature():
+ try:
+ return open(Globals.SIGNATURE_FILE).read().strip()
+ except IOError:
+ log(syslog.LOG_ERR, "unable to read signaure from %s file" % Globals.SIGNATURE_FILE)
+ return False
+
+
+def storeSignature(signature, fileName=Globals.SIGNATURE_FILE):
+ try:
+ open(fileName, "w").write(signature + "\n")
+ except IOError:
+ log(syslog.LOG_ERR, "unable to write signature %s to %s file" % (signature, fileName))
+ return False
+ return True
+
+
+def isUserExist(userName):
+ try:
+ grp.getgrnam(userName).gr_gid
+ return True
+ except KeyError:
+ pass
+ try:
+ pwd.getpwnam(userName).pw_uid
+ return True
+ except KeyError:
+ pass
+ return False
+
+
+def getGsnUserInfo(fileName=Globals.GSN_USER_INFO_FILE):
+ userInfo = {}
+ userInfo["UserId"] = None
+ userInfo["Password"] = None
+ try:
+ for line in open(fileName):
+ line = line.strip()
+ k = line[:line.index("=")]
+ v = line[line.index("=") + 1:]
+ if v[0] == "'" or v[0] == '"':
+ v = v[1:]
+ if v[-1] == "'" or v[-1] == '"':
+ v = v[:-1]
+ if k.upper() == "GSN_ID":
+ userInfo["UserId"] = v
+ if k.upper() == "GSN_PASSWORD":
+ userInfo["Password"] = v
+ except IOError, e:
+ log("Failed to read file %s: %s" % (fileName, e))
+ return userInfo
+
+
+def setGsnUserInfo(userInfo, fileName=Globals.GSN_USER_INFO_FILE):
+ try:
+ fp = open(fileName, "w")
+ fp.write("GSN_ID=%s\n" % userInfo["UserId"])
+ fp.write("GSN_PASSWORD=%s\n" % userInfo["Password"])
+ fp.close()
+ return True
+ except IOError, e:
+ log("Failed to write file %s: %s" % (fileName, e))
+ return False
+
+
+def getPlatformVersion(fileName=Globals.GLUSTER_VERSION_FILE):
+ versionInfo = {}
+ versionInfo["Version"] = None
+ versionInfo["Update"] = None
+ try:
+ lines = open(Globals.GLUSTER_VERSION_FILE).readlines()
+ for line in open(fileName):
+ line = line.strip()
+ k = line[:line.index("=")]
+ v = line[line.index("=") + 1:]
+ if v[0] == "'" or v[0] == '"':
+ v = v[1:]
+ if v[-1] == "'" or v[-1] == '"':
+ v = v[:-1]
+ if k.upper() == "VERSION":
+ versionInfo["Version"] = v
+ if k.upper() == "UPDATE":
+ versionInfo["Update"] = v
+ except IOError, e:
+ log("Failed to read file %s: %s" % (fileName, e))
+ return versionInfo
+
+
+def setPlatformVersion(versionInfo, fileName=Globals.GLUSTER_VERSION_FILE):
+ if isString(versionInfo):
+ tokens = versionInfo.strip().split(".")
+ if len(tokens) < 2:
+ log("Invalid version format %s. Expecting <MAJOR>.<MINOR>.<PATCHLEVEL>" % versionInfo)
+ return False
+ version = ".".join(tokens[:2])
+ update = ".".join(tokens[2:])
+ if not update:
+ update = "0"
+ else:
+ version = versionInfo["Version"]
+ update = versionInfo["Update"]
+ try:
+ fp = open(fileName, "w")
+ fp.write("VERSION=%s\n" % version)
+ fp.write("UPDATE=%s\n" % update)
+ fp.close()
+ return True
+ except IOError, e:
+ log("Failed to write file %s: %s" % (fileName, e))
+ return False
+
+
+def getGlusterUpdateDom(serverVersion):
+ errorMessage = ""
+ updateInfoDom = None
+ try:
+ baseUrl = open(Globals.GLUSTER_UPDATE_SITE_FILE).read().strip()
+ except IOError, e:
+ log("Failed to read file %s: %s" % (Globals.GLUSTER_UPDATE_SITE_FILE, e))
+ errorMessage = "Failed to read update site file"
+ return updateInfoDom, errorMessage
+
+ try:
+ url = "%s/%s/%s" % (baseUrl, serverVersion, Globals.GLUSTER_UPDATES_FILE)
+ connection = urllib.urlopen(url)
+ if connection.getcode() != 200:
+ connection.close()
+ errorMessage = "Error received from server to open URL %s" % url
+ return updateInfoDom, errorMessage
+ updateInfoString = connection.read()
+ connection.close()
+ except IOError, e:
+ log("Failed to get update information from URL %s: %s" % (url, e))
+ errorMessage = "Error getting update information"
+ return updateInfoDom, errorMessage
+
+ updateInfoDom = Protocol.XDOM()
+ if not updateInfoDom.parseString(updateInfoString):
+ log("XML parse error on update information content [%s]" % updateInfoString)
+ errorMessage = "Parse error on update information"
+ updateInfoDom = None
+ return updateInfoDom, errorMessage
+
+
+def removeFile(fileName, root=False):
+ if root:
+ if runCommand("rm %s" % fileName, root=True) == 0:
+ return True
+ return False
+ try:
+ os.remove(fileName)
+ return True
+ except OSError, e:
+ Utils.log("Failed to remove file %s: %s" % (fileName, e))
+ return False
+
+
+def isLiveMode():
+ return os.path.exists(Globals.LIVE_MODE_FILE)
diff --git a/src/com.gluster.storage.management.server/WebContent/scripts/XmlHandler.py b/src/com.gluster.storage.management.server/WebContent/scripts/XmlHandler.py
new file mode 100644
index 00000000..72164ffb
--- /dev/null
+++ b/src/com.gluster.storage.management.server/WebContent/scripts/XmlHandler.py
@@ -0,0 +1,346 @@
+# Copyright (C) 2009 Gluster, Inc. <http://www.gluster.com>
+# This file is part of Gluster Storage Platform.
+#
+# Gluster Storage Platform is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 3 of
+# the License, or (at your option) any later version.
+#
+# Gluster Storage Platform 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+import xml
+import xml.parsers.expat
+import xml.dom.minidom as MDOM
+import os
+import Globals
+import copy
+import Utils
+
+XML_STRING = 0
+XML_FILE = 1
+
+class XDOM:
+ _domObj = None
+
+ def __init__(self):
+ self._domObj = MDOM.Document()
+ return
+
+ @classmethod
+ def getText(self, nodeList):
+ rc = ""
+ for node in nodeList:
+ if node.nodeType == node.TEXT_NODE:
+ rc = rc + node.data
+ return rc
+
+ def parseString(self, requestString):
+ try:
+ self._domObj = MDOM.parseString(requestString)
+ except xml.parsers.expat.ExpatError, e:
+ Utils.log("XML string parse error: %s" % str(e))
+ return False
+ return True
+
+ def parseFile(self, fileName):
+ try:
+ self._domObj = MDOM.parse(fileName)
+ except IOError, e:
+ Utils.log("error reading file: %s" % str(e))
+ return False
+ except xml.parsers.expat.ExpatError, e:
+ Utils.log("XML file %s parse error: %s" % (fileName, str(e)))
+ return False
+ return True
+
+ def setDomObj(self, dom):
+ if dom and type(dom) != type([]):
+ self._domObj = dom
+ return True
+ return False
+
+ def createTag(self, tag, text=None):
+ if not self._domObj:
+ return None
+ if tag == None:
+ return None
+
+ tagE = self._domObj.createElement(str(tag))
+ if text:
+ tagEText = self._domObj.createTextNode(str(text))
+ tagE.appendChild(tagEText)
+ return tagE
+
+ def addTag(self, tag):
+ if not self._domObj:
+ return False
+ if not tag:
+ return False
+
+ self._domObj.appendChild(tag)
+ return True
+
+ def createTagRoute(self, tagRoute, text=None):
+ if not tagRoute:
+ return False
+
+ tagList = tagRoute.split(".")
+ tag = None
+ previousTag = None
+ for tagName in tagList[:-1]:
+ newTag = self.createTag(tagName, None)
+ if not tag:
+ tag = newTag
+ previousTag = newTag
+ continue
+ previousTag.appendChild(newTag)
+ previousTag = newTag
+
+ if previousTag:
+ previousTag.appendChild(self.createTag(tagList[-1], text))
+ else:
+ tag = self.createTag(tagList[-1], text)
+ return tag
+
+ def appendTagRoute(self, tagRoute, value=None):
+ if not self._domObj:
+ return False
+ if not tagRoute:
+ return False
+
+ parentTagE = self._domObj
+
+ tagNameList = tagRoute.split(".")
+ newTagRoute = tagNameList.pop(-1)
+
+ for i in range(len(tagNameList), 0, -1):
+ tagE = self.getElementsByTagRoute(".".join(tagNameList[:i]))
+ if tagE:
+ parentTagE = tagE[0]
+ break
+ newTagRoute = tagNameList[i-1] + "." + newTagRoute
+
+ newTagE = self.createTagRoute(newTagRoute, value)
+ if not newTagE:
+ return False
+ try:
+ parentTagE.appendChild(newTagE)
+ except xml.dom.HierarchyRequestErr, e:
+ Utils.log("error occured. %s" + str(e))
+ return False
+ return True
+
+ def setTextByTagRoute(self, tagRoute, tagValue):
+ if not self._domObj:
+ return None
+
+ if not tagRoute:
+ return None
+
+ tagE = self.getElementsByTagRoute(tagRoute)
+ if not tagE:
+ return False
+
+ parentTagE = self.getElementsByTagRoute(".".join(tagRoute.split(".")[:-1]))
+ if not parentTagE:
+ return False
+
+ parentTagE[0].childNodes.remove(tagE[0])
+ parentTagE[0].appendChild(self.createTag(tagRoute.split(".")[-1], tagValue))
+ return True
+
+ def getElementsByTagRoute(self, tagRoute):
+ if not self._domObj:
+ return None
+
+ if not tagRoute:
+ return None
+
+ x = None
+ for tag in tagRoute.split("."):
+ if x is None:
+ x = self._domObj.getElementsByTagName(tag)
+ continue
+ if x == []:
+ break
+ x = x[0].getElementsByTagName(tag)
+ return x
+
+ def getTextByTagRoute(self, tagRoute):
+ if not self._domObj:
+ return None
+
+ x = self.getElementsByTagRoute(tagRoute)
+ if x:
+ return self.getText(x[0].childNodes)
+ return None
+
+ def getElementsByTagName(self, name):
+ if not self._domObj:
+ return None
+ return self._domObj.getElementsByTagName(name)
+
+ def writexml(self, fileName, indent="", addindent="", newl=""):
+ if not self._domObj:
+ return None
+ try:
+ fp = open(fileName, "w")
+ self._domObj.writexml(fp, indent, addindent, newl)
+ fp.close()
+ return True
+ except IOError:
+ return False
+
+ def toString(self, indent=" ", newl="\n", encoding = None):
+ if not self._domObj:
+ return None
+ return self._domObj.toprettyxml(indent, newl, encoding)
+
+ def toxml(self, encoding = None):
+ if not self._domObj:
+ return None
+ return self._domObj.toxml(encoding)
+
+ def toprettyxml(self, indent=" ", newl="\n", encoding = None):
+ return self.toString(indent, newl, encoding)
+
+ def createResponseTag(self):
+ responseTag = self._domObj.createElement("response")
+ return responseTag
+##--end of XDOM
+
+class RequestXml(XDOM):
+ def __init__(self, requestString, type=None):
+ if None == requestString:
+ XDOM.__init__(self)
+ return
+ try:
+ if None == type:
+ if os.path.isfile(requestString):
+ self._domObj = MDOM.parse(requestString)
+ else:
+ self._domObj = MDOM.parseString(requestString)
+ elif XML_FILE == type:
+ self._domObj = MDOM.parse(requestString)
+ elif XML_STRING == type:
+ self._domObj = MDOM.parseString(requestString)
+ except IOError:
+ XDOM.__init__(self)
+ except xml.parsers.expat.ExpatError:
+ XDOM.__init__(self)
+
+##--end of RequestXML
+
+
+class ResponseXml(XDOM):
+ _responseTag = None
+ def __init__(self):
+ XDOM.__init__(self)
+ self._responseTag = self.createResponseTag()
+ self._domObj.appendChild(self._responseTag)
+
+ @classmethod
+ def errorResponse(self, message):
+ if not self.responseTag:
+ return False
+ self.appendTagRoute("status.code", "-1");
+ self.appendTagRoute("status.message", message)
+
+ def append(self, tagName, tagValue=None):
+ if not self._responseTag:
+ return False
+ tag = self.createTag(tagName, tagValue)
+ if tag:
+ self._responseTag.appendChild(tag)
+ return True
+ return False
+
+ def appendTag(self, tag):
+ if not tag:
+ return False
+ if not self._responseTag:
+ return False
+ self._responseTag.appendChild(tag)
+ return True
+
+ def appendTagRoute(self, tagRoute, value=None):
+ if not self._responseTag:
+ return None
+ if not tagRoute:
+ return None
+
+ parentTagE = self._responseTag
+
+ tagNameList = tagRoute.split(".")
+ newTagRoute = tagNameList.pop(-1)
+
+ for i in range(len(tagNameList), 0, -1):
+ tagE = self.getElementsByTagRoute(".".join(["response"] + tagNameList[:i]))
+ if tagE:
+ parentTagE = tagE[0]
+ break
+ newTagRoute = tagNameList[i-1] + "." + newTagRoute
+
+ newTagE = self.createTagRoute(newTagRoute, value)
+ if not newTagE:
+ return None
+ try:
+ parentTagE.appendChild(newTagE)
+ except xml.dom.HierarchyRequestErr, e:
+ Utils.log("error occured. %s" + str(e))
+ return None
+ return newTagE
+
+ def appendTagRouteOld(self, tagRoute, value=None):
+ if not self._responseTag:
+ return False
+ if not tagRoute:
+ return False
+
+ parentTagE = self._responseTag
+
+ tagNameList = tagRoute.split(".")
+ newTagRoute = tagNameList.pop(-1)
+
+ for i in range(len(tagNameList), 0, -1):
+ tagE = self.getElementsByTagRoute(".".join(["response"] + tagNameList[:i]))
+ if tagE:
+ parentTagE = tagE[0]
+ break
+ newTagRoute = tagNameList[i-1] + "." + newTagRoute
+
+ newTagE = self.createTagRoute(newTagRoute, value)
+ if not newTagE:
+ return False
+ try:
+ parentTagE.appendChild(newTagE)
+ except xml.dom.HierarchyRequestErr, e:
+ Utils.log("error occured. %s" + str(e))
+ return False
+ return True
+##--end of ResponseXml
+
+def test():
+ rs = ResponseXml()
+ rs.appendTagRoute("status.code", "0");
+ rs.appendTagRoute("status.message", "SUCCESS")
+ serverTag = rs.appendTagRoute("server.name", "Server1")
+ networkInterfaces = rs.appendTagRoute("server.networkInterfaces", None)
+ networkTag = rs.createTag("networkInterface", None)
+ networkTag.appendChild(rs.createTag("name", "interface1"))
+ networkTag.appendChild(rs.createTag("ipaddress", "192.168.1.40"))
+ networkInterfaces.appendChild(networkTag)
+ networkTag = rs.createTag("networkInterface", None)
+ networkTag.appendChild(rs.createTag("name", "interface2"))
+ networkTag.appendChild(rs.createTag("ipaddress", "192.168.1.41"))
+ networkInterfaces.appendChild(networkTag)
+ print rs.toprettyxml()
+
+#test()