summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorShireesh Anjal <shireesh@gluster.com>2011-04-11 14:05:20 +0530
committerShireesh Anjal <shireesh@gluster.com>2011-04-11 14:05:20 +0530
commit8e28b180eec30f2059977c20a83a8f2488e41788 (patch)
tree3d4fbfd586d4675a3c80e2d594fdfb88980ff594 /src
parent49f755f886ce0b99c7e0f61d71eaee814ce5ae66 (diff)
parent89211e6eb5996e1f18493d2a48696171b3693811 (diff)
Merge branch 'master' into volume-options
Conflicts: src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterUtil.java src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java
Diffstat (limited to 'src')
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterUtil.java2
-rw-r--r--src/com.gluster.storage.management.gui/META-INF/MANIFEST.MF3
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/CreateVolumeAction.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java11
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java70
-rw-r--r--src/com.gluster.storage.management.server.scripts/src/common/Common.py9
-rw-r--r--src/com.gluster.storage.management.server.scripts/src/common/DiskUtils.py192
-rwxr-xr-x[-rw-r--r--]src/com.gluster.storage.management.server.scripts/src/nodes/CreateVolumeExportDirectory.py65
-rw-r--r--src/com.gluster.storage.management.server.scripts/src/nodes/XmlHandler.py2
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java91
11 files changed, 389 insertions, 60 deletions
diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterUtil.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterUtil.java
index 35bba55d..d1533f25 100644
--- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterUtil.java
+++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterUtil.java
@@ -202,7 +202,7 @@ public class GlusterUtil {
return command;
}
- private Status createOptions(Volume volume) {
+ public Status createOptions(Volume volume) {
Map<String, String> options = volume.getOptions();
if (options != null) {
for (Entry<String, String> option : options.entrySet()) {
diff --git a/src/com.gluster.storage.management.gui/META-INF/MANIFEST.MF b/src/com.gluster.storage.management.gui/META-INF/MANIFEST.MF
index 2e59c854..13fb07dc 100644
--- a/src/com.gluster.storage.management.gui/META-INF/MANIFEST.MF
+++ b/src/com.gluster.storage.management.gui/META-INF/MANIFEST.MF
@@ -21,7 +21,8 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.6.1",
org.eclipse.birt.chart.device.swt;bundle-version="2.6.1",
com.ibm.icu;bundle-version="4.2.1",
com.richclientgui.rcptoolbox;bundle-version="1.0.5",
- org.eclipse.core.resources
+ org.eclipse.core.resources,
+ org.eclipse.equinox.common.source;bundle-version="3.6.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java
index adc98f98..1c5a3c72 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java
@@ -73,7 +73,7 @@ public abstract class AbstractActionDelegate implements IWorkbenchWindowActionDe
this.window = window;
}
- private Shell getShell() {
+ protected Shell getShell() {
if(window == null) {
return Display.getDefault().getActiveShell();
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/CreateVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/CreateVolumeAction.java
index 9ec500bc..7f06bc96 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/CreateVolumeAction.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/CreateVolumeAction.java
@@ -36,7 +36,7 @@ public class CreateVolumeAction extends AbstractActionDelegate {
public void run() {
CreateVolumeWizard wizard = new CreateVolumeWizard();
- WizardDialog dialog = new WizardDialog(window.getShell(), wizard);
+ WizardDialog dialog = new WizardDialog(getShell(), wizard);
dialog.create();
dialog.getShell().setSize(500, 550);
dialog.open();
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java
index b09bbb44..e880df36 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java
@@ -234,6 +234,7 @@ public class CreateVolumePage1 extends WizardPage {
new Label(container, SWT.NONE);
btnNfs = new Button(container, SWT.CHECK);
+ btnNfs.setEnabled(false);
btnNfs.setSelection(true);
btnNfs.setText("NFS");
@@ -251,7 +252,7 @@ public class CreateVolumePage1 extends WizardPage {
new Label(container, SWT.NONE);
Label lblAccessControlInfo = new Label(container, SWT.TOP);
lblAccessControlInfo.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
- lblAccessControlInfo.setText("(Comma separated list of IP addresses)");
+ lblAccessControlInfo.setText("(Comma separated list of IP addresses/Hostname)");
Label lblStartVolume = new Label(container, SWT.NONE);
lblStartVolume.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
@@ -270,9 +271,11 @@ public class CreateVolumePage1 extends WizardPage {
volume.setTransportType(TRANSPORT_TYPE.ETHERNET);
Set<NAS_PROTOCOL> nasProtocols = new HashSet<Volume.NAS_PROTOCOL>();
nasProtocols.add(NAS_PROTOCOL.GLUSTERFS);
- if(btnNfs.getSelection()) {
- nasProtocols.add(NAS_PROTOCOL.NFS);
- }
+ nasProtocols.add(NAS_PROTOCOL.NFS);
+
+// if(btnNfs.getSelection()) {
+// nasProtocols.add(NAS_PROTOCOL.NFS);
+// }
volume.setAccessControlList(txtAccessControl.getText());
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/details/VolumeOptionsPage.java
index 349c638a..2ab83789 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/details/VolumeOptionsPage.java
@@ -183,6 +183,76 @@ public class VolumeOptionsPage extends Composite {
return valueColumn.getColumn();
}
+ private class OptionValueEditingSupport extends EditingSupport {
+ private CellEditor cellEditor;
+
+ public OptionValueEditingSupport(ColumnViewer viewer) {
+ super(viewer);
+ cellEditor = new TextCellEditor((Composite) viewer.getControl());
+ }
+
+ @Override
+ protected void setValue(final Object element, final Object value) {
+ final Entry<String, String> entry = (Entry<String, String>)element;
+ if(entry.getValue().equals(value)) {
+ // value is same as that present in the model. return without doing anything.
+ return;
+ }
+
+ final Cursor oldCursor = getViewer().getControl().getCursor();
+ //getViewer().getControl().setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_WAIT));
+ // value has changed. set volume option at back-end and update model accordingly
+ BusyIndicator.showWhile(getDisplay(), new Runnable() {
+
+ @Override
+ public void run() {
+ VolumesClient client = new VolumesClient(GlusterDataModelManager.getInstance().getSecurityToken());
+ Status status = client.setVolumeOption(volume.getName(), entry.getKey(), (String)value);
+ if(status.isSuccess()) {
+ volume.setOption(entry.getKey(), (String)value);
+ } else {
+ MessageDialog.openError(getShell(), "Set Volume Option", status.getMessage());
+ }
+ getViewer().update(entry, null);
+ //getViewer().refresh();
+ //getViewer().getControl().setCursor(oldCursor);
+ }
+ });
+ }
+
+ @Override
+ protected Object getValue(Object element) {
+ return ((Entry<String, String>) element).getValue();
+ }
+
+ @Override
+ protected CellEditor getCellEditor(Object element) {
+ return cellEditor;
+ }
+
+ @Override
+ protected boolean canEdit(Object element) {
+ return true;
+ }
+ }
+
+ private TableColumn createValueColumn() {
+ TableViewerColumn valueColumn = new TableViewerColumn(tableViewer, SWT.NONE);
+ valueColumn.getColumn()
+ .setText(OPTIONS_TABLE_COLUMN_NAMES[OPTIONS_TABLE_COLUMN_INDICES.OPTION_VALUE.ordinal()]);
+ valueColumn.setLabelProvider(new ColumnLabelProvider() {
+ @Override
+ public String getText(Object element) {
+ return ((Entry<String, String>) element).getValue();
+ }
+ });
+
+ // User can edit value of a volume option
+ valueColumn.setEditingSupport(new OptionValueEditingSupport(valueColumn.getViewer()));
+
+ return valueColumn.getColumn();
+ }
+
private TableColumn createKeyColumn() {
TableViewerColumn keyColumn = new TableViewerColumn(tableViewer, SWT.NONE);
keyColumn.getColumn().setText(OPTIONS_TABLE_COLUMN_NAMES[OPTIONS_TABLE_COLUMN_INDICES.OPTION_KEY.ordinal()]);
diff --git a/src/com.gluster.storage.management.server.scripts/src/common/Common.py b/src/com.gluster.storage.management.server.scripts/src/common/Common.py
index 60f200fe..99c2f440 100644
--- a/src/com.gluster.storage.management.server.scripts/src/common/Common.py
+++ b/src/com.gluster.storage.management.server.scripts/src/common/Common.py
@@ -32,3 +32,12 @@ def log(priority, message=None):
else:
syslog.syslog(logPriority, logMessage)
return
+
+
+def stripEmptyLines(content):
+ ret = ""
+ for line in content.split("\n"):
+ if line.strip() != "":
+ ret += line
+ return ret
+
diff --git a/src/com.gluster.storage.management.server.scripts/src/common/DiskUtils.py b/src/com.gluster.storage.management.server.scripts/src/common/DiskUtils.py
new file mode 100644
index 00000000..bde12500
--- /dev/null
+++ b/src/com.gluster.storage.management.server.scripts/src/common/DiskUtils.py
@@ -0,0 +1,192 @@
+# 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 os
+import glob
+import dbus
+
+import Globals
+from Utils import *
+
+ONE_MB_SIZE = 1048576
+
+
+def _stripDev(device):
+ if isString(device) and device.startswith("/dev/"):
+ return device[5:]
+ return device
+
+
+def _addDev(deviceName):
+ if isString(deviceName) and not deviceName.startswith("/dev/"):
+ return "/dev/" + deviceName
+ return deviceName
+
+
+def getDeviceName(device):
+ if type(device) == type([]):
+ nameList = []
+ for d in device:
+ nameList.append(_stripDev(d))
+ return nameList
+ return _stripDev(device)
+
+
+def getDevice(deviceName):
+ if isString(deviceName):
+ return _addDev(deviceName)
+ if type(deviceName) == type([]):
+ nameList = []
+ for d in deviceName:
+ nameList.append(_addDev(d))
+ return nameList
+ return _addDev(deviceName)
+
+
+def getDiskPartitionByUuid(uuid):
+ uuidFile = "/dev/disk/by-uuid/%s" % uuid
+ if os.path.exists(uuidFile):
+ return getDeviceName(os.path.realpath(uuidFile))
+ return None
+
+
+def getUuidByDiskPartition(device):
+ for uuidFile in glob.glob("/dev/disk/by-uuid/*"):
+ if os.path.realpath(uuidFile) == device:
+ return os.path.basename(uuidFile)
+ return None
+
+
+def getDiskPartitionUuid(partition):
+ log("WARNING: getDiskPartitionUuid() is deprecated by getUuidByDiskPartition()")
+ return getUuidByDiskPartition(partition)
+
+
+def getDiskPartitionByLabel(label):
+ ## TODO: Finding needs to be enhanced
+ labelFile = "/dev/disk/by-label/%s" % label
+ if os.path.exists(labelFile):
+ return getDeviceName(os.path.realpath(labelFile))
+ return None
+
+
+def getDeviceByLabel(label):
+ log("WARNING: getDeviceByLabel() is deprecated by getDiskPartitionByLabel()")
+ return getDiskPartitionByLabel(label)
+
+
+def getDiskPartitionLabel(device):
+ rv = runCommandFG(["sudo", "e2label", device], stdout=True)
+ if rv["Status"] == 0:
+ return rv["Stdout"].strip()
+ return False
+
+
+def getRootPartition(fsTabFile=Globals.FSTAB_FILE):
+ fsTabEntryList = readFsTab(fsTabFile)
+ for fsTabEntry in fsTabEntryList:
+ if fsTabEntry["MountPoint"] == "/":
+ if fsTabEntry["Device"].startswith("UUID="):
+ return getDiskPartitionByUuid(fsTabEntry["Device"].split("UUID=")[-1])
+ if fsTabEntry["Device"].startswith("LABEL="):
+ return getDiskPartitionByLabel(fsTabEntry["Device"].split("LABEL=")[-1])
+ return getDeviceName(fsTabEntry["Device"])
+ return None
+
+
+def getOsDisk():
+ log("WARNING: getOsDisk() is deprecated by getRootPartition()")
+ return getRootPartition()
+
+
+def getDiskList(diskDeviceList=None):
+ diskDeviceList = getDevice(diskDeviceList)
+ if isString(diskDeviceList):
+ diskDeviceList = [diskDeviceList]
+
+ dbusSystemBus = dbus.SystemBus()
+ halObj = dbusSystemBus.get_object("org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager")
+ halManager = dbus.Interface(halObj, "org.freedesktop.Hal.Manager")
+ storageUdiList = halManager.FindDeviceByCapability("storage")
+
+ diskList = []
+ for udi in storageUdiList:
+ halDeviceObj = dbusSystemBus.get_object("org.freedesktop.Hal", udi)
+ halDevice = dbus.Interface(halDeviceObj,
+ "org.freedesktop.Hal.Device")
+ if halDevice.GetProperty("storage.drive_type") == "cdrom" or \
+ halDevice.GetProperty("block.is_volume"):
+ continue
+
+ disk = {}
+ disk["Device"] = str(halDevice.GetProperty('block.device'))
+ if diskDeviceList and disk["Device"] not in diskDeviceList:
+ continue
+ disk["Description"] = str(halDevice.GetProperty('storage.vendor')) + " " + str(halDevice.GetProperty('storage.model'))
+ if halDevice.GetProperty('storage.removable'):
+ disk["Size"] = long(halDevice.GetProperty('storage.removable.media_size'))
+ else:
+ disk["Size"] = long(halDevice.GetProperty('storage.size'))
+ disk["Interface"] = str(halDevice.GetProperty('storage.bus'))
+ disk["DriveType"] = str(halDevice.GetProperty('storage.drive_type'))
+ partitionList = []
+ partitionUdiList = halManager.FindDeviceStringMatch("info.parent", udi)
+ for partitionUdi in partitionUdiList:
+ partitionHalDeviceObj = dbusSystemBus.get_object("org.freedesktop.Hal",
+ partitionUdi)
+ partitionHalDevice = dbus.Interface(partitionHalDeviceObj,
+ "org.freedesktop.Hal.Device")
+ if not partitionHalDevice.GetProperty("block.is_volume"):
+ continue
+ partition = {}
+ partition["Device"] = str(partitionHalDevice.GetProperty('block.device'))
+ partition["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid'))
+ partition["Size"] = long(partitionHalDevice.GetProperty('volume.size'))
+ partition["Fstype"] = str(partitionHalDevice.GetProperty('volume.fstype'))
+ partition["Fsversion"] = str(partitionHalDevice.GetProperty('volume.fsversion'))
+ partition["Label"] = str(partitionHalDevice.GetProperty('volume.label'))
+ partition["Used"] = 0L
+ if partitionHalDevice.GetProperty("volume.is_mounted"):
+ rv = runCommandFG(["df", str(partitionHalDevice.GetProperty('volume.mount_point'))], stdout=True)
+ if rv["Status"] == 0:
+ try:
+ partition["Used"] = long(rv["Stdout"].split("\n")[1].split()[2])
+ except IndexError:
+ pass
+ except ValueError:
+ pass
+ partitionList.append(partition)
+ disk["Partitions"] = partitionList
+ diskList.append(disk)
+ return diskList
+
+
+def getMountPointByUuid(partitionUuid):
+ # check uuid in etc/fstab
+ try:
+ fstabEntries = open(Globals.FSTAB_FILE).readlines()
+ except IOError:
+ fstabEntries = []
+ found = False
+ for entry in fstabEntries:
+ entry = entry.strip()
+ if not entry:
+ continue
+ if entry.split()[0] == "UUID=" + partitionUuid:
+ return entry.split()[1]
+ return None
diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/CreateVolumeExportDirectory.py b/src/com.gluster.storage.management.server.scripts/src/nodes/CreateVolumeExportDirectory.py
index 611d9695..59dc3c19 100644..100755
--- a/src/com.gluster.storage.management.server.scripts/src/nodes/CreateVolumeExportDirectory.py
+++ b/src/com.gluster.storage.management.server.scripts/src/nodes/CreateVolumeExportDirectory.py
@@ -16,36 +16,55 @@
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
import os
+import sys
+import syslog
from XmlHandler import ResponseXml
-from optparse import OptionParser
+import DiskUtils
import Utils
+import Common
-def stripEmptyLines(content):
- ret = ""
- for line in content.split("\n"):
- if line.strip() != "":
- ret += line
- return ret
-
-def createDirectory(disk, volumename):
- dirname = "/export"
- if not os.path.isdir(dirname) or not os.path.isdir(disk):
- rs = ResponseXml()
- rs.appendTagRoute("code", 1)
- rs.appendTagRoute("message", "Disk is not mounted properly")
+def createDirectory(disk, volumeName):
+
+ # Retrieving disk uuid
+ diskUuid = DiskUtils.getUuidByDiskPartition(DiskUtils.getDevice(disk))
+
+ rs = ResponseXml()
+ if not diskUuid:
+ Common.log(syslog.LOG_ERR, "failed to find disk:%s uuid" % disk)
+ rs.appendTagRoute("status.code", "-1")
+ rs.appendTagRoute("status.message", "Error: Unable to find disk uuid")
+ return rs.toprettyxml()
+
+ # Retrieving disk mount point using disk uuid
+ diskMountPoint = DiskUtils.getMountPointByUuid(diskUuid)
+ if not os.path.exists(diskMountPoint):
+ Common.log(syslog.LOG_ERR, "failed to retrieve disk:%s mount point" % disk)
+ rs.appendTagRoute("status.code", "-1")
+ rs.appendTagRoute("status.message", "Error: Failed to retrieve disk details")
return rs.toprettyxml()
-
-
- if not os.path.isdir(dirname + "/" + disk + "/" + volumename + "/"):
- command = "mkdir " + volumename;
+
+ # creating volume directory under disk mount point
+ volumeDirectory = "%s/%s" % (diskMountPoint, volumeName)
+ if not os.path.exists(volumeDirectory):
+ command = ["sudo", "mkdir", volumeDirectory]
rv = Utils.runCommandFG(command, stdout=True, root=True)
- message = stripEmptyLines(rv["Stdout"])
+ message = Common.stripEmptyLines(rv["Stdout"])
if rv["Stderr"]:
- message += "Error: [" + stripEmptyLines(rv["Stderr"]) + "]"
- rs = ResponseXml()
+ error = Common.stripEmptyLines(rv["Stderr"])
+ message += "Error: [%s]" % (error)
+ Common.log(syslog.LOG_ERR, "failed to create volume directory %s, %s" % (volumeDirectory, error)
rs.appendTagRoute("status.code", rv["Status"])
rs.appendTagRoute("status.message", message)
return rs.toprettyxml()
-def main(disk, volumename):
- return createDirectory(disk, volumename) \ No newline at end of file
+def main():
+ if len(sys.argv) != 3:
+ print >> sys.stderr, "usage: %s <disk name> <volume name>" % sys.argv[0]
+ sys.exit(-1)
+
+ disk = sys.argv[1]
+ volumeName = sys.argv[2]
+ print createDirectory(disk, volumeName)
+ sys.exit(0)
+
+main()
diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/XmlHandler.py b/src/com.gluster.storage.management.server.scripts/src/nodes/XmlHandler.py
index d5a1fe19..72164ffb 100644
--- a/src/com.gluster.storage.management.server.scripts/src/nodes/XmlHandler.py
+++ b/src/com.gluster.storage.management.server.scripts/src/nodes/XmlHandler.py
@@ -343,4 +343,4 @@ def test():
networkInterfaces.appendChild(networkTag)
print rs.toprettyxml()
-test()
+#test()
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java
index 49fb1e0d..06406434 100644
--- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java
@@ -29,6 +29,7 @@ import static com.gluster.storage.management.core.constants.RESTConstants.SUBRES
import static com.gluster.storage.management.core.constants.RESTConstants.SUBRESOURCE_OPTIONS;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import javax.ws.rs.Consumes;
@@ -55,8 +56,9 @@ import com.sun.jersey.spi.resource.Singleton;
@Singleton
@Path(RESOURCE_PATH_VOLUMES)
public class VolumesResource {
- private static final String SCRIPT_NAME = "preVolumeCreate.py";
-
+ private static final String PREPARE_BRICK_SCRIPT = "preVolumeCreate.py";
+ private static final String VOLUME_DIRECTORY_CLEANUP_SCRIPT = "cleanupVolumeDirectoryCreate.py";
+
@InjectParam
private static ServerUtil serverUtil;
private final GlusterUtil glusterUtil = new GlusterUtil();
@@ -79,24 +81,28 @@ public class VolumesResource {
@Consumes(MediaType.TEXT_XML)
@Produces(MediaType.TEXT_XML)
public Status createVolume(Volume volume) {
- //Create the directories for the volume
- List<String> bricks = new ArrayList<String>();
- for(String disk : volume.getDisks()) {
-
- String brickNotation = prepareBrick(volume, disk);
- if (brickNotation != null) {
- bricks.add(brickNotation);
- } else {
- int failedIndex = volume.getDisks().indexOf(disk);
- // TODO: Perform cleanup on all previously prepared bricks
- // i.e. those disks with index < failedIndex
-
- return new Status(Status.STATUS_CODE_FAILURE, "Error while preparing disk [" + disk + "] for volume ["
- + volume.getName() + "]");
+ // Create the directories for the volume
+ List<String> disks = volume.getDisks();
+ Status result = createDirectory(disks, volume.getName());
+ if (result.isSuccess()) {
+ List<String> bricks = Arrays.asList(result.getMessage().split(", "));
+
+ result = glusterUtil.createVolume(volume, bricks);
+ if (!result.isSuccess()) {
+ // Perform cleanup on all nodes before returning
+ cleanupDirectory(disks, volume.getName(), disks.size());
+ return result;
}
}
-
- return glusterUtil.createVolume(volume, bricks);
+ // Only if volume creation is success, then call the volume set options
+ return glusterUtil.createOptions(volume);
+ }
+
+ @GET
+ @Path("{" + PATH_PARAM_VOLUME_NAME + "}")
+ @Produces(MediaType.TEXT_XML)
+ public Volume getVolume(@PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) {
+ return glusterUtil.getVolume(volumeName);
}
@GET
@@ -129,7 +135,7 @@ public class VolumesResource {
@FormParam(RESTConstants.FORM_PARAM_OPTION_VALUE) String value) {
return glusterUtil.setOption(volumeName, key, value);
}
-
+
@PUT
@Path("{" + PATH_PARAM_VOLUME_NAME + " }/" + SUBRESOURCE_OPTIONS)
@Produces(MediaType.TEXT_XML)
@@ -145,19 +151,48 @@ public class VolumesResource {
// whenever such a CLI command is made available in GlusterFS
return new VolumeOptionInfoListResponse(Status.STATUS_SUCCESS, volumeOptionsDefaults.getDefaults());
}
-
- private String prepareBrick(Volume vol, String disk) {
+
+ private Status prepareBrick(String disk, String volumeName) {
String serverName = disk.split(":")[0];
String diskName = disk.split(":")[1];
- Status result = (Status)serverUtil.executeOnServer(true, serverName, SCRIPT_NAME + " " + vol.getName() + " " + diskName, Status.class);
-
- if(result.isSuccess()) {
- return result.getMessage();
- } else {
- return null;
+ return (Status) serverUtil.executeOnServer(true, serverName, PREPARE_BRICK_SCRIPT + " " + volumeName + " "
+ + diskName, Status.class);
+ }
+
+ @SuppressWarnings("null")
+ private Status createDirectory(List<String> disks, String volumeName) {
+ List<String> brickNotation = null;
+ for (int i = 0; i < disks.size(); i++) {
+ Status result = prepareBrick(disks.get(i), volumeName);
+ if (result.isSuccess()) {
+ brickNotation.add(result.getMessage());
+ } else {
+ cleanupDirectory(disks, volumeName, i);
+ return new Status(Status.STATUS_CODE_FAILURE, "Error while preparing disk [" + disks.get(i)
+ + "] for volume [" + volumeName + "]");
+ }
}
+ return new Status(Status.STATUS_CODE_SUCCESS, brickNotation.toString());
+
}
-
+
+ private Status cleanupDirectory(List<String> disks, String volumeName, int maxIndex) {
+ String serverName, diskName, diskInfo[];
+ Status result;
+ for (int i = 0; i < maxIndex; i++) {
+ // TODO: Call to delete the volume directory
+ diskInfo = disks.get(i).split(":");
+ serverName = diskInfo[0];
+ diskName = diskInfo[1];
+ result = (Status) serverUtil.executeOnServer(true, serverName, VOLUME_DIRECTORY_CLEANUP_SCRIPT + " " + volumeName + " "
+ + diskName, Status.class);
+ if (!result.isSuccess()) {
+ return result;
+ }
+ }
+ return new Status(Status.STATUS_CODE_SUCCESS, "Directories cleanedup...");
+ }
+
public static void main(String[] args) {
VolumesResource vr = new VolumesResource();
VolumeListResponse response = vr.getAllVolumes();