From 1ddd638a2e2c6531535249cf2301e0c5a1b1c844 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 22 Jun 2011 21:06:30 +0530 Subject: Added functionalities to get partition details into get_server_details.py --- .../src/DiskUtils.py | 152 ++++++++++++++++++--- .../src/get_server_details.py | 41 +----- 2 files changed, 135 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py b/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py index 03c5019e..8571a807 100644 --- a/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py +++ b/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py @@ -21,19 +21,22 @@ import dbus import syslog import Globals import Common +import time import Utils +import Disk +import Protocol ONE_MB_SIZE = 1048576 def _stripDev(device): - if isString(device) and device.startswith("/dev/"): + if Utils.isString(device) and device.startswith("/dev/"): return device[5:] return device def _addDev(deviceName): - if isString(deviceName) and not deviceName.startswith("/dev/"): + if Utils.isString(deviceName) and not deviceName.startswith("/dev/"): return "/dev/" + deviceName return deviceName @@ -48,7 +51,7 @@ def getDeviceName(device): def getDevice(deviceName): - if isString(deviceName): + if Utils.isString(deviceName): return _addDev(deviceName) if type(deviceName) == type([]): nameList = [] @@ -73,7 +76,7 @@ def getUuidByDiskPartition(device): def getDiskPartitionUuid(partition): - log("WARNING: getDiskPartitionUuid() is deprecated by getUuidByDiskPartition()") + Utils.log("WARNING: getDiskPartitionUuid() is deprecated by getUuidByDiskPartition()") return getUuidByDiskPartition(partition) @@ -81,17 +84,18 @@ 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)) + if os.path.islink(labelFile): + return getDeviceName(os.path.realpath(labelFile)) return None def getDeviceByLabel(label): - log("WARNING: getDeviceByLabel() is deprecated by getDiskPartitionByLabel()") + Utils.log("WARNING: getDeviceByLabel() is deprecated by getDiskPartitionByLabel()") return getDiskPartitionByLabel(label) def getDiskPartitionLabel(device): - rv = runCommandFG(["sudo", "e2label", device], stdout=True) + rv = Utils.runCommandFG(["sudo", "e2label", device], stdout=True) if rv["Status"] == 0: return rv["Stdout"].strip() return False @@ -104,19 +108,21 @@ def getRootPartition(fsTabFile=Globals.FSTAB_FILE): if fsTabEntry["Device"].startswith("UUID="): return getDiskPartitionByUuid(fsTabEntry["Device"].split("UUID=")[-1]) if fsTabEntry["Device"].startswith("LABEL="): - return getDiskPartitionByLabel(fsTabEntry["Device"].split("LABEL=")[-1]) + partitionName = getDiskPartitionByLabel(fsTabEntry["Device"].split("LABEL=")[-1]) + if partitionName: + return partitionName return getDeviceName(fsTabEntry["Device"]) return None def getOsDisk(): - log("WARNING: getOsDisk() is deprecated by getRootPartition()") + Utils.log("WARNING: getOsDisk() is deprecated by getRootPartition()") return getRootPartition() -def getDiskList(diskDeviceList=None): +def getDiskInfo(diskDeviceList=None): diskDeviceList = getDevice(diskDeviceList) - if isString(diskDeviceList): + if Utils.isString(diskDeviceList): diskDeviceList = [diskDeviceList] dbusSystemBus = dbus.SystemBus() @@ -125,12 +131,15 @@ def getDiskList(diskDeviceList=None): halManager = dbus.Interface(halObj, "org.freedesktop.Hal.Manager") storageUdiList = halManager.FindDeviceByCapability("storage") + diskInfo = {} diskList = [] + totalDiskSpace = 0 + totalDiskUsage = 0 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 \ + if halDevice.GetProperty("storage.drive_type") in ["cdrom", "floppy"] or \ halDevice.GetProperty("block.is_volume"): continue @@ -142,11 +151,12 @@ def getDiskList(diskDeviceList=None): if halDevice.GetProperty('storage.removable'): disk["Size"] = long(halDevice.GetProperty('storage.removable.media_size')) else: - disk["Size"] = long(halDevice.GetProperty('storage.size')) + disk["Size"] = long(halDevice.GetProperty('storage.size')) / 1024**2 disk["Interface"] = str(halDevice.GetProperty('storage.bus')) disk["DriveType"] = str(halDevice.GetProperty('storage.drive_type')) partitionList = [] partitionUdiList = halManager.FindDeviceStringMatch("info.parent", udi) + diskSpaceInUse = 0 for partitionUdi in partitionUdiList: partitionHalDeviceObj = dbusSystemBus.get_object("org.freedesktop.Hal", partitionUdi) @@ -157,24 +167,36 @@ def getDiskList(diskDeviceList=None): partition = {} partition["Device"] = str(partitionHalDevice.GetProperty('block.device')) partition["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid')) - partition["Size"] = long(partitionHalDevice.GetProperty('volume.size')) + partition["Size"] = long(partitionHalDevice.GetProperty('volume.size')) / 1024**2 partition["Fstype"] = str(partitionHalDevice.GetProperty('volume.fstype')) partition["Fsversion"] = str(partitionHalDevice.GetProperty('volume.fsversion')) partition["Label"] = str(partitionHalDevice.GetProperty('volume.label')) + partition["mountPoint"] = str(partitionHalDevice.GetProperty('volume.mount_point')) + partition["readOnlyAccess"] = str(partitionHalDevice.GetProperty('volume.is_mounted_read_only')) partition["Used"] = 0L if partitionHalDevice.GetProperty("volume.is_mounted"): - rv = runCommandFG(["df", str(partitionHalDevice.GetProperty('volume.mount_point'))], stdout=True) + rv = Utils.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]) + partition["Used"] = long(rv["Stdout"].split("\n")[1].split()[2]) / 1024 + diskSpaceInUse += partition["Used"] except IndexError: pass except ValueError: pass partitionList.append(partition) disk["Partitions"] = partitionList + disk["Used"] = diskSpaceInUse + totalDiskSpace += disk["Size"] + totalDiskUsage += disk["Used"] diskList.append(disk) - return diskList + diskInfo["disks"] = diskList + diskInfo["totalDiskSpace"] = totalDiskSpace + diskInfo["diskSpaceInUse"] = totalDiskUsage + return diskInfo + +def getDiskList(diskDeviceList=None): + return diskInfo["disks"] def readFsTab(fsTabFile=Globals.FSTAB_FILE): try: @@ -252,7 +274,7 @@ def getDiskSizeInfo(partition): rv = Utils.runCommandFG(command, stdout=True, root=True) message = Common.stripEmptyLines(rv["Stdout"]) if rv["Stderr"]: - Common.log(syslog.LOG_ERR, "failed to get disk details. %s" % Common.stripEmptyLines(rv["Stdout"])) + Common.Utils.log(syslog.LOG_ERR, "failed to get disk details. %s" % Common.stripEmptyLines(rv["Stdout"])) return None, None, None for line in rv["Stdout"].split("\n"): tokens = line.split() @@ -282,7 +304,7 @@ def getDiskSizeInfo(partition): rv = Utils.runCommandFG(command, stdout=True, root=True) message = Common.stripEmptyLines(rv["Stdout"]) if rv["Stderr"]: - Common.log(syslog.LOG_ERR, "failed to get disk details. %s" % Common.stripEmptyLines(rv["Stdout"])) + Common.Utils.log(syslog.LOG_ERR, "failed to get disk details. %s" % Common.stripEmptyLines(rv["Stdout"])) return None, None, None lines = rv["Stdout"].split(";\n") @@ -303,6 +325,96 @@ def refreshHal(): rv = Utils.runCommandFG(["lshal"], stdout=True, root=True) if rv["Stderr"]: error = Common.stripEmptyLines(rv["Stderr"]) - Common.log(syslog.LOG_ERR, "failed to execute lshal command. Error: %s" % error) + Common.Utils.log(syslog.LOG_ERR, "failed to execute lshal command. Error: %s" % error) return False return True + + +def isDataDiskPartitionFormatted(device): + #Todo: Proper label needs to be added for data partition + #if getDiskPartitionLabel(device) != Globals.DATA_PARTITION_LABEL: + # return False + + diskObj = Disk.Disk() + for disk in diskObj.getMountableDiskList(): + if disk['device'].upper() == device.upper(): + mountPoint = disk['mount_point'] + if not mountPoint: + return False + if not os.path.exists(mountPoint): + return False + + uuid = getUuidByDiskPartition(device) + if not uuid: + return False + + for fsTabEntry in readFsTab(): + if fsTabEntry["Device"] == ("UUID=%s" % uuid) and fsTabEntry["MountPoint"] == mountPoint: + return True + return False + + +def getDiskDom(diskDeviceList=None, bootPartition=None, skipDisk=None): + diskDeviceList = getDevice(diskDeviceList) + if Utils.isString(diskDeviceList): + diskDeviceList = [diskDeviceList] + + if skipDisk: + skipDisk = getDevice(skipDisk) + if Utils.isString(skipDisk): + skipDisk = [skipDisk] + + diskInfo = getDiskInfo(diskDeviceList) + diskList = diskInfo["disks"] + if not diskList: + return None + + diskDom = Protocol.XDOM() + disksTag = diskDom.createTag("disks", None) + disksTag.appendChild(diskDom.createTag("totalDiskSpace", diskInfo["totalDiskSpace"])) + disksTag.appendChild(diskDom.createTag("diskSpaceInUse", diskInfo["diskSpaceInUse"])) + if not bootPartition: + bootPartition = getRootPartition() + for disk in diskList: + if skipDisk and disk["Device"] in skipDisk: + continue + diskTag = diskDom.createTag("disk", None) + diskTag.appendChild(diskDom.createTag("device", getDeviceName(disk["Device"]))) + diskTag.appendChild(diskDom.createTag("description", disk["Description"])) + diskTag.appendChild(diskDom.createTag("size", str(disk["Size"]))) + diskTag.appendChild(diskDom.createTag("used", str(disk["Used"]))) + diskTag.appendChild(diskDom.createTag("interface", disk["Interface"])) + if disk["Partitions"]: + diskTag.appendChild(diskDom.createTag("init", "yes")) + else: + diskTag.appendChild(diskDom.createTag("init", "no")) + for partition in disk["Partitions"]: + partitionTag = diskDom.createTag("partition", None) + device = getDeviceName(partition["Device"]) + partitionTag.appendChild(diskDom.createTag("name", device)) + partitionTag.appendChild(diskDom.createTag("mountPoint", partition['mountPoint'])) + if not partition["Uuid"]: + partitionTag.appendChild(diskDom.createTag("uuid", getUuidByDiskPartition("/dev/" + device))) + else: + partitionTag.appendChild(diskDom.createTag("uuid", partition["Uuid"])) + partitionTag.appendChild(diskDom.createTag("size", str(partition["Size"]))) + partitionTag.appendChild(diskDom.createTag("free", str((partition["Size"] - partition["Used"])))) + partitionTag.appendChild(diskDom.createTag("used", partition["Used"])) + partitionTag.appendChild(diskDom.createTag("filesystem", partition["Fstype"])) + partitionTag.appendChild(diskDom.createTag("readOnlyAccess", partition["readOnlyAccess"])) + if partition['mountPoint'] or isDataDiskPartitionFormatted(partition["Device"]): + partitionTag.appendChild(diskDom.createTag("status", "READY")) + else: + partitionTag.appendChild(diskDom.createTag("status", "UNINITIALIZED")) + if "/export/" in partition["mountPoint"]: + partitionTag.appendChild(diskDom.createTag("dataDisk", "True")) + else: + partitionTag.appendChild(diskDom.createTag("dataDisk", "False")) + if "/" == partition["mountPoint"]: + partitionTag.appendChild(diskDom.createTag("boot", "yes")) + else: + partitionTag.appendChild(diskDom.createTag("boot", "no")) + diskTag.appendChild(partitionTag) + disksTag.appendChild(diskTag) + diskDom.addTag(disksTag) + return diskDom diff --git a/src/com.gluster.storage.management.server.scripts/src/get_server_details.py b/src/com.gluster.storage.management.server.scripts/src/get_server_details.py index ce1d97e6..2ab3cdd4 100755 --- a/src/com.gluster.storage.management.server.scripts/src/get_server_details.py +++ b/src/com.gluster.storage.management.server.scripts/src/get_server_details.py @@ -33,7 +33,6 @@ from optparse import OptionParser def getServerDetails(listall): - serverName = socket.gethostname() meminfo = getMeminfo() cpu = 100 * float(getLoadavg()) @@ -94,10 +93,8 @@ def getServerDetails(listall): # refreshing hal data DiskUtils.refreshHal() - diskObj = Disk() - disks = diskObj.getMountableDiskList() - - if disks is None: + diskDom = DiskUtils.getDiskDom() + if not diskDom: print "No disk found!" syslog.syslog(syslog.LOG_ERR, "Error finding disk information of server:%s" % serverName) return None @@ -108,39 +105,7 @@ def getServerDetails(listall): serverTag.appendChild(responseDom.createTag("status", "ONLINE")) serverTag.appendChild(responseDom.createTag("uuid", None)) - totalDiskSpace = 0 - diskSpaceInUse = 0 - diskTag = responseDom.createTag("disks") - for disk in disks: - if not listall: - if not disk['mount_point'].startswith("/export/"): - continue - if disk['interface'] in ['usb', 'mmc']: - continue - partitionTag = responseDom.createTag("disk", None) - partitionTag.appendChild(responseDom.createTag("name", os.path.basename(disk['device']))) - partitionTag.appendChild(responseDom.createTag("mountPoint", disk['mount_point'])) - partitionTag.appendChild(responseDom.createTag("serverName", serverName)) - partitionTag.appendChild(responseDom.createTag("description", disk['description'])) - total, used, free = 0, 0, 0 - if disk['size']: - total, used, free = DiskUtils.getDiskSizeInfo(disk['device']) - if total: - partitionTag.appendChild(responseDom.createTag("space", str(total))) - totalDiskSpace += total - else: - partitionTag.appendChild(responseDom.createTag("space", "NA")) - if used: - partitionTag.appendChild(responseDom.createTag("spaceInUse", str(used))) - diskSpaceInUse += used - partitionTag.appendChild(responseDom.createTag("status", "AVAILABLE")) - else: - partitionTag.appendChild(responseDom.createTag("spaceInUse", "NA")) - partitionTag.appendChild(responseDom.createTag("status", "UNINITIALIZED")) - diskTag.appendChild(partitionTag) - serverTag.appendChild(diskTag) - serverTag.appendChild(responseDom.createTag("totalDiskSpace", str(totalDiskSpace))) - serverTag.appendChild(responseDom.createTag("diskSpaceInUse", str(diskSpaceInUse))) + serverTag.appendChild(diskDom.getElementsByTagRoute("disks")[0]) return serverTag def main(): -- cgit From 87167e5c2ab3c78738dd929a2844bad56700954f Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 5 Jul 2011 18:56:23 +0530 Subject: Updated DiskUtils with raid disk details and review changes --- .../src/DiskUtils.py | 499 ++++++++++++++++++--- .../src/NetworkUtils.py | 6 +- .../src/Utils.py | 318 +++++++++++++ 3 files changed, 760 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py b/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py index 8571a807..fc209c96 100644 --- a/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py +++ b/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py @@ -17,6 +17,7 @@ import os import glob +from copy import deepcopy import dbus import syslog import Globals @@ -25,6 +26,7 @@ import time import Utils import Disk import Protocol +from FsTabUtils import * ONE_MB_SIZE = 1048576 @@ -76,7 +78,7 @@ def getUuidByDiskPartition(device): def getDiskPartitionUuid(partition): - Utils.log("WARNING: getDiskPartitionUuid() is deprecated by getUuidByDiskPartition()") + Common.log("WARNING: getDiskPartitionUuid() is deprecated by getUuidByDiskPartition()") return getUuidByDiskPartition(partition) @@ -90,7 +92,7 @@ def getDiskPartitionByLabel(label): def getDeviceByLabel(label): - Utils.log("WARNING: getDeviceByLabel() is deprecated by getDiskPartitionByLabel()") + Common.log("WARNING: getDeviceByLabel() is deprecated by getDiskPartitionByLabel()") return getDiskPartitionByLabel(label) @@ -115,8 +117,45 @@ def getRootPartition(fsTabFile=Globals.FSTAB_FILE): return None +def getRaidDisk(): + array = [] + arrayList = [] + mdFound = False + + try: + fp = open("/proc/mdstat") + for line in fp: + str = line.strip() + if str.startswith("md"): + array.append(str) + mdFound = True + continue + if mdFound: + if str: + array.append(str) + else: + arrayList.append(array) + array = [] + mdFound = False + fp.close() + except IOError, e: + return None + + raidList = {} + for array in arrayList: + raid = {} + tokens = array[0].split() + raid['status'] = tokens[2] + raid['type'] = tokens[3] + + raid['disks'] = [x.split('[')[0] for x in tokens[4:]] + raid['size'] = float(array[1].split()[0]) / 1024.0 + raidList[tokens[0]] = raid + return raidList + + def getOsDisk(): - Utils.log("WARNING: getOsDisk() is deprecated by getRootPartition()") + Common.log("WARNING: getOsDisk() is deprecated by getRootPartition()") return getRootPartition() @@ -133,8 +172,6 @@ def getDiskInfo(diskDeviceList=None): diskInfo = {} diskList = [] - totalDiskSpace = 0 - totalDiskUsage = 0 for udi in storageUdiList: halDeviceObj = dbusSystemBus.get_object("org.freedesktop.Hal", udi) halDevice = dbus.Interface(halDeviceObj, @@ -142,7 +179,6 @@ def getDiskInfo(diskDeviceList=None): if halDevice.GetProperty("storage.drive_type") in ["cdrom", "floppy"] or \ halDevice.GetProperty("block.is_volume"): continue - disk = {} disk["Device"] = str(halDevice.GetProperty('block.device')) if diskDeviceList and disk["Device"] not in diskDeviceList: @@ -154,6 +190,18 @@ def getDiskInfo(diskDeviceList=None): disk["Size"] = long(halDevice.GetProperty('storage.size')) / 1024**2 disk["Interface"] = str(halDevice.GetProperty('storage.bus')) disk["DriveType"] = str(halDevice.GetProperty('storage.drive_type')) + disk["Status"] = None + if isDiskInFormatting(disk["Device"]): + disk["Status"] = "formatting in progress" + disk["Uuid"] = None + disk["Init"] = False + disk["Type"] = False + disk["FsType"] = None + disk["FsVersion"] = None + disk["MountPoint"] = None + disk["ReadOnlyAccess"] = None + disk["SpaceInUse"] = None + partitionList = [] partitionUdiList = halManager.FindDeviceStringMatch("info.parent", udi) diskSpaceInUse = 0 @@ -164,35 +212,61 @@ def getDiskInfo(diskDeviceList=None): "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')) / 1024**2 - partition["Fstype"] = str(partitionHalDevice.GetProperty('volume.fstype')) - partition["Fsversion"] = str(partitionHalDevice.GetProperty('volume.fsversion')) - partition["Label"] = str(partitionHalDevice.GetProperty('volume.label')) - partition["mountPoint"] = str(partitionHalDevice.GetProperty('volume.mount_point')) - partition["readOnlyAccess"] = str(partitionHalDevice.GetProperty('volume.is_mounted_read_only')) - partition["Used"] = 0L + partitionDevice = str(partitionHalDevice.GetProperty('block.device')) if partitionHalDevice.GetProperty("volume.is_mounted"): rv = Utils.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]) / 1024 - diskSpaceInUse += partition["Used"] + used = long(rv["Stdout"].split("\n")[1].split()[2]) / 1024 + diskSpaceInUse += used except IndexError: pass except ValueError: pass + + if disk["Device"] == partitionDevice: + disk["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid')) + disk["Init"] = True # TODO: use isDataDiskPartitionFormatted function to cross verify this! + mountPoint = str(partitionHalDevice.GetProperty('volume.mount_point')) + if "/export/" in mountPoint: + disk["Type"] = True + disk["FsType"] = str(partitionHalDevice.GetProperty('volume.fstype')) + disk["FsVersion"] = str(partitionHalDevice.GetProperty('volume.fsversion')) + disk["MountPoint"] = str(partitionHalDevice.GetProperty('volume.mount_point')) + disk["ReadOnlyAccess"] = str(partitionHalDevice.GetProperty('volume.is_mounted_read_only')) + if not disk["Size"]: + disk["Size"] = long(partitionHalDevice.GetProperty('volume.size')) / 1024**2 + disk["SpaceInUse"] = used + continue + + partition = {} + partition["Init"] = False + partition["Type"] = False + partition["Status"] = None + if isDiskInFormatting(partitionDevice): + partition["Status"] = "formatting in progress" + partition["Interface"] = None # Partition will not have bus details, info.interfaces can be used here! + partition["Device"] = partitionDevice + partition["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid')) + partition["Size"] = long(partitionHalDevice.GetProperty('volume.size')) / 1024**2 + partition["FsType"] = str(partitionHalDevice.GetProperty('volume.fstype')) + partition["FsVersion"] = str(partitionHalDevice.GetProperty('volume.fsversion')) + partition["Label"] = str(partitionHalDevice.GetProperty('volume.label')) + partition["MountPoint"] = str(partitionHalDevice.GetProperty('volume.mount_point')) + partition["Size"] = long(partitionHalDevice.GetProperty('volume.size')) / 1024**2 + partition["SpaceInUse"] = used + if partition["MountPoint"] or isDataDiskPartitionFormatted(partitionDevice): + partition["Init"] = True + if "/export/" in partition["MountPoint"]: + partition["Type"] = True + partition["ReadOnlyAccess"] = str(partitionHalDevice.GetProperty('volume.is_mounted_read_only')) + partitionList.append(partition) disk["Partitions"] = partitionList - disk["Used"] = diskSpaceInUse - totalDiskSpace += disk["Size"] - totalDiskUsage += disk["Used"] + if not disk["SpaceInUse"]: + disk["SpaceInUse"] = diskSpaceInUse diskList.append(disk) diskInfo["disks"] = diskList - diskInfo["totalDiskSpace"] = totalDiskSpace - diskInfo["diskSpaceInUse"] = totalDiskUsage return diskInfo def getDiskList(diskDeviceList=None): @@ -202,7 +276,7 @@ def readFsTab(fsTabFile=Globals.FSTAB_FILE): try: fsTabfp = open(fsTabFile) except IOError, e: - Utils.log("readFsTab(): " + str(e)) + Common.log("readFsTab(): " + str(e)) return None fsTabEntryList = [] @@ -228,7 +302,6 @@ def readFsTab(fsTabFile=Globals.FSTAB_FILE): pass if fsTabEntry["Device"] and fsTabEntry["MountPoint"] and fsTabEntry["FsType"] and fsTabEntry["Options"]: fsTabEntryList.append(fsTabEntry) - fsTabfp.close() return fsTabEntryList @@ -274,7 +347,7 @@ def getDiskSizeInfo(partition): rv = Utils.runCommandFG(command, stdout=True, root=True) message = Common.stripEmptyLines(rv["Stdout"]) if rv["Stderr"]: - Common.Utils.log(syslog.LOG_ERR, "failed to get disk details. %s" % Common.stripEmptyLines(rv["Stdout"])) + Common.log(syslog.LOG_ERR, "failed to get disk details. %s" % Common.stripEmptyLines(rv["Stdout"])) return None, None, None for line in rv["Stdout"].split("\n"): tokens = line.split() @@ -304,7 +377,7 @@ def getDiskSizeInfo(partition): rv = Utils.runCommandFG(command, stdout=True, root=True) message = Common.stripEmptyLines(rv["Stdout"]) if rv["Stderr"]: - Common.Utils.log(syslog.LOG_ERR, "failed to get disk details. %s" % Common.stripEmptyLines(rv["Stdout"])) + Common.log(syslog.LOG_ERR, "failed to get disk details. %s" % Common.stripEmptyLines(rv["Stdout"])) return None, None, None lines = rv["Stdout"].split(";\n") @@ -325,7 +398,7 @@ def refreshHal(): rv = Utils.runCommandFG(["lshal"], stdout=True, root=True) if rv["Stderr"]: error = Common.stripEmptyLines(rv["Stderr"]) - Common.Utils.log(syslog.LOG_ERR, "failed to execute lshal command. Error: %s" % error) + Common.log(syslog.LOG_ERR, "failed to execute lshal command. Error: %s" % error) return False return True @@ -369,52 +442,360 @@ def getDiskDom(diskDeviceList=None, bootPartition=None, skipDisk=None): if not diskList: return None + raidDiskPartitions = [] + raidDisk = getRaidDisk() + for partition in raidDisk.values(): + raidDiskPartitions += partition['disks'] + diskDom = Protocol.XDOM() disksTag = diskDom.createTag("disks", None) - disksTag.appendChild(diskDom.createTag("totalDiskSpace", diskInfo["totalDiskSpace"])) - disksTag.appendChild(diskDom.createTag("diskSpaceInUse", diskInfo["diskSpaceInUse"])) + raidPartitions = {} + raidDisks = {} if not bootPartition: bootPartition = getRootPartition() for disk in diskList: if skipDisk and disk["Device"] in skipDisk: continue diskTag = diskDom.createTag("disk", None) - diskTag.appendChild(diskDom.createTag("device", getDeviceName(disk["Device"]))) + diskDevice = getDeviceName(disk["Device"]) + diskTag.appendChild(diskDom.createTag("name", diskDevice)) diskTag.appendChild(diskDom.createTag("description", disk["Description"])) - diskTag.appendChild(diskDom.createTag("size", str(disk["Size"]))) - diskTag.appendChild(diskDom.createTag("used", str(disk["Used"]))) + diskTag.appendChild(diskDom.createTag("uuid", disk["Uuid"])) + diskTag.appendChild(diskDom.createTag("status", disk["Status"])) + diskTag.appendChild(diskDom.createTag("init", str(disk["Init"]).lower())) + diskTag.appendChild(diskDom.createTag("type", str(disk["Type"]).lower())) diskTag.appendChild(diskDom.createTag("interface", disk["Interface"])) - if disk["Partitions"]: - diskTag.appendChild(diskDom.createTag("init", "yes")) - else: - diskTag.appendChild(diskDom.createTag("init", "no")) + diskTag.appendChild(diskDom.createTag("fsType", disk["FsType"])) + diskTag.appendChild(diskDom.createTag("fsVersion", disk["FsVersion"])) + diskTag.appendChild(diskDom.createTag("mountPoint", disk["MountPoint"])) + diskTag.appendChild(diskDom.createTag("size", disk["Size"])) + diskTag.appendChild(diskDom.createTag("spaceInUse", disk["SpaceInUse"])) + partitionsTag = diskDom.createTag("partitions", None) for partition in disk["Partitions"]: partitionTag = diskDom.createTag("partition", None) device = getDeviceName(partition["Device"]) partitionTag.appendChild(diskDom.createTag("name", device)) - partitionTag.appendChild(diskDom.createTag("mountPoint", partition['mountPoint'])) - if not partition["Uuid"]: - partitionTag.appendChild(diskDom.createTag("uuid", getUuidByDiskPartition("/dev/" + device))) - else: + if partition["Uuid"]: #TODO: Move this verification and findings to getDiskInfo function partitionTag.appendChild(diskDom.createTag("uuid", partition["Uuid"])) - partitionTag.appendChild(diskDom.createTag("size", str(partition["Size"]))) - partitionTag.appendChild(diskDom.createTag("free", str((partition["Size"] - partition["Used"])))) - partitionTag.appendChild(diskDom.createTag("used", partition["Used"])) - partitionTag.appendChild(diskDom.createTag("filesystem", partition["Fstype"])) - partitionTag.appendChild(diskDom.createTag("readOnlyAccess", partition["readOnlyAccess"])) - if partition['mountPoint'] or isDataDiskPartitionFormatted(partition["Device"]): - partitionTag.appendChild(diskDom.createTag("status", "READY")) - else: - partitionTag.appendChild(diskDom.createTag("status", "UNINITIALIZED")) - if "/export/" in partition["mountPoint"]: - partitionTag.appendChild(diskDom.createTag("dataDisk", "True")) else: - partitionTag.appendChild(diskDom.createTag("dataDisk", "False")) - if "/" == partition["mountPoint"]: - partitionTag.appendChild(diskDom.createTag("boot", "yes")) - else: - partitionTag.appendChild(diskDom.createTag("boot", "no")) - diskTag.appendChild(partitionTag) - disksTag.appendChild(diskTag) + partitionTag.appendChild(diskDom.createTag("uuid", getUuidByDiskPartition("/dev/" + device))) + partitionTag.appendChild(diskDom.createTag("status", partition["Status"])) + partitionTag.appendChild(diskDom.createTag("init", str(partition["Init"]).lower())) + partitionTag.appendChild(diskDom.createTag("type", str(partition["Type"]).lower())) + partitionTag.appendChild(diskDom.createTag("interface", partition["Interface"])) + partitionTag.appendChild(diskDom.createTag("filesystem", partition["FsType"])) + partitionTag.appendChild(diskDom.createTag("mountPoint", partition['MountPoint'])) + partitionTag.appendChild(diskDom.createTag("size", partition["Size"])) + partitionTag.appendChild(diskDom.createTag("spaceInUse", partition["SpaceInUse"])) + if device in raidDiskPartitions: + raidPartitions[device] = partitionTag + continue + partitionsTag.appendChild(partitionTag) + diskTag.appendChild(partitionsTag) + + if diskDevice in raidDiskPartitions: + raidDisks[diskDevice] = diskTag + else: + disksTag.appendChild(diskTag) + + + for rdisk in raidDisk.keys(): + raidDiskTag = diskDom.createTag("disk", None) + raidDiskTag.appendChild(diskDom.createTag("name", rdisk)) + if 'active' == raidDisk[rdisk]['status']: + raidDiskTag.appendChild(diskDom.createTag("status", "true")) + else: + raidDiskTag.appendChild(diskDom.createTag("status", "false")) + raidDiskTag.appendChild(diskDom.createTag("interface", raidDisk[rdisk]['type'])) + raidDiskTag.appendChild(diskDom.createTag("size", raidDisk[rdisk]['size'])) + raidDisksTag = diskDom.createTag("raidDisks", None) + raidDiskPartitionsTag = diskDom.createTag("partitions", None) + for disk in raidDisk[rdisk]['disks']: + if raidPartitions.has_key(disk): + raidDiskPartitionsTag.appendChild(raidPartitions[disk]) + if raidDisks.has_key(disk): + raidDisksTag.appendChild(raidDisks[disk]) + raidDisksTag.appendChild(raidDiskPartitionsTag) + raidDiskTag.appendChild(raidDisksTag) + disksTag.appendChild(raidDiskTag) + #disksTag.appendChild(raidDisksTag) diskDom.addTag(disksTag) return diskDom + + +def initializeDisk(disk, boot=False, startSize=0, sudo=False): + if boot and startSize > 0: + return False + + disk = getDevice(disk) + diskObj = getDiskList(disk)[0] + + if boot or startSize == 0: + command = "dd if=/dev/zero of=%s bs=1024K count=1" % diskObj["Device"] + if runCommandFG(command, root=sudo) != 0: + if boot: + Common.log("failed to clear boot sector of disk %s" % diskObj["Device"]) + return False + Common.log("failed to clear boot sector of disk %s. ignoring" % diskObj["Device"]) + + command = "parted -s %s mklabel gpt" % diskObj["Device"] + if runCommandFG(command, root=sudo) != 0: + return False + + if boot: + command = "parted -s %s mkpart primary ext3 0MB %sMB" % (diskObj["Device"], Globals.OS_PARTITION_SIZE) + if runCommandFG(command, root=sudo) != 0: + return False + command = "parted -s %s set 1 boot on" % (diskObj["Device"]) + if runCommandFG(command, root=sudo) != 0: + return False + startSize = Globals.OS_PARTITION_SIZE + + size = (diskObj["Size"] / ONE_MB_SIZE) - startSize + while size > Globals.MAX_PARTITION_SIZE: + endSize = startSize + Globals.MAX_PARTITION_SIZE + command = "parted -s %s mkpart primary ext3 %sMB %sMB" % (diskObj["Device"], startSize, endSize) + if runCommandFG(command, root=sudo) != 0: + return False + size -= Globals.MAX_PARTITION_SIZE + startSize = endSize + + if size: + command = "parted -s %s mkpart primary ext3 %sMB 100%%" % (diskObj["Device"], startSize) + if runCommandFG(command, root=sudo) != 0: + return False + + if runCommandFG("udevadm settle", root=sudo) != 0: + if runCommandFG("udevadm settle", root=sudo) != 0: + Common.log("udevadm settle for disk %s failed. ignoring" % diskObj["Device"]) + time.sleep(1) + + if runCommandFG("partprobe %s" % diskObj["Device"], root=sudo) != 0: + Common.log("partprobe %s failed" % diskObj["Device"]) + return False + + if runCommandFG("gptsync %s" % diskObj["Device"], root=sudo) != 0: + Common.log("gptsync %s failed. ignoring" % diskObj["Device"]) + + # wait forcefully to appear devices in /dev + time.sleep(2) + return True + + +def initializeOsDisk(diskObj): + Common.log("WARNING: initializeOsDisk() is deprecated by initializeDisk(boot=True)") + return initializeDisk(diskObj, boot=True) + + +def initializeDataDisk(diskObj): + Common.log("WARNING: initializeDataDisk() is deprecated by initializeDisk()") + return initializeDisk(diskObj) + +def getBootPartition(serverName): + diskDom = XDOM() + diskDom.parseFile("%s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)) + if not diskDom: + return None + partitionDom = XDOM() + partitionUuid = None + partitionName = None + for partitionTag in diskDom.getElementsByTagRoute("disk.partition"): + partitionDom.setDomObj(partitionTag) + boot = partitionDom.getTextByTagRoute("boot") + if boot and boot.strip().upper() == 'YES': + partitionUuid = partitionDom.getTextByTagRoute("uuid") + partitionName = partitionDom.getTextByTagRoute("device") + break + if not (partitionUuid and partitionName): + return None + + # check device label name + deviceBaseName = os.path.basename(partitionName) + process = runCommandBG(['sudo', 'e2label', partitionName]) + if type(process) == type(True): + return None + if process.wait() != 0: + return None + output = process.communicate() + deviceLabel = output[0].split()[0] + if deviceLabel != Globals.BOOT_PARTITION_LABEL: + return None + + # 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: + found = True + break + if not found: + return None + return partitionName + + +def isDiskInFormatting(device): + DEVICE_FORMAT_LOCK_FILE = "/var/lock/%s.lock" % device + return os.path.exists(DEVICE_FORMAT_LOCK_FILE) + + +def isDiskInFormat(device): + Common.log("WARNING: isDiskInFormat() is deprecated by isDataDiskPartitionFormatted()") + return isDataDiskPartitionFormatted(device) + + +def diskOrder(serverExportList): + newServerExportList = [] + while serverExportList: + serverExport = deepcopy(serverExportList[0]) + if newServerExportList and serverExport.split(":")[0] == newServerExportList[-1].split(":")[0]: + inserted = False + for i in range(0, len(newServerExportList) - 1): + if serverExport.split(":")[0] == newServerExportList[i].split(":")[0]: + continue + if i == 0: + newServerExportList.insert(i, serverExport) + inserted = True + break + if serverExport.split(":")[0] == newServerExportList[i - 1].split(":")[0]: + continue + newServerExportList.insert(i, serverExport) + inserted = True + break + if not inserted: + newServerExportList.append(serverExport) + else: + newServerExportList.append(serverExport) + serverExportList.remove(serverExport) + i = 0 + while serverExportList and i < len(serverExportList): + if serverExport.split(":")[0] == serverExportList[i].split(":")[0]: + i += 1 + continue + serverExport = deepcopy(serverExportList[i]) + newServerExportList.append(serverExport) + serverExportList.remove(serverExport) + return newServerExportList + + +def updateServerDiskConfig(serverName, diskDom, requestFlag=True, partitionFlag=True): + command = "command.server." + if not requestFlag: + command = "" + diskList = {} + for tagE in diskDom.getElementsByTagRoute(command + "disk"): + diskList[diskDom.getTextByTagRoute(command + "device")] = tagE + configDom = XDOM() + if not configDom.parseFile("%s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)): + return diskDom.writexml("%s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)) + diskTag = configDom.getElementsByTagRoute("disks.disk") + disks = configDom.getElementsByTagRoute("disks") + if not (diskTag or disks): + return None + for tagE in diskTag: + diskDom = XDOM() + diskDom.setDomObj(tagE) + device = diskDom.getTextByTagRoute("device") + if partitionFlag and device in diskList: + disks[0].removeChild(tagE) + disks[0].appendChild(deepcopy(diskList[device])) + continue + if not partitionFlag and device in diskList: + partitionList = [] + for childNodeTag in tagE.childNodes: + if childNodeTag.nodeName == 'partition': + partitionList.append(childNodeTag) + tagE.childNodes = [] + tagE.childNodes = diskList[device].childNodes + partitionList + return configDom.writexml("%s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)) + + +def compareDisksDom(diskDomA, diskDomB, requestFlag=True): + command = "command.server.disk." + if not requestFlag: + command = "" + sourceDiskList = {} + sourceDisk = {} + for tagE in diskDomA.getElementsByTagRoute("disk"): + sourceDisk["description"] = diskDomA.getTextByTagRoute("description") + sourceDisk["size"] = diskDomA.getTextByTagRoute("size") + sourceDisk["init"] = diskDomA.getTextByTagRoute("init") + sourceDisk["interface"] = diskDomA.getTextByTagRoute("interface") + sourceDiskList[diskDomA.getTextByTagRoute("device")] = sourceDisk + objDiskList = {} + objDisk = {} + for tagE in diskDomB.getElementsByTagRoute("disk"): + objDisk["description"] = diskDomB.getTextByTagRoute("description") + objDisk["size"] = diskDomB.getTextByTagRoute("size") + objDisk["init"] = diskDomB.getTextByTagRoute("init") + objDisk["interface"] = diskDomB.getTextByTagRoute("interface") + objDiskList[diskDomB.getTextByTagRoute("device")] = objDisk + return sourceDiskList == objDiskList + + +def compareDiskDom(diskDomA, diskDomB, requestFlag=True): + command = "command.server.disk." + if not requestFlag: + command = "" + sourceDisk = {} + sourceDisk["device"] = diskDomA.getTextByTagRoute("device") + sourceDisk["description"] = diskDomA.getTextByTagRoute("description") + sourceDisk["size"] = diskDomA.getTextByTagRoute("size") + sourceDisk["init"] = diskDomA.getTextByTagRoute("init") + sourceDisk["interface"] = diskDomA.getTextByTagRoute("interface") + for tagE in diskDomA.getElementsByTagRoute("partition"): + sourceDiskPartitions = {} + partitionDom = XDOM() + partitionDom.setDomObj(tagE) + sourceDiskPartitions["size"] = partitionDom.getTextByTagRoute("size") + #sourceDiskPartitions["free"] = partitionDom.getTextByTagRoute("free") + sourceDiskPartitions["format"] = partitionDom.getTextByTagRoute("format") + sourceDiskPartitions["uuid"] = partitionDom.getTextByTagRoute("uuid") + sourceDisk[partitionDom.getTextByTagRoute("device")] = sourceDiskPartitions + + objDisk = {} + objDisk["device"] = diskDomB.getTextByTagRoute(command + "device") + objDisk["description"] = diskDomB.getTextByTagRoute(command + "description") + objDisk["size"] = diskDomB.getTextByTagRoute(command + "size") + objDisk["init"] = diskDomB.getTextByTagRoute(command + "init") + objDisk["interface"] = diskDomB.getTextByTagRoute(command + "interface") + for tagE in diskDomB.getElementsByTagRoute(command + "partition"): + objDiskPartitions = {} + partitionDom = XDOM() + partitionDom.setDomObj(tagE) + objDiskPartitions["size"] = partitionDom.getTextByTagRoute("size") + #objDiskPartitions["free"] = partitionDom.getTextByTagRoute("free") + objDiskPartitions["format"] = partitionDom.getTextByTagRoute("format") + objDiskPartitions["uuid"] = partitionDom.getTextByTagRoute("uuid") + objDisk[partitionDom.getTextByTagRoute("device")] = objDiskPartitions + return sourceDisk == objDisk + + +def getServerConfigDiskDom(serverName, diskName=None): + diskConfigDom = XDOM() + if not diskConfigDom.parseFile("%s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)): + Common.log("Unable to parse %s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)) + return None + diskTag = diskConfigDom.getElementsByTagRoute("disks.disk") + if not diskTag: + Common.log("Unable to reterive disk information %s/%s/disk.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)) + return None + if diskName: + for tagE in diskTag: + diskDom = XDOM() + diskDom.setDomObj(tagE) + if diskName == diskDom.getTextByTagRoute("device"): + return diskDom + return None + + for tagE in diskTag: + for partitionTag in tagE.getElementsByTagName("partition"): + tagE.removeChild(partitionTag) + return diskConfigDom + + diff --git a/src/com.gluster.storage.management.server.scripts/src/NetworkUtils.py b/src/com.gluster.storage.management.server.scripts/src/NetworkUtils.py index 7a854564..da212a9b 100755 --- a/src/com.gluster.storage.management.server.scripts/src/NetworkUtils.py +++ b/src/com.gluster.storage.management.server.scripts/src/NetworkUtils.py @@ -194,7 +194,7 @@ def getNetSpeed(deviceName): for line in rv["Stdout"].split("\n"): tokens = line.strip().split(":") if tokens[0].upper() == "SPEED": - return tokens[1].strip().upper() + return tokens[1].strip().upper().split("MB")[0] return None def getLinkStatus(deviceName): @@ -264,9 +264,7 @@ def setBondMode(deviceName, mode, fileName=None): def getNetDeviceList(root=""): netDeviceList = [] - for deviceName in os.listdir("/sys/class/net/"): - #for device in getHardwareList(): netDevice = {} netDevice["device"] = None netDevice["description"] = None @@ -298,11 +296,11 @@ def getNetDeviceList(root=""): netDevice["mode"] = getBondMode(deviceName, root + Globals.MODPROBE_CONF_FILE) netDevice["model"] = getNetModel(deviceName) netDevice["speed"] = getNetSpeed(deviceName) - try: netDevice["hwaddr"] = open("/sys/class/net/%s/address" % deviceName).read().strip() except IOError: pass + netDeviceList.append(netDevice) conf = readIfcfgConfFile(deviceName, root) diff --git a/src/com.gluster.storage.management.server.scripts/src/Utils.py b/src/com.gluster.storage.management.server.scripts/src/Utils.py index 6e33af0b..38d009f6 100644 --- a/src/com.gluster.storage.management.server.scripts/src/Utils.py +++ b/src/com.gluster.storage.management.server.scripts/src/Utils.py @@ -712,3 +712,321 @@ def isLiveMode(): def convertKbToMb(kb): return kb / 1024.0 + + +def getIPIndex(indexFile): + try: + fp = open(indexFile) + line = fp.readline() + fp.close() + index = int(line) + except IOError: + index = 0 + except ValueError: + index = False + return index + +def setIPIndex(index, indexFile): + try: + fp = open(indexFile, "w") + fp.write(str(index)) + fp.close() + except IOError: + return False + return True + +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 hasEntryFoundInFile(searchString, dnsEntryFileName): + try: + addServerEntryList = open(dnsEntryFileName).read().split() + except IOError: + return None + if searchString in addServerEntryList: + return True + return False + + +def computeIpAddress(ipAddress, startIp, endIp): + startIpNumber = IP2Number(startIp) + endIpNumber = IP2Number(endIp) + if not ipAddress: + return startIp + nextIpNumber = IP2Number(ipAddress) + while True: + nextIpNumber = nextIpNumber + 1 + ipAddress = Number2IP(nextIpNumber) + rv = runCommandFG(["ping", "-qnc", "1", ipAddress]) + if type(rv) == type(True): + return False + if rv != 0: + break + + if nextIpNumber >= startIpNumber and nextIpNumber <= endIpNumber: + return ipAddress + + nextIpNumber = IP2Number(startIp) + while True: + ipAddress = Number2IP(nextIpNumber) + nextIpNumber = nextIpNumber + 1 + rv = runCommandFG(["ping", "-qnc", "1", ipAddress]) + if type(rv) == type(True): + return False + if rv != 0: + break + + if IP2Number(ipAddress) >= startIpNumber and IP2Number(ipAddress) <= endIpNumber: + return ipAddress + return False + + +def setHostNameAndIp(hostName, ipAddress, lastAddServerDetailFile): + try: + fp = open(lastAddServerDetailFile, "w") + fp.write("HOSTNAME=" + hostName + "\n") + fp.write("IPADDRESS=" + ipAddress); + fp.close() + except IOError: + return False + return True + +def getPort(): + try: + fd = open(Globals.PORT_FILE, "r") + portString = fd.readline() + fd.close() + port = int(portString) + except IOError: + port = Globals.DEFAULT_PORT - 2 + except ValueError: + port = Globals.DEFAULT_PORT - 2 + return port + +def setPort(port): + try: + fd = open(Globals.PORT_FILE, "w") + fd.write(str(port)) + fd.close() + except IOError: + return False + return True + +def getServerAgentCredentials(): + try: + lines = open(Globals.SERVERAGENT_AUTH_FILE).readlines() + except IOError: + return None,None + + userName = None + password = None + + for l in lines: + if l[-1] == '\n': + l = l[:-1] + k = l[:l.index('=')] + v = l[l.index('=') + 1:] + if v[0] == "'" or v[0] == '"': + v = v[1:] + if v[-1] == "'" or v[-1] == '"': + v = v[:-1] + if k.upper() == "AGENT_ID": + userName = v + if k.upper() == "AGENT_PASSWORD": + password = v + + return userName, password + +def getGatewayAgentCredentials(): + try: + lines = open(Globals.GATEWAYAGENT_AUTH_FILE).readlines() + except IOError: + return None + + #userName = None + password = None + + for l in lines: + if l[-1] == '\n': + l = l[:-1] + k = l[:l.index('=')] + v = l[l.index('=') + 1:] + if v[0] == "'" or v[0] == '"': + v = v[1:] + if v[-1] == "'" or v[-1] == '"': + v = v[:-1] + #if k.upper() == "AGENT_ID": + # userName = v + if k.upper() == "AGENT_PASSWORD": + password = v + + return password + +def getWebAgentCredentials(): + try: + lines = open(Globals.WEBAGENT_AUTH_FILE).readlines() + except IOError: + return None,None + + userName = None + password = None + + for l in lines: + if l[-1] == '\n': + l = l[:-1] + k = l[:l.index('=')] + v = l[l.index('=') + 1:] + if v[0] == "'" or v[0] == '"': + v = v[1:] + if v[-1] == "'" or v[-1] == '"': + v = v[:-1] + if k.upper() == "AGENT_ID": + userName = v + if k.upper() == "AGENT_PASSWORD": + password = v + + return userName, password + +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 getFreeIpAddress(): + startRange, endRange = getStoragePoolInfo() + if not (startRange and endRange): + return None + + startIpNumber = IP2Number(startRange) + endIpNumber = IP2Number(endRange) + + for ipNumber in range(endIpNumber, startIpNumber, -1): + rv = runCommandFG(["ping", "-qnc", "1", Number2IP(ipNumber)]) + if type(rv) == type(True): + return None + if rv != 0: + return Number2IP(ipNumber) + return None + +def getDhcpServerStatus(): + status = runCommandFG(["sudo", "service", "dnsmasq", " status"]) + if type(status) == type(True) or 0 != status: + return False + return True + +def startDhcpServer(): + status = runCommandFG(["sudo", "service", "dnsmasq", " start"]) + if type(status) == type(True) or 0 != status: + return False + return True + +def stopDhcpServer(): + status = runCommandFG(["sudo", "service", "dnsmasq", " stop"]) + if type(status) == type(True) or 0 != status: + return False + return True + +def getStoragePoolInfo(): + startRange = None + endRange = None + try: + for line in open(Globals.GLUSTER_SERVER_POOL_FILE): + tokens = line.split("=") + if tokens[0] == "STARTRANGE": + startRange = tokens[1].strip() + if tokens[0] == "ENDRANGE": + endRange = tokens[1].strip() + except IOError: + log(syslog.LOG_ERR, "unable to read %s file" % Globals.GLUSTER_SERVER_POOL_FILE) + return startRange, endRange + +def configureDnsmasq(serverIpAddress, dhcpIpAddress): + dnsmasqConfFile = Globals.GLUSTER_CONF_CONF_DIR + "/dnsmasq.conf" + serverPortString = "68" + try: + for arg in open("/proc/cmdline").read().strip().split(): + token = arg.split("=") + if token[0] == "dhcp": + serverPortString = token[1] + break + except IOError: + log(syslog.LOG_ERR, "Failed to read /proc/cmdline. Continuing with default port 68") + try: + serverPort = int(serverPortString) + except ValueError: + log(syslog.LOG_ERR, "Invalid dhcp port '%s' in /proc/cmdline. Continuing with default port 68" % serverPortString) + serverPort = 68 + + try: + fp = open(dnsmasqConfFile, "w") + fp.write("no-hosts\n") + #fp.write("addn-hosts=%s\n" % Globals.GLUSTER_DNS_ENTRIES) + fp.write("bind-interfaces\n") + fp.write("except-interface=lo\n") + fp.write("dhcp-range=%s,%s\n" % (dhcpIpAddress, dhcpIpAddress)) + fp.write("dhcp-lease-max=1\n") + #fp.write("dhcp-option=option:router,%s\n" % serverIp) + #fp.write("dhcp-option=option:ntp-server,%s\n" % serverIp) + fp.write("dhcp-alternate-port=%s\n" % serverPort) + fp.write("server=%s\n" % serverIpAddress) + fp.write("dhcp-script=/usr/sbin/server-info\n") + fp.close() + except IOError: + log(syslog.LOG_ERR, "unable to write dnsmasq configuration %s" % dnsmasqConfFile) + return False + status = runCommandFG(["sudo", "cp", "-f", Globals.GLUSTER_CONF_CONF_DIR + "/dnsmasq.conf", Globals.DNSMASQ_CONF_FILE]) + if type(status) == type(True) or 0 != status: + log(syslog.LOG_ERR, "unable to copy dnsmasq configuration to " + Globals.DNSMASQ_CONF_FILE) + return False + return True + +def configureDhcpServer(serverIpAddress, dhcpIpAddress): + return configureDnsmasq(serverIpAddress, dhcpIpAddress) -- cgit From 5eabbd68b7036ef452847649f25af5f1e26e69db Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 6 Jul 2011 20:36:20 +0530 Subject: Updated DiskUtils with raid disk details and review changes. --- .../src/DiskUtils.py | 27 ++++++++-------------- .../src/get_server_details.py | 18 ++++----------- 2 files changed, 14 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py b/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py index fc209c96..f548cb7f 100644 --- a/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py +++ b/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py @@ -190,9 +190,9 @@ def getDiskInfo(diskDeviceList=None): disk["Size"] = long(halDevice.GetProperty('storage.size')) / 1024**2 disk["Interface"] = str(halDevice.GetProperty('storage.bus')) disk["DriveType"] = str(halDevice.GetProperty('storage.drive_type')) - disk["Status"] = None + disk["Status"] = "UNINITIALIZED" if isDiskInFormatting(disk["Device"]): - disk["Status"] = "formatting in progress" + disk["Status"] = "FORMATTING IN PROGRESS" disk["Uuid"] = None disk["Init"] = False disk["Type"] = False @@ -226,10 +226,12 @@ def getDiskInfo(diskDeviceList=None): if disk["Device"] == partitionDevice: disk["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid')) - disk["Init"] = True # TODO: use isDataDiskPartitionFormatted function to cross verify this! + disk["Init"] = True # TODO: use isDataDiskPartitionFormatted function to cross verify this + disk["Status"] = "INITIALIZED" mountPoint = str(partitionHalDevice.GetProperty('volume.mount_point')) if "/export/" in mountPoint: disk["Type"] = True + disk["Status"] = "READY" disk["FsType"] = str(partitionHalDevice.GetProperty('volume.fstype')) disk["FsVersion"] = str(partitionHalDevice.GetProperty('volume.fsversion')) disk["MountPoint"] = str(partitionHalDevice.GetProperty('volume.mount_point')) @@ -242,9 +244,9 @@ def getDiskInfo(diskDeviceList=None): partition = {} partition["Init"] = False partition["Type"] = False - partition["Status"] = None + partition["Status"] = "UNINITIALIZED" if isDiskInFormatting(partitionDevice): - partition["Status"] = "formatting in progress" + partition["Status"] = "FORMATTING IN PROGRESS" partition["Interface"] = None # Partition will not have bus details, info.interfaces can be used here! partition["Device"] = partitionDevice partition["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid')) @@ -257,10 +259,11 @@ def getDiskInfo(diskDeviceList=None): partition["SpaceInUse"] = used if partition["MountPoint"] or isDataDiskPartitionFormatted(partitionDevice): partition["Init"] = True + partition["Status"] = "INITIALIZED" if "/export/" in partition["MountPoint"]: partition["Type"] = True + partition["Status"] = "READY" partition["ReadOnlyAccess"] = str(partitionHalDevice.GetProperty('volume.is_mounted_read_only')) - partitionList.append(partition) disk["Partitions"] = partitionList if not disk["SpaceInUse"]: @@ -394,15 +397,6 @@ def getDiskSizeInfo(partition): return total, used, free -def refreshHal(): - rv = Utils.runCommandFG(["lshal"], stdout=True, root=True) - if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) - Common.log(syslog.LOG_ERR, "failed to execute lshal command. Error: %s" % error) - return False - return True - - def isDataDiskPartitionFormatted(device): #Todo: Proper label needs to be added for data partition #if getDiskPartitionLabel(device) != Globals.DATA_PARTITION_LABEL: @@ -483,7 +477,7 @@ def getDiskDom(diskDeviceList=None, bootPartition=None, skipDisk=None): partitionTag.appendChild(diskDom.createTag("init", str(partition["Init"]).lower())) partitionTag.appendChild(diskDom.createTag("type", str(partition["Type"]).lower())) partitionTag.appendChild(diskDom.createTag("interface", partition["Interface"])) - partitionTag.appendChild(diskDom.createTag("filesystem", partition["FsType"])) + partitionTag.appendChild(diskDom.createTag("fsType", partition["FsType"])) partitionTag.appendChild(diskDom.createTag("mountPoint", partition['MountPoint'])) partitionTag.appendChild(diskDom.createTag("size", partition["Size"])) partitionTag.appendChild(diskDom.createTag("spaceInUse", partition["SpaceInUse"])) @@ -518,7 +512,6 @@ def getDiskDom(diskDeviceList=None, bootPartition=None, skipDisk=None): raidDisksTag.appendChild(raidDiskPartitionsTag) raidDiskTag.appendChild(raidDisksTag) disksTag.appendChild(raidDiskTag) - #disksTag.appendChild(raidDisksTag) diskDom.addTag(disksTag) return diskDom diff --git a/src/com.gluster.storage.management.server.scripts/src/get_server_details.py b/src/com.gluster.storage.management.server.scripts/src/get_server_details.py index 2ab3cdd4..a478afba 100755 --- a/src/com.gluster.storage.management.server.scripts/src/get_server_details.py +++ b/src/com.gluster.storage.management.server.scripts/src/get_server_details.py @@ -19,13 +19,9 @@ import sys import syslog import socket -import Globals -import Commands import re import Common import DiskUtils -from ServerUtils import * -from Protocol import * from NetworkUtils import * from Disk import * from XmlHandler import ResponseXml @@ -89,15 +85,11 @@ def getServerDetails(listall): responseDom.appendTag(serverTag) serverTag.appendChild(responseDom.createTag("numOfCPUs", int(os.sysconf('SC_NPROCESSORS_ONLN')))) - - # refreshing hal data - DiskUtils.refreshHal() - diskDom = DiskUtils.getDiskDom() if not diskDom: - print "No disk found!" - syslog.syslog(syslog.LOG_ERR, "Error finding disk information of server:%s" % serverName) - return None + sys.stderr.write("No disk found!") + Common.log("Failed to get disk details") + sys.exit(1) serverTag.appendChild(responseDom.createTag("cpuUsage", str(cpu))) serverTag.appendChild(responseDom.createTag("totalMemory", str(convertKbToMb(meminfo['MemTotal'])))) @@ -109,9 +101,7 @@ def getServerDetails(listall): return serverTag def main(): - ME = os.path.basename(sys.argv[0]) - parser = OptionParser(version="%s %s" % (ME, Globals.GLUSTER_PLATFORM_VERSION)) - + parser = OptionParser() parser.add_option("-N", "--only-data-disks", action="store_false", dest="listall", default=True, help="List only data disks") -- cgit From 60d53a40bd2b48c8231740559e29bfa7951a2dae Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 6 Jul 2011 20:36:20 +0530 Subject: Updated DiskUtils with raid disk details and review changes. Added functionalities for format device Moved stripEmptyLines, log functions into Utils.py --- .../src/DiskUtils.py | 27 ++++++++-------------- .../src/get_server_details.py | 18 ++++----------- 2 files changed, 14 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py b/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py index fc209c96..f548cb7f 100644 --- a/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py +++ b/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py @@ -190,9 +190,9 @@ def getDiskInfo(diskDeviceList=None): disk["Size"] = long(halDevice.GetProperty('storage.size')) / 1024**2 disk["Interface"] = str(halDevice.GetProperty('storage.bus')) disk["DriveType"] = str(halDevice.GetProperty('storage.drive_type')) - disk["Status"] = None + disk["Status"] = "UNINITIALIZED" if isDiskInFormatting(disk["Device"]): - disk["Status"] = "formatting in progress" + disk["Status"] = "FORMATTING IN PROGRESS" disk["Uuid"] = None disk["Init"] = False disk["Type"] = False @@ -226,10 +226,12 @@ def getDiskInfo(diskDeviceList=None): if disk["Device"] == partitionDevice: disk["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid')) - disk["Init"] = True # TODO: use isDataDiskPartitionFormatted function to cross verify this! + disk["Init"] = True # TODO: use isDataDiskPartitionFormatted function to cross verify this + disk["Status"] = "INITIALIZED" mountPoint = str(partitionHalDevice.GetProperty('volume.mount_point')) if "/export/" in mountPoint: disk["Type"] = True + disk["Status"] = "READY" disk["FsType"] = str(partitionHalDevice.GetProperty('volume.fstype')) disk["FsVersion"] = str(partitionHalDevice.GetProperty('volume.fsversion')) disk["MountPoint"] = str(partitionHalDevice.GetProperty('volume.mount_point')) @@ -242,9 +244,9 @@ def getDiskInfo(diskDeviceList=None): partition = {} partition["Init"] = False partition["Type"] = False - partition["Status"] = None + partition["Status"] = "UNINITIALIZED" if isDiskInFormatting(partitionDevice): - partition["Status"] = "formatting in progress" + partition["Status"] = "FORMATTING IN PROGRESS" partition["Interface"] = None # Partition will not have bus details, info.interfaces can be used here! partition["Device"] = partitionDevice partition["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid')) @@ -257,10 +259,11 @@ def getDiskInfo(diskDeviceList=None): partition["SpaceInUse"] = used if partition["MountPoint"] or isDataDiskPartitionFormatted(partitionDevice): partition["Init"] = True + partition["Status"] = "INITIALIZED" if "/export/" in partition["MountPoint"]: partition["Type"] = True + partition["Status"] = "READY" partition["ReadOnlyAccess"] = str(partitionHalDevice.GetProperty('volume.is_mounted_read_only')) - partitionList.append(partition) disk["Partitions"] = partitionList if not disk["SpaceInUse"]: @@ -394,15 +397,6 @@ def getDiskSizeInfo(partition): return total, used, free -def refreshHal(): - rv = Utils.runCommandFG(["lshal"], stdout=True, root=True) - if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) - Common.log(syslog.LOG_ERR, "failed to execute lshal command. Error: %s" % error) - return False - return True - - def isDataDiskPartitionFormatted(device): #Todo: Proper label needs to be added for data partition #if getDiskPartitionLabel(device) != Globals.DATA_PARTITION_LABEL: @@ -483,7 +477,7 @@ def getDiskDom(diskDeviceList=None, bootPartition=None, skipDisk=None): partitionTag.appendChild(diskDom.createTag("init", str(partition["Init"]).lower())) partitionTag.appendChild(diskDom.createTag("type", str(partition["Type"]).lower())) partitionTag.appendChild(diskDom.createTag("interface", partition["Interface"])) - partitionTag.appendChild(diskDom.createTag("filesystem", partition["FsType"])) + partitionTag.appendChild(diskDom.createTag("fsType", partition["FsType"])) partitionTag.appendChild(diskDom.createTag("mountPoint", partition['MountPoint'])) partitionTag.appendChild(diskDom.createTag("size", partition["Size"])) partitionTag.appendChild(diskDom.createTag("spaceInUse", partition["SpaceInUse"])) @@ -518,7 +512,6 @@ def getDiskDom(diskDeviceList=None, bootPartition=None, skipDisk=None): raidDisksTag.appendChild(raidDiskPartitionsTag) raidDiskTag.appendChild(raidDisksTag) disksTag.appendChild(raidDiskTag) - #disksTag.appendChild(raidDisksTag) diskDom.addTag(disksTag) return diskDom diff --git a/src/com.gluster.storage.management.server.scripts/src/get_server_details.py b/src/com.gluster.storage.management.server.scripts/src/get_server_details.py index 2ab3cdd4..a478afba 100755 --- a/src/com.gluster.storage.management.server.scripts/src/get_server_details.py +++ b/src/com.gluster.storage.management.server.scripts/src/get_server_details.py @@ -19,13 +19,9 @@ import sys import syslog import socket -import Globals -import Commands import re import Common import DiskUtils -from ServerUtils import * -from Protocol import * from NetworkUtils import * from Disk import * from XmlHandler import ResponseXml @@ -89,15 +85,11 @@ def getServerDetails(listall): responseDom.appendTag(serverTag) serverTag.appendChild(responseDom.createTag("numOfCPUs", int(os.sysconf('SC_NPROCESSORS_ONLN')))) - - # refreshing hal data - DiskUtils.refreshHal() - diskDom = DiskUtils.getDiskDom() if not diskDom: - print "No disk found!" - syslog.syslog(syslog.LOG_ERR, "Error finding disk information of server:%s" % serverName) - return None + sys.stderr.write("No disk found!") + Common.log("Failed to get disk details") + sys.exit(1) serverTag.appendChild(responseDom.createTag("cpuUsage", str(cpu))) serverTag.appendChild(responseDom.createTag("totalMemory", str(convertKbToMb(meminfo['MemTotal'])))) @@ -109,9 +101,7 @@ def getServerDetails(listall): return serverTag def main(): - ME = os.path.basename(sys.argv[0]) - parser = OptionParser(version="%s %s" % (ME, Globals.GLUSTER_PLATFORM_VERSION)) - + parser = OptionParser() parser.add_option("-N", "--only-data-disks", action="store_false", dest="listall", default=True, help="List only data disks") -- cgit From 7ae05a5ecd6c177b0d6e5383f89252e4070bbcbe Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Wed, 6 Jul 2011 18:31:44 +0530 Subject: Initialize Disk confirmation dialog added --- .../management/client/GlusterServersClient.java | 5 +- .../core/constants/GlusterConstants.java | 1 + .../storage/management/core/model/Disk.java | 3 +- .../gui/dialogs/InitializeDiskTypeSelection.java | 148 +++++++++++++++++++++ .../gui/views/pages/AbstractDisksPage.java | 44 +++--- .../server/tasks/InitializeDiskTask.java | 33 +++-- .../management/server/utils/GlusterUtil.java | 2 +- 7 files changed, 196 insertions(+), 40 deletions(-) create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/InitializeDiskTypeSelection.java (limited to 'src') diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java index fa925842..865ec5f2 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java @@ -21,6 +21,7 @@ package com.gluster.storage.management.client; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_SERVERS; +import java.net.URI; import java.util.List; import com.gluster.storage.management.core.constants.RESTConstants; @@ -62,10 +63,10 @@ public class GlusterServersClient extends AbstractClient { postRequest(form); } - public void initializeDisk(String serverName, String diskName, String fsType) { + public URI initializeDisk(String serverName, String diskName, String fsType) { Form form = new Form(); form.add(RESTConstants.FORM_PARAM_FSTYPE, fsType); - putRequest(serverName + "/" + RESTConstants.RESOURCE_DISKS + "/" + diskName, form); + return putRequestURI(serverName + "/" + RESTConstants.RESOURCE_DISKS + "/" + diskName, form); } public void removeServer(String serverName) { diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/GlusterConstants.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/GlusterConstants.java index 567eda61..b87d38f5 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/GlusterConstants.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/GlusterConstants.java @@ -31,6 +31,7 @@ public class GlusterConstants { }; public static final List VOLUME_LOG_LEVELS_ARR = StringUtil.enumToArray(VOLUME_LOG_LEVELS.values()); + public static final String FSTYPE_DEFAULT = "default"; public static final String FSTYPE_EXT_3 = "ext3"; public static final String FSTYPE_EXT_4 = "ext4"; public static final String FSTYPE_XFS = "xfs"; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java index ecc3a278..d862df28 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java @@ -56,7 +56,8 @@ public class Disk extends Entity { } public boolean isUninitialized() { - return getStatus() == DISK_STATUS.UNINITIALIZED; + return true; +// return getStatus() == DISK_STATUS.UNINITIALIZED; } public boolean hasErrors() { diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/InitializeDiskTypeSelection.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/InitializeDiskTypeSelection.java new file mode 100644 index 00000000..bb700de5 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/InitializeDiskTypeSelection.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * + * InitializeDiskTypeSelection.java + * + * Copyright (c) 2011 Gluster, Inc. + * 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 + * . + *******************************************************************************/ +package com.gluster.storage.management.gui.dialogs; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +import com.gluster.storage.management.core.constants.GlusterConstants; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public class InitializeDiskTypeSelection extends Dialog { + + private Combo formatTypeCombo = null; + private final GUIHelper guiHelper = GUIHelper.getInstance(); + private Composite initializeDiskTypeComposite; + private Composite composite; + private String fsType; + + public InitializeDiskTypeSelection(Shell parentShell) { + super(parentShell); + // TODO Auto-generated constructor stub + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + + newShell.setText("Gluster Management Console - Select Cluster"); + addEscapeListener(newShell); + } + + private void addEscapeListener(Shell shell) { + shell.addTraverseListener(new TraverseListener() { + + @Override + public void keyTraversed(TraverseEvent e) { + if (e.keyCode == SWT.ESC) { + cancelPressed(); + } + } + }); + } + + @Override + protected Control createDialogArea(Composite parent) { + // Makes sure that child composites inherit the same background + parent.setBackgroundMode(SWT.INHERIT_FORCE); + + composite = (Composite) super.createDialogArea(parent); + configureDialogLayout(composite); + createComposite(composite); + return composite; + } + + private void configureDialogLayout(Composite composite) { + GridLayout layout = (GridLayout) composite.getLayout(); + layout.numColumns = 3; + layout.marginLeft = 20; + layout.marginRight = 20; + layout.marginTop = 20; + layout.horizontalSpacing = 20; + layout.verticalSpacing = 20; + } + + private void createComposite(Composite composite) { + initializeDiskTypeComposite = new Composite(composite, SWT.NONE); + GridLayout layout = new GridLayout(3, false); + initializeDiskTypeComposite.setLayout(layout); + + createLabel(initializeDiskTypeComposite, "Format disk using "); + createFormatTypeCombo(initializeDiskTypeComposite); + createLabel(initializeDiskTypeComposite, " file system"); + } + + private void createLabel(Composite composite, String labelText) { + Label formatTypeLabel = new Label(composite, SWT.NONE); + formatTypeLabel.setText(labelText); + formatTypeLabel.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + } + + private void createFormatTypeCombo(Composite composite) { + List fsType = new ArrayList(); + fsType.add(GlusterConstants.FSTYPE_DEFAULT); + fsType.add(GlusterConstants.FSTYPE_EXT_3); + fsType.add(GlusterConstants.FSTYPE_EXT_4); + fsType.add(GlusterConstants.FSTYPE_XFS); + formatTypeCombo = new Combo(composite, SWT.READ_ONLY); + formatTypeCombo.setItems(fsType.toArray(new String[0])); + formatTypeCombo.select(0); + } + + @Override + protected void okPressed() { + fsType = formatTypeCombo.getText(); + super.okPressed(); + } + + @Override + public void cancelPressed() { + super.cancelPressed(); + } + + /** + * Overriding to make sure that the dialog is centered in screen + */ + @Override + protected void initializeBounds() { + super.initializeBounds(); + + guiHelper.centerShellInScreen(getShell()); + } + + public String getFSType() { + return fsType.trim(); + } + +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java index 63cf65ed..cc12415e 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java @@ -18,12 +18,14 @@ *******************************************************************************/ package com.gluster.storage.management.gui.views.pages; +import java.net.URI; import java.util.List; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TableEditor; import org.eclipse.swt.events.DisposeEvent; @@ -39,18 +41,18 @@ import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.widgets.ImageHyperlink; +import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.client.GlusterServersClient; -import com.gluster.storage.management.core.constants.GlusterConstants; +import com.gluster.storage.management.client.TasksClient; import com.gluster.storage.management.core.model.ClusterListener; import com.gluster.storage.management.core.model.DefaultClusterListener; import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.Disk.DISK_STATUS; import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.TaskInfo; import com.gluster.storage.management.gui.Application; import com.gluster.storage.management.gui.IEntityListener; -import com.gluster.storage.management.gui.IImageKeys; -import com.gluster.storage.management.gui.jobs.InitializeDiskJob; -import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.dialogs.InitializeDiskTypeSelection; public abstract class AbstractDisksPage extends AbstractTableViewerPage implements IEntityListener { private List disks; @@ -203,30 +205,26 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im @Override public void linkActivated(HyperlinkEvent e) { - Integer formatOption = new MessageDialog(getShell(), "Initialize Disk", GUIHelper.getInstance().getImage( - IImageKeys.DISK), "Please choose the file system to Initialize the disk?", MessageDialog.QUESTION, new String[] { - "Cancel", GlusterConstants.FSTYPE_EXT_3, GlusterConstants.FSTYPE_EXT_4, GlusterConstants.FSTYPE_XFS }, -1).open(); - - if (formatOption <= 0) { // By Cancel button(0) or Escape key(-1) + InitializeDiskTypeSelection formatDialog = new InitializeDiskTypeSelection(getShell()); + int userAction = formatDialog.open(); + if (userAction == Window.CANCEL) { + formatDialog.cancelPressed(); return; } - String fsType = null; - if (formatOption == 1) { - fsType = GlusterConstants.FSTYPE_EXT_3; - } else if (formatOption == 2) { - fsType = GlusterConstants.FSTYPE_EXT_4; - } else if (formatOption == 3) { - fsType = GlusterConstants.FSTYPE_XFS; - } - GlusterServersClient serversClient = new GlusterServersClient(); - serversClient.initializeDisk(disk.getServerName(), disk.getName(), fsType); + try { + URI uri = serversClient.initializeDisk(disk.getServerName(), disk.getName(), formatDialog.getFSType()); - updateStatus(DISK_STATUS.INITIALIZING, true); - - guiHelper.showProgressView(); - new InitializeDiskJob(disk).schedule(); + TasksClient taskClient = new TasksClient(); + TaskInfo taskInfo = taskClient.getTaskInfo(uri); + if (taskInfo != null && taskInfo instanceof TaskInfo) { + GlusterDataModelManager.getInstance().getModel().getCluster().addTaskInfo(taskInfo); + } + updateStatus(DISK_STATUS.INITIALIZING, true); + } catch (Exception e1) { + MessageDialog.openError(getShell(), "Error: Initialize disk", e1.getMessage()); + } } } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java index 89c8c20f..ea9dd7e5 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java @@ -20,6 +20,10 @@ */ package com.gluster.storage.management.server.tasks; +import org.springframework.context.ApplicationContext; +import org.springframework.web.context.ContextLoader; + +import com.gluster.storage.management.core.constants.GlusterConstants; import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Status; @@ -34,12 +38,12 @@ import com.sun.jersey.core.util.Base64; public class InitializeDiskTask extends Task { - private static final String INITIALIZE_DISK_SCRIPT = "initialize_disk.py"; + private static final String INITIALIZE_DISK_SCRIPT = "format_device.py"; private String serverName; private String diskName; private String fsType; - private SshUtil sshUtil = new SshUtil(); + private SshUtil sshUtil; private GlusterUtil glusterUtil; public InitializeDiskTask(ClusterService clusterService, String clusterName, String serverName, String diskName, String fsType) { @@ -49,12 +53,20 @@ public class InitializeDiskTask extends Task { setServerName(serverName); setDiskName(diskName); setFsType(fsType); + init(); } public InitializeDiskTask(ClusterService clusterService, String clusterName, TaskInfo info) { super(clusterService, clusterName, info); + init(); } + private void init() { + ApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext(); + glusterUtil = ctx.getBean(GlusterUtil.class); + sshUtil = ctx.getBean(SshUtil.class); + } + @Override public String getId() { return new String( @@ -108,23 +120,18 @@ public class InitializeDiskTask extends Task { } private void startInitializeDisk(String serverName) { - ProcessResult processResult = sshUtil.executeRemote(serverName, INITIALIZE_DISK_SCRIPT + " -t " + getFsType() - + " " + getDiskName()); + String fsTypeCommand = (getFsType().equals(GlusterConstants.FSTYPE_DEFAULT)) ? "" : " -t " + getFsType(); + ProcessResult processResult = sshUtil.executeRemote(serverName, INITIALIZE_DISK_SCRIPT + fsTypeCommand + " " + + getDiskName()); if (processResult.isSuccess()) { - getTaskInfo().setStatus(new TaskStatus(new Status(Status.STATUS_CODE_RUNNING, processResult.getOutput()))); - TaskStatus taskStatus = null; - if (fsType.equals("xfs")) { - taskStatus.setPercentageSupported(false); - } else { - taskStatus.setPercentageSupported(true); - } - + TaskStatus taskStatus = new TaskStatus(new Status(Status.STATUS_CODE_RUNNING, processResult.getOutput())); + taskStatus.setPercentageSupported((getFsType().equals(GlusterConstants.FSTYPE_XFS)) ? false : true); + getTaskInfo().setStatus(taskStatus); return; } // if we reach here, it means Initialize disk start failed. throw new GlusterRuntimeException(processResult.toString()); - } @Override diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java index e614641c..4bd3b632 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java @@ -73,7 +73,7 @@ public class GlusterUtil { private static final GlusterCoreUtil glusterCoreUtil = new GlusterCoreUtil(); - private static final String INITIALIZE_DISK_STATUS_SCRIPT = "initialize_disk_status.py"; + private static final String INITIALIZE_DISK_STATUS_SCRIPT = "format_device_status.py"; @Autowired private SshUtil sshUtil; -- cgit From 7bc61b55432a68bc0845fcfab19f20f18822629a Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Thu, 7 Jul 2011 17:53:46 +0530 Subject: Disk data model change --- .../management/client/DiscoveredServersClient.java | 10 +- .../management/client/GlusterDataModelManager.java | 5 +- .../management/client/GlusterServersClient.java | 11 +- .../storage/management/core/model/Device.java | 194 +++++++++++++++++++++ .../storage/management/core/model/Disk.java | 134 +++++--------- .../management/core/model/GlusterDummyModel.java | 22 +-- .../storage/management/core/model/Partition.java | 26 +++ .../management/core/utils/GlusterCoreUtil.java | 25 ++- .../management/gui/BrickTableLabelProvider.java | 6 +- .../management/gui/DiskTableLabelProvider.java | 6 +- .../gui/ServerDiskTableLabelProvider.java | 6 +- .../management/gui/jobs/InitializeDiskJob.java | 6 +- .../management/gui/views/ClusterSummaryView.java | 4 +- .../gui/views/pages/AbstractDisksPage.java | 6 +- 14 files changed, 340 insertions(+), 121 deletions(-) create mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java create mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Partition.java (limited to 'src') diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java index 3704e2ff..0d4ef85c 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java @@ -25,10 +25,12 @@ import java.util.List; import javax.ws.rs.core.MultivaluedMap; +import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.response.GenericResponse; import com.gluster.storage.management.core.response.ServerListResponse; import com.gluster.storage.management.core.response.ServerNameListResponse; +import com.gluster.storage.management.core.utils.GlusterCoreUtil; import com.sun.jersey.core.util.MultivaluedMapImpl; public class DiscoveredServersClient extends AbstractClient { @@ -59,7 +61,13 @@ public class DiscoveredServersClient extends AbstractClient { } public List getDiscoveredServerDetails() { - return ((ServerListResponse) getDiscoveredServers(Boolean.TRUE, ServerListResponse.class)).getServers(); + List servers = ((ServerListResponse) getDiscoveredServers(Boolean.TRUE, ServerListResponse.class)) + .getServers(); + + for (Server server : servers) { + GlusterCoreUtil.updateServerNameOnDevices(server); + } + return servers; } public Server getServer(String serverName) { diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java index 9ee4513c..296de3d6 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java @@ -19,7 +19,6 @@ package com.gluster.storage.management.client; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -31,8 +30,8 @@ import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.Cluster; import com.gluster.storage.management.core.model.ClusterListener; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; import com.gluster.storage.management.core.model.Event; import com.gluster.storage.management.core.model.Event.EVENT_TYPE; import com.gluster.storage.management.core.model.GlusterDataModel; @@ -707,7 +706,7 @@ public class GlusterDataModelManager { } public String getDiskStatus(Disk disk) { - if (disk.getStatus() == DISK_STATUS.AVAILABLE) { + if (disk.getStatus() == DEVICE_STATUS.INITIALIZED) { for (Volume volume : model.getCluster().getVolumes()) { if (isDiskUsed(volume, disk)) { return "In use"; diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java index 865ec5f2..0abccda5 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java @@ -28,6 +28,7 @@ import com.gluster.storage.management.core.constants.RESTConstants; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.response.GlusterServerListResponse; +import com.gluster.storage.management.core.utils.GlusterCoreUtil; import com.sun.jersey.api.representation.Form; public class GlusterServersClient extends AbstractClient { @@ -50,11 +51,17 @@ public class GlusterServersClient extends AbstractClient { } public List getServers() { - return ((GlusterServerListResponse) fetchResource(GlusterServerListResponse.class)).getServers(); + List servers = ((GlusterServerListResponse) fetchResource(GlusterServerListResponse.class)).getServers(); + for(GlusterServer server : servers) { + GlusterCoreUtil.updateServerNameOnDevices(server); + } + return servers; } public GlusterServer getGlusterServer(String serverName) { - return (GlusterServer) fetchSubResource(serverName, GlusterServer.class); + GlusterServer server = (GlusterServer) fetchSubResource(serverName, GlusterServer.class); + GlusterCoreUtil.updateServerNameOnDevices(server); + return server; } public void addServer(Server discoveredServer) { diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java new file mode 100644 index 00000000..90f319bb --- /dev/null +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java @@ -0,0 +1,194 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * 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 + * . + *******************************************************************************/ +package com.gluster.storage.management.core.model; + +import java.io.File; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlTransient; + +import com.gluster.storage.management.core.utils.StringUtil; + + +/** + * + */ +public class Device extends Entity { + public enum DEVICE_STATUS { + INITIALIZED, UNINITIALIZED, INITIALIZING, IO_ERROR + }; + + public enum DEVICE_TYPE { + DATA, BOOT, SWAP, UNKNOWN + }; + + private static final String[] DEVICE_STATUS_STR = { "Initialized", "Uninitialized", "Initializing", "I/O Error" }; + private static final String[] DEVICE_TYPE_STR = { "Data", "Boot", "Swap", "Unknown" }; + + // type = data, boot, other + private DEVICE_TYPE type; + + private String fsType; + private String fsVersion; + + private String serverName; + private String mountPoint; + + private Double space; + private Double spaceInUse; + private DEVICE_STATUS status; + + public Device() { + } + + public Device(Server server, String name, String mountPoint, Double space, Double spaceInUse, DEVICE_STATUS status) { + super(name, server); + setServerName(server != null ? server.getName() : ""); + setMountPoint(mountPoint); + setSpace(space); + setSpaceInUse(spaceInUse); + setStatus(status); + } + + @XmlElement(name="size") + public Double getSpace() { + return space; + } + + public Double getFreeSpace() { + return getSpace() - getSpaceInUse(); + } + + public void setSpace(Double space) { + this.space = space; + } + + public boolean isUninitialized() { + return getStatus() == DEVICE_STATUS.UNINITIALIZED; + } + + public boolean hasErrors() { + return getStatus() == DEVICE_STATUS.IO_ERROR; + } + + public boolean isReady() { + // TODO: Check if status is INITIALIZED AND type = DATA + return getStatus() == DEVICE_STATUS.INITIALIZED; + } + + public DEVICE_STATUS getStatus() { + return status; + } + + public String getStatusStr() { + if(isReady()) { + return "Available"; + } + return DEVICE_STATUS_STR[getStatus().ordinal()]; + } + + public void setStatus(DEVICE_STATUS status) { + this.status = status; + } + + public Double getSpaceInUse() { + return spaceInUse; + } + + public void setSpaceInUse(Double spaceInUse) { + this.spaceInUse = spaceInUse; + } + + @XmlTransient + public String getServerName() { + return serverName; + } + + public void setServerName(String serverName) { + this.serverName = serverName; + } + + public void setMountPoint(String mountPoint) { + this.mountPoint = mountPoint; + } + + public String getMountPoint() { + return mountPoint; + } + + public DEVICE_TYPE getType() { + return type; + } + + public String getTypeStr() { + return DEVICE_TYPE_STR[type.ordinal()]; + } + + public void setType(DEVICE_TYPE diskType) { + this.type = diskType; + } + + public String getFsType() { + return fsType; + } + + public void setFsType(String fsType) { + this.fsType = fsType; + } + + public String getFsVersion() { + return fsVersion; + } + + public void setFsVersion(String fsVersion) { + this.fsVersion = fsVersion; + } + + @Override + public boolean filter(String filterString, boolean caseSensitive) { + return StringUtil.filterString(getServerName() + getName() + getStatusStr() + getSpace() + getFreeSpace() + + getType(), filterString, caseSensitive); + } + + public String getQualifiedName() { + return getServerName() + ":" + getName(); + } + + public String getQualifiedBrickName(String volumeName) { + return getServerName() + ":" + getMountPoint() + File.separator + volumeName; + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof Device)) { + return false; + } + + Device disk = (Device)obj; + + if (getName().equals(disk.getName()) && getServerName().equals(disk.getServerName()) + && getMountPoint().equals(disk.getMountPoint()) && getStatus() == disk.getStatus() + && getSpace() == disk.getSpace() && getSpaceInUse() == disk.getSpaceInUse() + && getFsType().equals(disk.getFsType()) && getFsVersion().equals(disk.getFsVersion())) { + return true; + } + + return false; + } +} diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java index d862df28..e623f3d6 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java @@ -18,120 +18,70 @@ *******************************************************************************/ package com.gluster.storage.management.core.model; -import java.io.File; +import java.util.Collection; +import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import com.gluster.storage.management.core.utils.GlusterCoreUtil; import com.gluster.storage.management.core.utils.StringUtil; @XmlRootElement(name="Disk") -public class Disk extends Entity { - public enum DISK_STATUS { - AVAILABLE, UNINITIALIZED, INITIALIZING, IO_ERROR - }; - - private String[] DISK_STATUS_STR = { "Available", "Uninitialized", "Initializing", "I/O Error" }; - - private String serverName; - private String mountPoint; +public class Disk extends Device { private String description; - private Double space; - private Double spaceInUse; - private DISK_STATUS status; - - public Disk() { - - } - public Double getSpace() { - return space; - } + // interface = pci, raid0, raid3, etc + private String diskInterface; - public Double getFreeSpace() { - return getSpace() - getSpaceInUse(); - } - - public void setSpace(Double space) { - this.space = space; - } + private Collection partitions; - public boolean isUninitialized() { - return true; -// return getStatus() == DISK_STATUS.UNINITIALIZED; - } - - public boolean hasErrors() { - return getStatus() == DISK_STATUS.IO_ERROR; - } - - public boolean isReady() { - return getStatus() == DISK_STATUS.AVAILABLE; - } - - public DISK_STATUS getStatus() { - return status; - } - - public String getStatusStr() { - return DISK_STATUS_STR[getStatus().ordinal()]; - } + // In case of a software raid, the disk will contain an array of other disks + private Collection raidDisks; - public void setStatus(DISK_STATUS status) { - this.status = status; + public Disk() { } - public Double getSpaceInUse() { - return spaceInUse; + public void setDescription(String description) { + this.description = description; } - public void setSpaceInUse(Double spaceInUse) { - this.spaceInUse = spaceInUse; + public String getDescription() { + return description; } - public String getServerName() { - return serverName; + @XmlElement(name="interface") + public String getDiskInterface() { + return diskInterface; } - public void setServerName(String serverName) { - this.serverName = serverName; + public void setDiskInterface(String diskInterface) { + this.diskInterface = diskInterface; } - public void setMountPoint(String mountPoint) { - this.mountPoint = mountPoint; + public Collection getRaidDisks() { + return raidDisks; } - public String getMountPoint() { - return mountPoint; + public void setRaidDisks(Collection raidDisks) { + this.raidDisks = raidDisks; } - public void setDescription(String description) { - this.description = description; + public void setPartitions(Collection partitions) { + this.partitions = partitions; } - public String getDescription() { - return description; + public Collection getPartitions() { + return partitions; } - public Disk(Server server, String name, String mountPoint, Double space, Double spaceInUse, DISK_STATUS status) { - super(name, server); - setServerName(server != null ? server.getName() : ""); - setMountPoint(mountPoint); - setSpace(space); - setSpaceInUse(spaceInUse); - setStatus(status); + public Disk(Server server, String name, String mountPoint, Double space, Double spaceInUse, DEVICE_STATUS status) { + super(server, name, mountPoint, space, spaceInUse, status); } @Override public boolean filter(String filterString, boolean caseSensitive) { - return StringUtil.filterString(getServerName() + getName() + getStatusStr(), filterString, caseSensitive); - } - - public String getQualifiedName() { - return getServerName() + ":" + getName(); - } - - public String getQualifiedBrickName(String volumeName) { - return getServerName() + ":" + getMountPoint() + File.separator + volumeName; + return StringUtil.filterString(getServerName() + getName() + getStatusStr() + getSpace() + getFreeSpace() + + getType() + getDescription(), filterString, caseSensitive); } @Override @@ -141,13 +91,25 @@ public class Disk extends Entity { } Disk disk = (Disk)obj; - if (getName().equals(disk.getName()) && getServerName().equals(disk.getServerName()) - && getMountPoint().equals(disk.getMountPoint()) && getDescription().equals(disk.getDescription()) - && getStatus() == disk.getStatus() && getSpace() == disk.getSpace() - && getSpaceInUse() == disk.getSpaceInUse()) { - return true; + if (!(super.equals(obj) && getDescription().equals(disk.getDescription()) && getDiskInterface().equals( + disk.getDiskInterface()))) { + return false; } + for(Disk raidDisk : raidDisks) { + // check if the disk contains same raid disks + if (!(raidDisk.equals(GlusterCoreUtil.getEntity(disk.getRaidDisks(), raidDisk.getName(), false)))) { + return false; + } + } + + // check if the disk contains same partitions + for (Partition partition : partitions) { + if (!(partition.equals(GlusterCoreUtil.getEntity(disk.getPartitions(), partition.getName(), false)))) { + return false; + } + } + return false; } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java index f2ccc5db..22681919 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java @@ -23,7 +23,7 @@ import java.util.Arrays; import java.util.Date; import java.util.List; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; import com.gluster.storage.management.core.model.Volume.TRANSPORT_TYPE; import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; @@ -72,7 +72,7 @@ public class GlusterDummyModel { private void addDiscoveredServer(List servers, Entity parent, String name, int numOfCPUs, double cpuUsage, double totalMemory, double memoryInUse, double totalDiskSpace, double diskSpaceInUse) { Server server = new Server(name, parent, numOfCPUs, cpuUsage, totalMemory, memoryInUse); - server.addDisk(new Disk(server, "sda", "/export/md0", totalDiskSpace, diskSpaceInUse, DISK_STATUS.AVAILABLE)); + server.addDisk(new Disk(server, "sda", "/export/md0", totalDiskSpace, diskSpaceInUse, DEVICE_STATUS.INITIALIZED)); addNetworkInterface(server, "eth0"); servers.add(server); @@ -138,18 +138,18 @@ public class GlusterDummyModel { } private void initializeDisks() { - s1da = new Disk(server1, "sda", "/export/md0", 100d, 80d, DISK_STATUS.AVAILABLE); - s1db = new Disk(server1, "sdb", "/export/md1", 100d, 67.83, DISK_STATUS.AVAILABLE); + s1da = new Disk(server1, "sda", "/export/md0", 100d, 80d, DEVICE_STATUS.INITIALIZED); + s1db = new Disk(server1, "sdb", "/export/md1", 100d, 67.83, DEVICE_STATUS.INITIALIZED); - s2da = new Disk(server2, "sda", "/export/md0", 200d, 157.12, DISK_STATUS.AVAILABLE); - s2db = new Disk(server2, "sdb", "/export/md1", 200d, 182.27, DISK_STATUS.AVAILABLE); - s2dc = new Disk(server2, "sdc", "/export/md0", 200d, -1d, DISK_STATUS.UNINITIALIZED); - s2dd = new Disk(server2, "sdd", "/export/md1", 200d, 124.89, DISK_STATUS.AVAILABLE); + s2da = new Disk(server2, "sda", "/export/md0", 200d, 157.12, DEVICE_STATUS.INITIALIZED); + s2db = new Disk(server2, "sdb", "/export/md1", 200d, 182.27, DEVICE_STATUS.INITIALIZED); + s2dc = new Disk(server2, "sdc", "/export/md0", 200d, -1d, DEVICE_STATUS.UNINITIALIZED); + s2dd = new Disk(server2, "sdd", "/export/md1", 200d, 124.89, DEVICE_STATUS.INITIALIZED); - s4da = new Disk(server4, "sda", "/export/md0", 100d, 85.39, DISK_STATUS.AVAILABLE); + s4da = new Disk(server4, "sda", "/export/md0", 100d, 85.39, DEVICE_STATUS.INITIALIZED); - s5da = new Disk(server5, "sda", "/export/md1", 100d, 92.83, DISK_STATUS.AVAILABLE); - s5db = new Disk(server5, "sdb", "/export/md1", 200d, 185.69, DISK_STATUS.AVAILABLE); + s5da = new Disk(server5, "sda", "/export/md1", 100d, 92.83, DEVICE_STATUS.INITIALIZED); + s5db = new Disk(server5, "sdb", "/export/md1", 200d, 185.69, DEVICE_STATUS.INITIALIZED); } private void addDisksToServers() { diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Partition.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Partition.java new file mode 100644 index 00000000..a06b1e1c --- /dev/null +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Partition.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * 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 + * . + *******************************************************************************/ +package com.gluster.storage.management.core.model; + +/** + * + */ +public class Partition extends Device { + +} diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java index 838612be..7b1eec36 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java @@ -21,6 +21,7 @@ package com.gluster.storage.management.core.utils; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -30,6 +31,8 @@ import java.util.Set; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.Partition; +import com.gluster.storage.management.core.model.Server; public class GlusterCoreUtil { @@ -95,7 +98,7 @@ public class GlusterCoreUtil { return getEntity(entityList, searchEntity.getName(), caseInsensitive) != null; } - public static T getEntity(List entityList, String searchEntityName, boolean caseInsensitive) { + public static T getEntity(Collection entityList, String searchEntityName, boolean caseInsensitive) { if (caseInsensitive) { searchEntityName = searchEntityName.toUpperCase(); } @@ -112,4 +115,24 @@ public class GlusterCoreUtil { return null; } + + public static void updateServerNameOnDevices(Server server) { + String serverName = server.getName(); + for(Disk disk : server.getDisks()) { + disk.setServerName(serverName); + + if (disk.getRaidDisks() != null) { + for (Disk raidDisk : disk.getRaidDisks()) { + raidDisk.setServerName(serverName); + } + } + + if (disk.getPartitions() != null) { + for (Partition partition : disk.getPartitions()) { + partition.setServerName(serverName); + } + } + } + // TODO: do the same for raid disks and/or partitions whenever we start supporting them + } } 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 763dac2a..5e49aae2 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 @@ -23,8 +23,8 @@ import org.eclipse.swt.graphics.Image; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Brick; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; 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.pages.BricksPage.BRICK_TABLE_COLUMN_INDICES; @@ -44,9 +44,9 @@ public class BrickTableLabelProvider extends TableLabelProviderAdapter { Disk disk = GlusterDataModelManager.getInstance().getDiskDetails(brick.getDiskName()); if (columnIndex == DISK_TABLE_COLUMN_INDICES.STATUS.ordinal()) { - DISK_STATUS status = disk.getStatus(); + DEVICE_STATUS status = disk.getStatus(); switch (status) { - case AVAILABLE: + case INITIALIZED: return guiHelper.getImage(IImageKeys.STATUS_ONLINE); case IO_ERROR: return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); 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 d2f265b5..9759e384 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 @@ -22,8 +22,8 @@ import org.eclipse.swt.graphics.Image; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; 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.pages.DisksPage.DISK_TABLE_COLUMN_INDICES; @@ -44,9 +44,9 @@ public class DiskTableLabelProvider extends TableLabelProviderAdapter { Disk disk = (Disk) element; if (columnIndex == DISK_TABLE_COLUMN_INDICES.STATUS.ordinal()) { - DISK_STATUS status = disk.getStatus(); + DEVICE_STATUS status = disk.getStatus(); switch (status) { - case AVAILABLE: + case INITIALIZED: return guiHelper.getImage(IImageKeys.STATUS_ONLINE); case IO_ERROR: return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); 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 f0e65edc..21ce00f9 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 @@ -23,8 +23,8 @@ import org.eclipse.swt.graphics.Image; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; 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.pages.ServerDisksPage.SERVER_DISK_TABLE_COLUMN_INDICES; @@ -41,9 +41,9 @@ public class ServerDiskTableLabelProvider extends TableLabelProviderAdapter { Disk disk = (Disk) element; if (columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.STATUS.ordinal()) { - DISK_STATUS status = disk.getStatus(); + DEVICE_STATUS status = disk.getStatus(); switch (status) { - case AVAILABLE: + case INITIALIZED: return guiHelper.getImage(IImageKeys.STATUS_ONLINE); case IO_ERROR: return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/jobs/InitializeDiskJob.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/jobs/InitializeDiskJob.java index 02a8b0e0..76659885 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/jobs/InitializeDiskJob.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/jobs/InitializeDiskJob.java @@ -25,8 +25,8 @@ import org.eclipse.core.runtime.jobs.Job; import org.eclipse.ui.progress.IProgressConstants; import org.eclipse.ui.progress.IProgressConstants2; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; import com.gluster.storage.management.gui.Application; import com.gluster.storage.management.gui.IImageKeys; import com.gluster.storage.management.gui.utils.GUIHelper; @@ -44,7 +44,7 @@ public class InitializeDiskJob extends Job { setProperty(IProgressConstants.ICON_PROPERTY, guiHelper.getImageDescriptor(IImageKeys.WORK_IN_PROGRESS)); } - private void updateStatus(final DISK_STATUS status) { + private void updateStatus(final DEVICE_STATUS status) { disk.setStatus(status); disk.setSpaceInUse(0d); app.entityChanged(disk, new String[] { "status", "spaceInUse" }); @@ -76,7 +76,7 @@ public class InitializeDiskJob extends Job { e.printStackTrace(); } - updateStatus(DISK_STATUS.AVAILABLE); + updateStatus(DEVICE_STATUS.INITIALIZED); setProperty(IProgressConstants.ICON_PROPERTY, guiHelper.getImageDescriptor(IImageKeys.STATUS_SUCCESS)); return new Status(Status.OK, Application.PLUGIN_ID, "Task Completed!"); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java index ef14c197..32aeb0cb 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java @@ -40,8 +40,8 @@ import org.eclipse.ui.part.ViewPart; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.model.Alert; import com.gluster.storage.management.core.model.Cluster; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; import com.gluster.storage.management.core.model.EntityGroup; import com.gluster.storage.management.core.model.GlusterDataModel; import com.gluster.storage.management.core.model.GlusterServer; @@ -138,7 +138,7 @@ public class ClusterSummaryView extends ViewPart { createDiskSpaceChart(toolkit, section, values); } - private int getDiskCountByStatus(Cluster cluster, DISK_STATUS status) { + private int getDiskCountByStatus(Cluster cluster, DEVICE_STATUS status) { int diskCount = 0; for(GlusterServer server : cluster.getServers()) { for(Disk disk : server.getDisks()) { diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java index cc12415e..d58394e2 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java @@ -46,8 +46,8 @@ import com.gluster.storage.management.client.GlusterServersClient; import com.gluster.storage.management.client.TasksClient; import com.gluster.storage.management.core.model.ClusterListener; import com.gluster.storage.management.core.model.DefaultClusterListener; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.core.model.Disk.DISK_STATUS; import com.gluster.storage.management.core.model.Entity; import com.gluster.storage.management.core.model.TaskInfo; import com.gluster.storage.management.gui.Application; @@ -193,7 +193,7 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im this.myLink = link; } - private void updateStatus(final DISK_STATUS status, final boolean disposeEditor) { + private void updateStatus(final DEVICE_STATUS status, final boolean disposeEditor) { if (disposeEditor) { myLink.dispose(); myEditor.dispose(); @@ -221,7 +221,7 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im if (taskInfo != null && taskInfo instanceof TaskInfo) { GlusterDataModelManager.getInstance().getModel().getCluster().addTaskInfo(taskInfo); } - updateStatus(DISK_STATUS.INITIALIZING, true); + updateStatus(DEVICE_STATUS.INITIALIZING, true); } catch (Exception e1) { MessageDialog.openError(getShell(), "Error: Initialize disk", e1.getMessage()); } -- cgit From 529525fe5dec5d9ead5aab6bd39029ea1a63762b Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Thu, 7 Jul 2011 21:27:15 +0530 Subject: VolumeOptions data model change --- .../management/client/GlusterDataModelManager.java | 20 ++------- .../storage/management/core/model/Device.java | 13 ++++-- .../storage/management/core/model/Disk.java | 26 ++++++----- .../storage/management/core/model/Volume.java | 7 ++- .../management/core/model/VolumeOption.java | 2 +- .../management/core/model/VolumeOptions.java | 51 +++++++++------------- .../management/gui/BrickTableLabelProvider.java | 3 +- .../management/gui/DiskTableLabelProvider.java | 1 + .../gui/ServerDiskTableLabelProvider.java | 5 +++ .../gui/VolumeOptionsTableLabelProvider.java | 9 ++-- .../gui/views/pages/OptionKeyEditingSupport.java | 26 +++++------ .../gui/views/pages/OptionValueEditingSupport.java | 7 +-- .../gui/views/pages/VolumeOptionsPage.java | 11 ++--- .../management/server/utils/ServerUtil.java | 28 ++++++------ 14 files changed, 105 insertions(+), 104 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java index 296de3d6..6db98ed4 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java @@ -604,10 +604,10 @@ public class GlusterDataModelManager { } } - public void setVolumeOption(Volume volume, Entry entry) { - volume.setOption(entry.getKey(), (String) entry.getValue()); + public void setVolumeOption(Volume volume, String optionKey, String optionValue) { + volume.setOption(optionKey, optionValue); for (ClusterListener listener : listeners) { - listener.volumeChanged(volume, new Event(EVENT_TYPE.VOLUME_OPTION_SET, entry)); + listener.volumeChanged(volume, new Event(EVENT_TYPE.VOLUME_OPTION_SET, optionKey)); } } @@ -672,8 +672,7 @@ public class GlusterDataModelManager { } public void setAccessControlList(Volume volume, String accessControlList) { - volume.setAccessControlList(accessControlList); - setVolumeOption(volume, getOptionEntry(volume, Volume.OPTION_AUTH_ALLOW)); + setVolumeOption(volume, Volume.OPTION_AUTH_ALLOW, accessControlList); } public Server getGlusterServer(String serverName) { @@ -685,17 +684,6 @@ public class GlusterDataModelManager { return null; } - @SuppressWarnings({ "rawtypes", "unchecked" }) - private Entry getOptionEntry(Volume volume, String optionKey) { - for (Entry entry : volume.getOptions().entrySet()) { - if (entry.getKey().equals(optionKey)) { - return entry; - } - } - throw new GlusterRuntimeException("Couldn't find entry for option [" + optionKey + "] on volume [" - + volume.getName()); - } - private Boolean isDiskUsed(Volume volume, Disk disk) { for (Brick brick : volume.getBricks()) { if (disk.getName().equals(brick.getDiskName()) && disk.getServerName().equals(brick.getServerName())) { diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java index 90f319bb..063cdd18 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java @@ -19,6 +19,7 @@ package com.gluster.storage.management.core.model; import java.io.File; +import java.nio.channels.GatheringByteChannel; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlTransient; @@ -31,14 +32,15 @@ import com.gluster.storage.management.core.utils.StringUtil; */ public class Device extends Entity { public enum DEVICE_STATUS { - INITIALIZED, UNINITIALIZED, INITIALIZING, IO_ERROR + //TODO: Status "READY" to be removed after python script is changed accordingly + READY, INITIALIZED, UNINITIALIZED, INITIALIZING, IO_ERROR, UNKNOWN }; public enum DEVICE_TYPE { DATA, BOOT, SWAP, UNKNOWN }; - private static final String[] DEVICE_STATUS_STR = { "Initialized", "Uninitialized", "Initializing", "I/O Error" }; + private static final String[] DEVICE_STATUS_STR = { "Ready", "Initialized", "Uninitialized", "Initializing", "I/O Error", "Unknown" }; private static final String[] DEVICE_TYPE_STR = { "Data", "Boot", "Swap", "Unknown" }; // type = data, boot, other @@ -89,7 +91,8 @@ public class Device extends Entity { public boolean isReady() { // TODO: Check if status is INITIALIZED AND type = DATA - return getStatus() == DEVICE_STATUS.INITIALIZED; + // return (getStatus() == DEVICE_STATUS.INITIALIZED && getType() == DEVICE_TYPE.DATA); + return (getStatus() == DEVICE_STATUS.READY); } public DEVICE_STATUS getStatus() { @@ -97,6 +100,10 @@ public class Device extends Entity { } public String getStatusStr() { + if (getStatus() == null) { + return DEVICE_STATUS_STR[DEVICE_STATUS.UNKNOWN.ordinal()]; // Return as Unknown + } + if(isReady()) { return "Available"; } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java index e623f3d6..32341eca 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java @@ -26,7 +26,7 @@ import javax.xml.bind.annotation.XmlRootElement; import com.gluster.storage.management.core.utils.GlusterCoreUtil; import com.gluster.storage.management.core.utils.StringUtil; -@XmlRootElement(name="Disk") +@XmlRootElement(name="disk") public class Disk extends Device { private String description; @@ -96,19 +96,23 @@ public class Disk extends Device { return false; } - for(Disk raidDisk : raidDisks) { - // check if the disk contains same raid disks - if (!(raidDisk.equals(GlusterCoreUtil.getEntity(disk.getRaidDisks(), raidDisk.getName(), false)))) { - return false; + if (raidDisks != null) { + for (Disk raidDisk : raidDisks) { + // check if the disk contains same raid disks + if (!(raidDisk.equals(GlusterCoreUtil.getEntity(disk.getRaidDisks(), raidDisk.getName(), false)))) { + return false; + } } } - // check if the disk contains same partitions - for (Partition partition : partitions) { - if (!(partition.equals(GlusterCoreUtil.getEntity(disk.getPartitions(), partition.getName(), false)))) { - return false; - } - } +// // check if the disk contains same partitions +// if (partitions != null) { +// for (Partition partition : partitions) { +// if (!(partition.equals(GlusterCoreUtil.getEntity(disk.getPartitions(), partition.getName(), false)))) { +// return false; +// } +// } +// } return false; } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Volume.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Volume.java index 006202fb..fe05c517 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Volume.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Volume.java @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map.Entry; import java.util.Set; import javax.xml.bind.annotation.XmlElement; @@ -196,7 +197,11 @@ public class Volume extends Entity { } public void setOptions(LinkedHashMap options) { - this.options.setOptionsMap(options); + List volumeOptions = new ArrayList(); + for(Entry entry : options.entrySet()) { + volumeOptions.add(new VolumeOption(entry.getKey(), entry.getValue())); + } + this.options.setOptions(volumeOptions); } public void addBrick(Brick brick) { diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOption.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOption.java index f4ca3e81..4b54b010 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOption.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOption.java @@ -23,7 +23,7 @@ import javax.xml.bind.annotation.XmlRootElement; /** * */ -@XmlRootElement +@XmlRootElement(name="option") public class VolumeOption { private String key; private String value; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOptions.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOptions.java index f928c241..bda01075 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOptions.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeOptions.java @@ -27,64 +27,54 @@ import java.util.Set; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; /** * */ -@XmlRootElement +@XmlRootElement(name="options") public class VolumeOptions { - private Map optionsMap = new HashMap(); + private List options = new ArrayList(); public VolumeOptions() { } public String get(String key) { - return optionsMap.get(key); + for(VolumeOption option : options) { + if(option.getKey().equals(key)) { + return option.getValue(); + } + } + return null; } - public String put(String key, String value) { - return optionsMap.put(key, value); + public void put(String key, String value) { + options.add(new VolumeOption(key, value)); } @XmlElement(name="option", type=VolumeOption.class) public List getOptions() { - List options = new ArrayList(); - for(Entry entry : optionsMap.entrySet()) { - options.add(new VolumeOption(entry.getKey(), entry.getValue())); - } return options; } - public Set> getOptionsMap() { - return optionsMap.entrySet(); - } - - public void setOptionsMap(Map optionsMap) { - this.optionsMap = optionsMap; + public void setOptions(List options) { + this.options = options; } public void clear() { - optionsMap.clear(); + options.clear(); } - public Set> entrySet() { - return optionsMap.entrySet(); - } - - public Set keySet() { - return optionsMap.keySet(); - } - - public String remove(String key) { - return optionsMap.remove(key); + public boolean remove(String key) { + return options.remove(get(key)); } public int size() { - return optionsMap.size(); + return options.size(); } public boolean containsKey(String key) { - return optionsMap.containsKey(key); + return get(key) != null; } @Override @@ -108,8 +98,7 @@ public class VolumeOptions { } public void copyFrom(VolumeOptions options) { - for(Entry entry : options.entrySet()) { - optionsMap.put(entry.getKey(), entry.getValue()); - } + this.options.clear(); + this.options.addAll(options.getOptions()); } } \ No newline at end of file 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 5e49aae2..7d2b1b7b 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 @@ -47,6 +47,7 @@ public class BrickTableLabelProvider extends TableLabelProviderAdapter { DEVICE_STATUS status = disk.getStatus(); switch (status) { case INITIALIZED: + case READY: return guiHelper.getImage(IImageKeys.STATUS_ONLINE); case IO_ERROR: return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); @@ -63,7 +64,7 @@ public class BrickTableLabelProvider extends TableLabelProviderAdapter { } private String getDiskFreeSpace(Disk disk) { - if (disk.isReady() && disk.getFreeSpace() != null) { + if (disk != null && disk.isReady() && disk.getFreeSpace() != null) { return NumberUtil.formatNumber((disk.getFreeSpace() / 1024)); } else { return "NA"; 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 9759e384..e0f11a85 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 @@ -47,6 +47,7 @@ public class DiskTableLabelProvider extends TableLabelProviderAdapter { DEVICE_STATUS status = disk.getStatus(); switch (status) { case INITIALIZED: + case READY: return guiHelper.getImage(IImageKeys.STATUS_ONLINE); case IO_ERROR: return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); 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 21ce00f9..d6564610 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 @@ -42,6 +42,11 @@ public class ServerDiskTableLabelProvider extends TableLabelProviderAdapter { Disk disk = (Disk) element; if (columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.STATUS.ordinal()) { DEVICE_STATUS status = disk.getStatus(); + + if (status == null) { + return null; + } + switch (status) { case INITIALIZED: return guiHelper.getImage(IImageKeys.STATUS_ONLINE); 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 cd85d22b..53c8c472 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 @@ -20,6 +20,7 @@ package com.gluster.storage.management.gui; import java.util.Map.Entry; +import com.gluster.storage.management.core.model.VolumeOption; import com.gluster.storage.management.gui.views.pages.VolumeOptionsPage.OPTIONS_TABLE_COLUMN_INDICES; public class VolumeOptionsTableLabelProvider extends TableLabelProviderAdapter { @@ -29,11 +30,9 @@ public class VolumeOptionsTableLabelProvider extends TableLabelProviderAdapter { return null; } - Entry entry = (Entry) element; - String key = entry.getKey(); - String value = entry.getValue(); - return (columnIndex == OPTIONS_TABLE_COLUMN_INDICES.OPTION_KEY.ordinal() ? key - : columnIndex == OPTIONS_TABLE_COLUMN_INDICES.OPTION_VALUE.ordinal() ? value + VolumeOption option = (VolumeOption)element; + return (columnIndex == OPTIONS_TABLE_COLUMN_INDICES.OPTION_KEY.ordinal() ? option.getKey() + : columnIndex == OPTIONS_TABLE_COLUMN_INDICES.OPTION_VALUE.ordinal() ? option.getValue() : "Invalid"); } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionKeyEditingSupport.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionKeyEditingSupport.java index 1f64d82e..924c5cc8 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionKeyEditingSupport.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionKeyEditingSupport.java @@ -4,7 +4,6 @@ package com.gluster.storage.management.gui.views.pages; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.Map.Entry; @@ -17,6 +16,7 @@ import org.eclipse.swt.widgets.Composite; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.VolumeOption; import com.gluster.storage.management.core.model.VolumeOptionInfo; import com.gluster.storage.management.core.model.VolumeOptions; @@ -73,7 +73,7 @@ public class OptionKeyEditingSupport extends EditingSupport { @Override protected Object getValue(Object element) { - Entry entryBeingAdded = getEntryBeingAdded(); + VolumeOption entryBeingAdded = getEntryBeingAdded(); if(entryBeingAdded == null) { return cellEditor.getValue(); } @@ -93,7 +93,7 @@ public class OptionKeyEditingSupport extends EditingSupport { return cellEditor; } - private int getIndexOfEntry(Entry entryBeingAdded) { + private int getIndexOfEntry(VolumeOption entryBeingAdded) { for(int index = 0; index < allowedKeys.length; index++) { if(allowedKeys[index].equals(entryBeingAdded.getKey())) { return index; @@ -102,18 +102,16 @@ public class OptionKeyEditingSupport extends EditingSupport { return -1; } - protected Entry getEntryBeingAdded() { - Entry entryBeingAdded = null; - Iterator> iter = volume.getOptions().entrySet().iterator(); - while(iter.hasNext()) { - Entry nextEntry = iter.next(); - if(!iter.hasNext() && nextEntry.getValue().isEmpty()) { - // it's the LAST entry, and it's value is empty. - // means this is a new row being added in the table viewer. - entryBeingAdded = nextEntry; - } + protected VolumeOption getEntryBeingAdded() { + List options = volume.getOptions().getOptions(); + int size = options.size(); + String lastValue = options.get(size - 1).getValue(); + if(lastValue == null || lastValue.isEmpty()) { + // it's the LAST entry, and it's value is empty. + // means this is a new row being added in the table viewer. + return options.get(size - 1); } - return entryBeingAdded; + return null; } @SuppressWarnings("unchecked") diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionValueEditingSupport.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionValueEditingSupport.java index 2358aa73..b349ab78 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionValueEditingSupport.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/OptionValueEditingSupport.java @@ -18,6 +18,7 @@ import org.eclipse.swt.widgets.Display; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.client.VolumesClient; import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.VolumeOption; import com.gluster.storage.management.core.model.VolumeOptionInfo; import com.gluster.storage.management.gui.utils.GUIHelper; @@ -39,7 +40,7 @@ public class OptionValueEditingSupport extends EditingSupport { @SuppressWarnings("unchecked") @Override protected void setValue(final Object element, final Object value) { - final Entry entry = (Entry) element; + final VolumeOption entry = (VolumeOption)element; final String optionKey = entry.getKey(); final String optionValue = (String)value; final String oldValue = entry.getValue(); @@ -67,9 +68,9 @@ public class OptionValueEditingSupport extends EditingSupport { public void run() { VolumesClient client = new VolumesClient(); try { - client.setVolumeOption(volume.getName(), entry.getKey(), (String) value); + client.setVolumeOption(volume.getName(), optionKey, optionValue); entry.setValue((String)value); - GlusterDataModelManager.getInstance().setVolumeOption(volume, entry); + GlusterDataModelManager.getInstance().setVolumeOption(volume, optionKey, optionValue); } catch(Exception e) { MessageDialog.openError(Display.getDefault().getActiveShell(), "Set Volume Option", e.getMessage()); } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java index 956fc215..b131999b 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java @@ -58,6 +58,7 @@ import com.gluster.storage.management.core.model.DefaultClusterListener; import com.gluster.storage.management.core.model.Event; import com.gluster.storage.management.core.model.Event.EVENT_TYPE; import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.VolumeOption; import com.gluster.storage.management.core.model.VolumeOptionInfo; import com.gluster.storage.management.gui.VolumeOptionsTableLabelProvider; import com.gluster.storage.management.gui.utils.GUIHelper; @@ -103,7 +104,7 @@ public class VolumeOptionsPage extends Composite { setAddButtonsEnabled(false); } - tableViewer.setInput(volume.getOptions().entrySet()); + tableViewer.setInput(volume.getOptions()); parent.layout(); // Important - this actually paints the table registerListeners(parent); @@ -151,7 +152,7 @@ public class VolumeOptionsPage extends Composite { if (!(addTopButton.isEnabled() || addBottomButton.isEnabled())) { // user has selected key, but not added value. Since this is not a valid entry, // remove the last option (without value) from the volume - Entry entryBeingAdded = keyEditingSupport.getEntryBeingAdded(); + VolumeOption entryBeingAdded = keyEditingSupport.getEntryBeingAdded(); volume.getOptions().remove(entryBeingAdded.getKey()); } } @@ -200,7 +201,7 @@ public class VolumeOptionsPage extends Composite { } // if this is the last option in the volume options, it must be the new option - return optionKey.equals(volume.getOptions().keySet().toArray()[volume.getOptions().size() - 1]); + return optionKey.equals(volume.getOptions().getOptions().get(volume.getOptions().size() - 1)); } }; @@ -219,8 +220,8 @@ public class VolumeOptionsPage extends Composite { filterText.setEnabled(false); } - private Entry getEntry(String key) { - for (Entry entry : volume.getOptions().entrySet()) { + private VolumeOption getEntry(String key) { + for (VolumeOption entry : volume.getOptions().getOptions()) { if (entry.getKey().equals(key)) { return entry; } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java index 2e78b57b..e8073765 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java @@ -20,20 +20,17 @@ */ package com.gluster.storage.management.server.utils; -import java.io.BufferedReader; import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.InetAddress; -import java.net.Socket; +import java.io.ByteArrayOutputStream; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.servlet.ServletContext; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import org.springframework.beans.factory.annotation.Autowired; @@ -44,6 +41,8 @@ import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.model.Status; +import com.gluster.storage.management.core.model.VolumeOption; +import com.gluster.storage.management.core.model.VolumeOptions; import com.gluster.storage.management.core.response.GenericResponse; import com.gluster.storage.management.core.utils.ProcessResult; import com.gluster.storage.management.core.utils.ProcessUtil; @@ -86,7 +85,7 @@ public class ServerUtil { */ public void fetchServerDetails(Server server) { // fetch standard server details like cpu, disk, memory details - Object response = executeOnServer(true, server.getName(), "get_server_details.py --only-data-disks", Server.class); + Object response = executeOnServer(true, server.getName(), "get_server_details.py", Server.class); if (response instanceof Status) { throw new GlusterRuntimeException(((Status)response).getMessage()); } @@ -225,10 +224,13 @@ public class ServerUtil { } public static void main(String args[]) throws Exception { - ServerUtil su = new ServerUtil(); - su.setSshUtil(new SshUtil()); - // Object result = new ServerUtil().executeOnServer(true, "serverName", "ls -lrt", String.class); - // System.out.println(result); + //String diskStr = "devserver110.1.10.18.8.4.4eth000:50:56:82:00:1d1000ETHERNETyesnone10.1.12.41255.255.255.010.1.12.120.02010.52343751267.6015625ONLINEsddVMware Virtual diskUNINITIALIZEDfalsefalsepci10240sdd1UNINITIALIZEDfalsefalse10236sdaVMware Virtual diskUNINITIALIZEDfalsefalsepci102402019sda1345d880e-822a-4e46-a518-75cc48b1869fINITIALIZEDtruefalseext3/boot12511sda2UNINITIALIZEDfalsefalseswap125sda3f94a0b2a-5ebc-4c13-a618-0328af97a31eINITIALIZEDtruefalseext3/99852008sdbVMware Virtual disk97ee7ea3-d235-424c-bdda-f5b697f204a2READYtruetruepciext31.0/export/sdb1024427sdcVMware Virtual disk87679044-6395-42fb-a80d-41c3b648f248READYtruetruepciext31.0/export/sdc8192602"; + String diskStr = ""; + //diskStr = ""; + VolumeOptions disk = (VolumeOptions)new ServerUtil().unmarshal(VolumeOptions.class, diskStr, false); + System.out.println(disk.size()); + for(VolumeOption option : disk.getOptions()) { + System.out.println(option.toString()); + } } - } -- cgit