From ea79ff5d088c25ad07203fd2e8f9f396d031bb21 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 30 May 2011 19:35:12 +0530 Subject: Removed nodes, common, server folders and moved the python files to com.gluster.storage.management.server.script directory --- .../src/Commands.py | 78 +++ .../src/Common.py | 43 ++ .../src/Disk.py | 141 +++++ .../src/DiskUtils.py | 226 +++++++ .../src/GetServerNetworkConfig.py | 96 +++ .../src/Globals.py | 120 ++++ .../src/GlusterdUtils.py | 250 ++++++++ .../src/NetworkUtils.py | 450 +++++++++++++ .../src/Protocol.py | 438 +++++++++++++ .../src/ServerUtils.py | 308 +++++++++ .../src/Utils.py | 703 +++++++++++++++++++++ .../src/VolumeUtils.py | 610 ++++++++++++++++++ .../src/XmlHandler.py | 346 ++++++++++ .../src/clear_volume_directory.py | 101 +++ .../src/common/Commands.py | 78 --- .../src/common/Common.py | 43 -- .../src/common/DiskUtils.py | 226 ------- .../src/common/Globals.py | 120 ---- .../src/common/NetworkUtils.py | 450 ------------- .../src/common/Protocol.py | 438 ------------- .../src/common/Utils.py | 703 --------------------- ...m-config-network-tui-1.3.99.18-1.el5.noarch.rpm | Bin 1915520 -> 0 bytes .../src/create_volume_directory.py | 85 +++ .../src/get_disk_mount_point.py | 64 ++ .../src/get_disk_name_by_path.py | 69 ++ .../src/get_file.py | 132 ++++ .../src/get_server_details.py | 224 +++++++ .../src/get_volume_brick_log.py | 109 ++++ .../src/get_volume_log.py | 132 ++++ .../src/multicast_response.py | 64 ++ .../src/nodes/Agent.py | 118 ---- .../src/nodes/Disk.py | 141 ----- .../src/nodes/GetServerNetworkConfig.py | 96 --- .../src/nodes/GlusterdUtils.py | 250 -------- .../src/nodes/PeerAgent.py | 212 ------- .../src/nodes/ServerAgent.py | 179 ------ .../src/nodes/ServerRequestHandler.py | 76 --- .../src/nodes/ServerUtils.py | 308 --------- .../src/nodes/Socket.py | 47 -- .../src/nodes/VolumeUtils.py | 610 ------------------ .../src/nodes/XmlHandler.py | 346 ---------- .../src/nodes/clear_volume_directory.py | 101 --- .../src/nodes/create_volume_directory.py | 85 --- .../src/nodes/get_disk_mount_point.py | 64 -- .../src/nodes/get_disk_name_by_path.py | 69 -- .../src/nodes/get_file.py | 132 ---- .../src/nodes/get_server_details.py | 224 ------- .../src/nodes/get_volume_brick_log.py | 109 ---- .../src/nodes/get_volume_log.py | 132 ---- .../src/nodes/multicast_response.py | 64 -- .../src/server/RemoteExecute.py | 287 --------- .../src/server/RequestHandler.py | 58 -- .../src/server/TransportAgent.py | 26 - .../src/server/transport.py | 94 --- .../src/server/vmware-discover-servers.py | 83 --- 55 files changed, 4789 insertions(+), 5969 deletions(-) create mode 100644 src/com.gluster.storage.management.server.scripts/src/Commands.py create mode 100644 src/com.gluster.storage.management.server.scripts/src/Common.py create mode 100755 src/com.gluster.storage.management.server.scripts/src/Disk.py create mode 100644 src/com.gluster.storage.management.server.scripts/src/DiskUtils.py create mode 100644 src/com.gluster.storage.management.server.scripts/src/GetServerNetworkConfig.py create mode 100644 src/com.gluster.storage.management.server.scripts/src/Globals.py create mode 100644 src/com.gluster.storage.management.server.scripts/src/GlusterdUtils.py create mode 100755 src/com.gluster.storage.management.server.scripts/src/NetworkUtils.py create mode 100644 src/com.gluster.storage.management.server.scripts/src/Protocol.py create mode 100644 src/com.gluster.storage.management.server.scripts/src/ServerUtils.py create mode 100644 src/com.gluster.storage.management.server.scripts/src/Utils.py create mode 100644 src/com.gluster.storage.management.server.scripts/src/VolumeUtils.py create mode 100644 src/com.gluster.storage.management.server.scripts/src/XmlHandler.py create mode 100755 src/com.gluster.storage.management.server.scripts/src/clear_volume_directory.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/common/Commands.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/common/Common.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/common/DiskUtils.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/common/Globals.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/common/NetworkUtils.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/common/Protocol.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/common/Utils.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/common/system-config-network-tui-1.3.99.18-1.el5.noarch.rpm create mode 100755 src/com.gluster.storage.management.server.scripts/src/create_volume_directory.py create mode 100755 src/com.gluster.storage.management.server.scripts/src/get_disk_mount_point.py create mode 100755 src/com.gluster.storage.management.server.scripts/src/get_disk_name_by_path.py create mode 100755 src/com.gluster.storage.management.server.scripts/src/get_file.py create mode 100755 src/com.gluster.storage.management.server.scripts/src/get_server_details.py create mode 100755 src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py create mode 100755 src/com.gluster.storage.management.server.scripts/src/get_volume_log.py create mode 100644 src/com.gluster.storage.management.server.scripts/src/multicast_response.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/nodes/Agent.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/nodes/Disk.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/nodes/GetServerNetworkConfig.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/nodes/GlusterdUtils.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/nodes/PeerAgent.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/nodes/ServerAgent.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/nodes/ServerRequestHandler.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/nodes/ServerUtils.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/nodes/Socket.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/nodes/VolumeUtils.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/nodes/XmlHandler.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/nodes/clear_volume_directory.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/nodes/create_volume_directory.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/nodes/get_disk_mount_point.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/nodes/get_disk_name_by_path.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/nodes/get_file.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/nodes/get_server_details.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/nodes/get_volume_brick_log.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/nodes/get_volume_log.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/nodes/multicast_response.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/server/RemoteExecute.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/server/RequestHandler.py delete mode 100644 src/com.gluster.storage.management.server.scripts/src/server/TransportAgent.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/server/transport.py delete mode 100755 src/com.gluster.storage.management.server.scripts/src/server/vmware-discover-servers.py diff --git a/src/com.gluster.storage.management.server.scripts/src/Commands.py b/src/com.gluster.storage.management.server.scripts/src/Commands.py new file mode 100644 index 00000000..c728b565 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/Commands.py @@ -0,0 +1,78 @@ +COMMAND_CREATE_VOLUME = "create-volume" +COMMAND_DELETE_VOLUME = "delete-volume" +COMMAND_START_VOLUME = "start-volume" +COMMAND_STOP_VOLUME = "stop-volume" +COMMAND_GET_VOLUME_HEALTH_STATUS = "get-volume-health-status" +COMMAND_GET_VOLUME_LIST = "get-volume-list" +COMMAND_GET_VOLUME_LOG = "get-volume-log" +COMMAND_CLEAR_VOLUME_LOGS = "clear-volume-logs" +COMMAND_GET_VOLUME_PROPERTY = "get-volume-property" +COMMAND_SET_VOLUME_PROPERTY = "set-volume-property" +COMMAND_GET_VOLUME_STATUS = "get-volume-status" +COMMAND_DOWNLOAD_VOLUME_LOGS = "download-volume-logs" +COMMAND_DELETE_SERVER = "delete-server" +COMMAND_GET_SERVER_DATE = "get-server-date" +COMMAND_GET_SERVER_VERSION_INFO = "get-server-version-info" +COMMAND_GET_INSTALLER_INFO = "get-installer-info" +COMMAND_GET_SERVER_LIST = "get-server-list" +COMMAND_GET_SERVER_SERVICE_STATUS = "get-server-service-status" +COMMAND_GET_STORAGE_SERVER_POOL_INFO = "get-storage-server-pool-info" +COMMAND_INSTALL_SERVER_BACKGROUND = "install-server-background" +COMMAND_PREPARE_DATA_DISK_BACKGROUND = "prepare-data-disk-background" +COMMAND_SET_SERVER_DATE = "set-server-date" +COMMAND_SET_SERVER_NETWORK_CONFIG = "set-server-network-config" +COMMAND_SET_STORAGE_SERVER_POOL_INFO = "set-storage-server-pool-info" +COMMAND_GET_SERVER_NETWORK_CONFIG = "get-server-network-config" +COMMAND_INSTALL_SERVER_STATUS = "install-server-status" +COMMAND_GET_SERVER_DISK_LIST = "get-server-disk-list" +COMMAND_PREPARE_DATA_DISK_STATUS = "prepare-data-disk-status" +COMMAND_GET_SERVER_SYSTEM_RESOURCE = "get-server-system-resource" +COMMAND_GET_SERVER_RESOURCE_RRD = "get-server-resource-rrd" +COMMAND_RUN_SERVER_SERVICE = "run-server-service" +COMMAND_SHUTDOWN_SERVER = "shutdown-server" +COMMAND_GET_SERVER_STATUS = "get-server-status" +COMMAND_GET_SERVER_LOG = "get-server-log" +COMMAND_DOWNLOAD_SERVER_LOGS = "download-server-logs" +COMMAND_CLEAR_SERVER_LOGS = "clear-server-logs" +COMMAND_GET_SERVER_RESOURCE_RRD = "get-server-resource-rrd" +COMMAND_GET_GSN_USER_INFO = "get-gsn-user-info" +COMMAND_SET_GSN_USER_INFO = "set-gsn-user-info" +COMMAND_GET_GLUSTER_UPDATE_INFO = "get-gluster-update-info" +COMMAND_DOWNLOAD_GLUSTER_UPDATE_BACKGROUND = "download-gluster-update-background" +COMMAND_DOWNLOAD_GLUSTER_UPDATE_STATUS = "download-gluster-update-status" +COMMAND_INSTALL_GLUSTER_UPDATE = "install-gluster-update" +COMMAND_EXPORT_CONFIG = "export-config" +COMMAND_IMPORT_CONFIG = "import-config" +COMMAND_SET_SYSTEM_PASSWORD = "set-system-password" +COMMAND_GET_SERVER_VOLUME_LIST = "get-server-volume-list" +COMMAND_RECONFIGURE_VOLUME = "reconfigure-volume" +COMMAND_SET_SERVER_DIRECTORY_SERVICE_CONFIG = "set-server-directory-service-config" +COMMAND_GET_SERVER_DIRECTORY_SERVICE_CONFIG = "get-server-directory-service-config" +COMMAND_JOIN_SERVER_TO_DIRECTORY_SERVICE = "join-server-to-directory-service" +COMMAND_SET_SERVER_TIME_CONFIG = "set-server-time-config" +COMMAND_GET_SERVER_TIME_CONFIG = "get-server-time-config" +COMMAND_LOGIN = "login" +COMMAND_LOGOUT = "logout" +COMMAND_GET_LOGIN_STATUS = "get-login-status" +COMMAND_GET_SERVER_TRANSPORT_LIST = "get-server-transport-list" +COMMAND_ADD_SERVER_PARTITION = "add-server-partition" +COMMAND_ADD_VOLUME_USER = "add-volume-user" +COMMAND_GET_PARTITION_VOLUME_LIST = "get-partition-volume-list" +COMMAND_GET_VOLUME_USER_INFO = "get-volume-user-info" +COMMAND_GET_VOLUME_USER_LIST = "get-volume-user-list" +COMMAND_MIGRATE_PARTITION_BACKGROUND = "migrate-partition-background" +COMMAND_MIGRATE_PARTITION_STATUS = "migrate-partition-status" +COMMAND_MIGRATE_VOLUME_SERVER_PARTITION_BACKGROUND = "migrate-volume-server-partition-background" +COMMAND_MIGRATE_VOLUME_SERVER_PARTITION_STATUS = "migrate-volume-server-partition-status" +COMMAND_REMOVE_SERVER_PARTITION = "remove-server-partition" +COMMAND_REMOVE_VOLUME_USER = "remove-volume-user" +COMMAND_RENAME_VOLUME_USER = "rename-volume-user" +COMMAND_RENAME_VOLUME = "rename-volume" +COMMAND_RUN_SERVER_SERVICE = "run-server-service" +COMMAND_SET_VOLUME_USER_PASSWORD = "set-volume-user-password" +COMMAND_STOP_PARTITION_MIGRATION = "stop-partition-migration" +COMMAND_STOP_VOLUME_SERVER_PARTITION_MIGRATION = "stop-volume-server-partition-migration" +COMMAND_GET_SERVER_DISK_INFO = "get-server-disk-info" +COMMAND_INITIALIZE_SERVER_DISK = "initialize-server-disk" +COMMAND_SET_SERVER_COUNT = "set-server-count" +COMMAND_GET_SERVER_COUNT = "get-server-count" diff --git a/src/com.gluster.storage.management.server.scripts/src/Common.py b/src/com.gluster.storage.management.server.scripts/src/Common.py new file mode 100644 index 00000000..99c2f440 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/Common.py @@ -0,0 +1,43 @@ +# Copyright (c) 2009 Gluster, Inc. +# This file is part of GlusterSP. +# +# GlusterSP is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 3 of the License, +# or (at your option) any later version. +# +# GlusterSP is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import sys +import syslog + +def log(priority, message=None): + if type(priority) == type(""): + logPriority = syslog.LOG_INFO + logMessage = priority + else: + logPriority = priority + logMessage = message + if not logMessage: + return + #if Globals.DEBUG: + # sys.stderr.write(logMessage) + else: + syslog.syslog(logPriority, logMessage) + return + + +def stripEmptyLines(content): + ret = "" + for line in content.split("\n"): + if line.strip() != "": + ret += line + return ret + diff --git a/src/com.gluster.storage.management.server.scripts/src/Disk.py b/src/com.gluster.storage.management.server.scripts/src/Disk.py new file mode 100755 index 00000000..a1ab9264 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/Disk.py @@ -0,0 +1,141 @@ +# Copyright (c) 2009 Gluster, Inc. +# This file is part of GlusterSP. +# +# GlusterSP is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 3 of the License, +# or (at your option) any later version. +# +# GlusterSP is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import os +import dbus +from Common import * + +class Disk: + def __init__(self): + """init""" + + self.volumes = [] + self.disks = [] + self.bus = dbus.SystemBus() + self.hal_obj = self.bus.get_object("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager") + self.hal = dbus.Interface(self.hal_obj, "org.freedesktop.Hal.Manager") + self.devices = [] + self.devices = self.hal.FindDeviceByCapability("storage") + + self.detect_disks() + self.detect_mountable_volumes() + + def getDiskList(self): + + return self.disks + + def getMountableDiskList(self): + + return self.volumes + + def detect_disks(self): + for device in self.devices: + dev = self._get_device(device) + if dev.GetProperty("storage.drive_type") != "cdrom": + if not dev.GetProperty("block.is_volume"): + self._add_disks(dev) + continue + + def _add_disks(self, dev): + disk = str(dev.GetProperty('block.device')) + disk_size = str(int(dev.GetProperty('storage.size')) / 1024**2) + + try: + if dev.GetProperty('storage.removable'): + disk_size = str(int(dev.GetProperty('storage.removable.media_size')) / 1024**2) + except: + return + + self.disks.append({ + 'device': disk, + 'description': str(dev.GetProperty('storage.model')) + " " + str(dev.GetProperty('storage.vendor')), + 'interface': str(dev.GetProperty('storage.bus')), + 'size': disk_size, + 'drive_type': str(dev.GetProperty('storage.drive_type')) + }) + + def detect_mountable_volumes(self): + """ Detect all mountable volumes using HAL via D-Bus """ + for device in self.devices: + dev = self._get_device(device) + if dev.GetProperty("storage.drive_type") != "cdrom": + if dev.GetProperty("block.is_volume"): + self._add_volume(dev) + continue + else: # iterate over children looking for a volume + children = self.hal.FindDeviceStringMatch("info.parent", + device) + if not children and "disk" == dev.GetProperty("storage.drive_type"): + self._add_volume(dev) + for child in children: + child = self._get_device(child) + if child.GetProperty("block.is_volume"): + self._add_volume(child, parent=dev) + #break # don't break, allow all partitions + + def _add_volume(self, dev, parent=None): + volume = str(dev.GetProperty('block.device')) + if not parent: + self.volumes.append ({ + 'device' : volume, + 'label' : str(dev.GetProperty('block.device')), + 'fstype' : None, + 'fsversion': None, + 'uuid' : None, + 'interface': str(dev.GetProperty('storage.bus')), + 'parent' : None, + 'description': str(dev.GetProperty('storage.model')) + " " + str(dev.GetProperty('storage.vendor')), + 'size' : None, + 'totalsize' : str(int(dev.GetProperty('storage.size')) / 1024**2), + 'drive_type': str(dev.GetProperty('storage.drive_type')), + 'mount_point': "NA" + }) + return + + self.volumes.append ({ + 'device' : volume, + 'label' : str(dev.GetProperty('volume.label')), + 'fstype' : str(dev.GetProperty('volume.fstype')), + 'fsversion': str(dev.GetProperty('volume.fsversion')), + 'uuid' : str(dev.GetProperty('volume.uuid')), + 'interface': str(parent.GetProperty('storage.bus')), + 'parent' : str(parent.GetProperty('block.device')), + 'description': str(parent.GetProperty('storage.model')) + " " + str(parent.GetProperty('storage.vendor')), + 'size' : str(int(dev.GetProperty('volume.size')) / 1024**2), + 'totalsize' : str(int(parent.GetProperty('storage.size')) / 1024**2), + 'drive_type': str(parent.GetProperty('storage.drive_type')), + 'mount_point': str(dev.GetProperty('volume.mount_point')) + }) + return + + def _get_device(self, udi): + """ Return a dbus Interface to a specific HAL device UDI """ + dev_obj = self.bus.get_object("org.freedesktop.Hal", udi) + return dbus.Interface(dev_obj, "org.freedesktop.Hal.Device") + + def get_free_bytes(self, device=None): + """ Return the number of available bytes on our device """ + import statvfs + stat = os.statvfs(device) + return stat[statvfs.F_BSIZE] * stat[statvfs.F_BAVAIL] + + def get_used_bytes(self, device=None): + """ Return the number of used bytes on our device """ + import statvfs + stat = os.statvfs(device) + return ((stat[statvfs.F_BSIZE] * stat[statvfs.F_BLOCKS]) - (stat[statvfs.F_BSIZE] * stat[statvfs.F_BAVAIL])) diff --git a/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py b/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py new file mode 100644 index 00000000..0e42bba2 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/DiskUtils.py @@ -0,0 +1,226 @@ +# Copyright (c) 2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import os +import glob +import dbus + +import Globals +from Utils import * + +ONE_MB_SIZE = 1048576 + + +def _stripDev(device): + if isString(device) and device.startswith("/dev/"): + return device[5:] + return device + + +def _addDev(deviceName): + if isString(deviceName) and not deviceName.startswith("/dev/"): + return "/dev/" + deviceName + return deviceName + + +def getDeviceName(device): + if type(device) == type([]): + nameList = [] + for d in device: + nameList.append(_stripDev(d)) + return nameList + return _stripDev(device) + + +def getDevice(deviceName): + if isString(deviceName): + return _addDev(deviceName) + if type(deviceName) == type([]): + nameList = [] + for d in deviceName: + nameList.append(_addDev(d)) + return nameList + return _addDev(deviceName) + + +def getDiskPartitionByUuid(uuid): + uuidFile = "/dev/disk/by-uuid/%s" % uuid + if os.path.exists(uuidFile): + return getDeviceName(os.path.realpath(uuidFile)) + return None + + +def getUuidByDiskPartition(device): + for uuidFile in glob.glob("/dev/disk/by-uuid/*"): + if os.path.realpath(uuidFile) == device: + return os.path.basename(uuidFile) + return None + + +def getDiskPartitionUuid(partition): + log("WARNING: getDiskPartitionUuid() is deprecated by getUuidByDiskPartition()") + return getUuidByDiskPartition(partition) + + +def getDiskPartitionByLabel(label): + ## TODO: Finding needs to be enhanced + labelFile = "/dev/disk/by-label/%s" % label + if os.path.exists(labelFile): + return getDeviceName(os.path.realpath(labelFile)) + return None + + +def getDeviceByLabel(label): + log("WARNING: getDeviceByLabel() is deprecated by getDiskPartitionByLabel()") + return getDiskPartitionByLabel(label) + + +def getDiskPartitionLabel(device): + rv = runCommandFG(["sudo", "e2label", device], stdout=True) + if rv["Status"] == 0: + return rv["Stdout"].strip() + return False + + +def getRootPartition(fsTabFile=Globals.FSTAB_FILE): + fsTabEntryList = readFsTab(fsTabFile) + for fsTabEntry in fsTabEntryList: + if fsTabEntry["MountPoint"] == "/": + if fsTabEntry["Device"].startswith("UUID="): + return getDiskPartitionByUuid(fsTabEntry["Device"].split("UUID=")[-1]) + if fsTabEntry["Device"].startswith("LABEL="): + return getDiskPartitionByLabel(fsTabEntry["Device"].split("LABEL=")[-1]) + return getDeviceName(fsTabEntry["Device"]) + return None + + +def getOsDisk(): + log("WARNING: getOsDisk() is deprecated by getRootPartition()") + return getRootPartition() + + +def getDiskList(diskDeviceList=None): + diskDeviceList = getDevice(diskDeviceList) + if isString(diskDeviceList): + diskDeviceList = [diskDeviceList] + + dbusSystemBus = dbus.SystemBus() + halObj = dbusSystemBus.get_object("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager") + halManager = dbus.Interface(halObj, "org.freedesktop.Hal.Manager") + storageUdiList = halManager.FindDeviceByCapability("storage") + + diskList = [] + for udi in storageUdiList: + halDeviceObj = dbusSystemBus.get_object("org.freedesktop.Hal", udi) + halDevice = dbus.Interface(halDeviceObj, + "org.freedesktop.Hal.Device") + if halDevice.GetProperty("storage.drive_type") == "cdrom" or \ + halDevice.GetProperty("block.is_volume"): + continue + + disk = {} + disk["Device"] = str(halDevice.GetProperty('block.device')) + if diskDeviceList and disk["Device"] not in diskDeviceList: + continue + disk["Description"] = str(halDevice.GetProperty('storage.vendor')) + " " + str(halDevice.GetProperty('storage.model')) + if halDevice.GetProperty('storage.removable'): + disk["Size"] = long(halDevice.GetProperty('storage.removable.media_size')) + else: + disk["Size"] = long(halDevice.GetProperty('storage.size')) + disk["Interface"] = str(halDevice.GetProperty('storage.bus')) + disk["DriveType"] = str(halDevice.GetProperty('storage.drive_type')) + partitionList = [] + partitionUdiList = halManager.FindDeviceStringMatch("info.parent", udi) + for partitionUdi in partitionUdiList: + partitionHalDeviceObj = dbusSystemBus.get_object("org.freedesktop.Hal", + partitionUdi) + partitionHalDevice = dbus.Interface(partitionHalDeviceObj, + "org.freedesktop.Hal.Device") + if not partitionHalDevice.GetProperty("block.is_volume"): + continue + partition = {} + partition["Device"] = str(partitionHalDevice.GetProperty('block.device')) + partition["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid')) + partition["Size"] = long(partitionHalDevice.GetProperty('volume.size')) + partition["Fstype"] = str(partitionHalDevice.GetProperty('volume.fstype')) + partition["Fsversion"] = str(partitionHalDevice.GetProperty('volume.fsversion')) + partition["Label"] = str(partitionHalDevice.GetProperty('volume.label')) + partition["Used"] = 0L + if partitionHalDevice.GetProperty("volume.is_mounted"): + rv = runCommandFG(["df", str(partitionHalDevice.GetProperty('volume.mount_point'))], stdout=True) + if rv["Status"] == 0: + try: + partition["Used"] = long(rv["Stdout"].split("\n")[1].split()[2]) + except IndexError: + pass + except ValueError: + pass + partitionList.append(partition) + disk["Partitions"] = partitionList + diskList.append(disk) + return diskList + +def readFsTab(fsTabFile=Globals.FSTAB_FILE): + try: + fsTabfp = open(fsTabFile) + except IOError, e: + Utils.log("readFsTab(): " + str(e)) + return None + + fsTabEntryList = [] + for line in fsTabfp: + tokens = line.strip().split() + if not tokens or tokens[0].startswith('#'): + continue + fsTabEntry = {} + fsTabEntry["Device"] = None + fsTabEntry["MountPoint"] = None + fsTabEntry["FsType"] = None + fsTabEntry["Options"] = None + fsTabEntry["DumpOption"] = 0 + fsTabEntry["fsckOrder"] = 0 + try: + fsTabEntry["Device"] = tokens[0] + fsTabEntry["MountPoint"] = tokens[1] + fsTabEntry["FsType"] = tokens[2] + fsTabEntry["Options"] = tokens[3] + fsTabEntry["DumpOption"] = tokens[4] + fsTabEntry["fsckOrder"] = tokens[5] + except IndexError: + pass + if fsTabEntry["Device"] and fsTabEntry["MountPoint"] and fsTabEntry["FsType"] and fsTabEntry["Options"]: + fsTabEntryList.append(fsTabEntry) + + fsTabfp.close() + return fsTabEntryList + + +def getMountPointByUuid(partitionUuid): + # check uuid in etc/fstab + try: + fstabEntries = open(Globals.FSTAB_FILE).readlines() + except IOError: + fstabEntries = [] + found = False + for entry in fstabEntries: + entry = entry.strip() + if not entry: + continue + if entry.split()[0] == "UUID=" + partitionUuid: + return entry.split()[1] + return None diff --git a/src/com.gluster.storage.management.server.scripts/src/GetServerNetworkConfig.py b/src/com.gluster.storage.management.server.scripts/src/GetServerNetworkConfig.py new file mode 100644 index 00000000..3311eb56 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/GetServerNetworkConfig.py @@ -0,0 +1,96 @@ +# Copyright (C) 2009 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import sys +import syslog +import Globals +import Commands +import re +from ServerUtils import * +from Protocol import * +from NetworkUtils import * + +def getServerNetworkConfig(requestXml): + serverName = requestXml.getTextByTagRoute("command.server-name") + version = requestXml.getVersion() + messageId = requestXml.getAttribute("id") + + if not serverName: + responseDom = ResponseXml(Commands.COMMAND_GET_SERVER_NETWORK_CONFIG, "No server name given", messageId, version) + responseDom.appendTagRoute("server.name", serverName) + return responseDom + responseDom = ResponseXml(Commands.COMMAND_GET_SERVER_NETWORK_CONFIG, "OK", messageId, version) + serverTag = responseDom.createTag("server", None) + serverTag.appendChild(responseDom.createTag("name", serverName)) + nameServerList, domain, searchDomain = readResolvConfFile() + if domain: + domainName = domain[0] + else: + domainName = None + serverTag.appendChild(responseDom.createTag("domainname", domainName)) + i = 1 + for dns in nameServerList: + serverTag.appendChild(responseDom.createTag("dns%s" % i, dns)) + i += 1 + #TODO: probe and retrieve timezone, ntp-server, preferred-network details and update the tags + configDom = XDOM() + if configDom.parseFile("%s/%s/network.xml" % (Globals.SERVER_CONF_DIR, serverName)): + serverTag.appendChild(responseDom.createTag("timezone", configDom.getTextByTagRoute("network.timezone"))) + serverTag.appendChild(responseDom.createTag("ntp-server", configDom.getTextByTagRoute("network.ntp-server"))) + preferredNetwork = configDom.getTextByTagRoute("network.preferred-network") + if not preferredNetwork: + preferredNetwork = "any" + serverTag.appendChild(responseDom.createTag("preferred-network", preferredNetwork)) + + deviceList = {} + for device in getNetDeviceList(): + deviceList[device["device"]] = device + try: + macAddress = open("/sys/class/net/%s/address" % device["device"]).read().strip() + except IOError: + continue + interfaceTag = responseDom.createTag("interface", None) + interfaceTag.appendChild(responseDom.createTag("device", device["device"])) + interfaceTag.appendChild(responseDom.createTag("description", device["description"])) + interfaceTag.appendChild(responseDom.createTag("hwaddr", macAddress)) + if deviceList[device["device"]]: + if deviceList[device["device"]]["onboot"]: + interfaceTag.appendChild(responseDom.createTag("onboot", "yes")) + else: + interfaceTag.appendChild(responseDom.createTag("onboot", "no")) + interfaceTag.appendChild(responseDom.createTag("bootproto", deviceList[device["device"]]["bootproto"])) + interfaceTag.appendChild(responseDom.createTag("ipaddr", deviceList[device["device"]]["ipaddr"])) + interfaceTag.appendChild(responseDom.createTag("netmask", deviceList[device["device"]]["netmask"])) + interfaceTag.appendChild(responseDom.createTag("gateway", deviceList[device["device"]]["gateway"])) + if deviceList[device["device"]]["mode"]: + interfaceTag.appendChild(responseDom.createTag("mode", deviceList[device["device"]]["mode"])) + if deviceList[device["device"]]["master"]: + interfaceTag.appendChild(responseDom.createTag("bonding", "yes")) + spliter = re.compile(r'[\D]') + interfaceTag.appendChild(responseDom.createTag("bondid", spliter.split(device["master"])[-1])) + else: + interfaceTag.appendChild(responseDom.createTag("onboot", "no")) + interfaceTag.appendChild(responseDom.createTag("bootproto", "none")) + serverTag.appendChild(interfaceTag) + responseDom.appendTag(serverTag) + return responseDom + +def test(): + requestString = """ +s1""" + requestDom = RequestXml(requestString) + print getServerNetworkConfig(requestDom).toxml() diff --git a/src/com.gluster.storage.management.server.scripts/src/Globals.py b/src/com.gluster.storage.management.server.scripts/src/Globals.py new file mode 100644 index 00000000..9ae53491 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/Globals.py @@ -0,0 +1,120 @@ +# Copyright (C) 2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +MULTICAST_GROUP = '224.224.1.1' +MULTICAST_PORT = 5353 +GLUSTER_PLATFORM_VERSION = "3.2" + +## System configuration constants +SYSCONFIG_NETWORK_DIR = "/etc/sysconfig/network-scripts" +DNSMASQ_CONF_DIR = "/etc/dnsmasq.d" + +FSTAB_FILE = "/etc/fstab" +NFS_EXPORTS_FILE = "/etc/exports" +SAMBA_CONF_FILE = "/etc/samba/smb.conf" +TIMEZONE_FILE = "/etc/timezone" +ZONEINFO_DIR = "/usr/share/zoneinfo" +LOCALTIME_FILE = "/etc/localtime" +KERBEROS_CONF_FILE = "/etc/krb5.conf" +NSSWITCH_CONF_FILE = "/etc/nsswitch.conf" +NTP_CONF_FILE = "/etc/ntp.conf" +MODPROBE_CONF_FILE = "/etc/modprobe.d/bonding.conf" +SYSCONFIG_NETWORK_FILE = "/etc/sysconfig/network" +RESOLV_CONF_FILE = "/etc/resolv.conf" +DNSMASQ_LEASE_FILE = "/var/tmp/dnsmasq.leases" +LIVE_MODE_FILE = "/etc/live" +ADD_SERVER_COMPLETED_FILE = "/var/tmp/installation-completed" + +DNSMASQ_DNS_CONF_FILE = DNSMASQ_CONF_DIR + "/dns.conf" +DNSMASQ_DHCP_CONF_FILE = DNSMASQ_CONF_DIR + "/dhcp.conf" +## + +## Base constants +MAX_PARTITION_SIZE = 16777216 # 16 TB +OS_PARTITION_SIZE = 4000 # 4 GB +SESSION_TIMEOUT = 1800 # 30 minutes +SERVER_AGENT_PORT = 50000 + +BOOT_PARTITION_LABEL = "GLUSTEROS" +DATA_PARTITION_LABEL = "GLUSTERDATA" +VOLUME_USER_DESCRIPTION = "Gluster Volume User" +SERVER_AGENT_RUN_USERNAME = "gluster" +INSTALLER_SERVER_NAME = "$installer$" + +GLUSTER_BASE_DIR = "/GLUSTER" +GLUSTER_LUN_DIR = "/data" +REEXPORT_DIR = "/reexport" +NFS_EXPORT_DIR = "/nfs" +CIFS_EXPORT_DIR = "/cifs" +WEBDAV_DOCUMENT_ROOT_DIR = "/var/www/html" +UPDATES_DIR = "/UPDATES" +TRANSPORT_HOME_DIR = "/transport" +GLUSTERFS_LOG_DIR = "/var/log/glusterfs" +LOG_DIR = "/var/log/glustermc" + +GLUSTER_UPDATES_FILE = "updates.xml" +INSTALLER_STATUS_FILE = "/var/log/install-server-status.log" +INSTALL_PLATFORM_LOCK_FILE = "/var/lock/install-gluster-platform.lock" +LAST_ACCESSED_NETWORK_FILE = "last-accessed-network" +PREPARE_DATA_DISK_LOCK_FILE = "/var/tmp/prepare-data-disk.lock" +## + +## Derived constants +GLUSTER_CONF_DIR = GLUSTER_BASE_DIR + "/conf" +GLUSTER_TMP_DIR = GLUSTER_BASE_DIR + "/tmp" +VOLUME_CONF_DIR = GLUSTER_BASE_DIR + "/volumes" +SERVER_CONF_DIR = GLUSTER_BASE_DIR + "/servers" +DNS_RECORDS_DIR = GLUSTER_BASE_DIR + "/dns-records" +INSTALLER_CONF_DIR = SERVER_CONF_DIR + "/" + INSTALLER_SERVER_NAME + +GSN_USER_INFO_FILE = GLUSTER_BASE_DIR + "/gsn-user.info" +GLUSTER_VERSION_FILE = GLUSTER_BASE_DIR + "/version" +GLUSTER_UPDATE_SITE_FILE = GLUSTER_BASE_DIR + "/update-site" +GLUSTER_DIRECTORY_SERVICE_CONF_FILE = GLUSTER_BASE_DIR + "/directory.xml" +GLUSTER_TIME_CONF_FILE = GLUSTER_BASE_DIR + "/timeconfig.xml" +TRANSACTION_KEY_FILE = GLUSTER_BASE_DIR + "/transaction.key" +SERVER_COUNT_FILE = GLUSTER_BASE_DIR + "/server-count" +SIGNATURE_FILE = GLUSTER_BASE_DIR + "/.signature" +GLUSTER_SERVER_POOL_FILE = GLUSTER_BASE_DIR + "/pool" +GLUSTER_ADMIN_FILE = GLUSTER_BASE_DIR + "/.password" + +VOLUME_SMBCONF_FILE = VOLUME_CONF_DIR + "/volumes.smbconf.list" + +GLOBAL_NETWORK_FILE = INSTALLER_CONF_DIR + "/network.xml" +INSTALL_SERVER_CONF_FILE = INSTALLER_CONF_DIR + "/installer.xml" +INSTALLER_INFO_FILE = INSTALLER_CONF_DIR + "/installer.info" +INSTALLED_SERVER_COUNT_FILE = INSTALLER_CONF_DIR + "/installed-server-count" + +SESSION_FILE = GLUSTER_TMP_DIR + "/login.sessions" + +GENERAL_LOG_FILE = LOG_DIR + "/general.log" +INSTALLER_LOG_FILE = LOG_DIR + "/installer.log" +PEER_AGENT_LOG_FILE = LOG_DIR + "/peeragent.log" +SERVER_AGENT_LOG_FILE = LOG_DIR + "/serveragent.log" +TRANSPORT_AGENT_LOG_FILE = LOG_DIR + "/transport.log" +## + + +## Global variables +## TODO: These should be removed +DOWNLOAD_GLUSTER_UPDATE_PROCESS = None +DOWNLOAD_GLUSTER_UPDATE_LEVEL = None +DOWNLOAD_GLUSTER_CURRENT_UPDATE_LEVEL = None +DOWNLOAD_GLUSTER_UPDATE_MD5SUM = None +REQUEST_MAP = {} +VERSION_DICTONARY = {} +## diff --git a/src/com.gluster.storage.management.server.scripts/src/GlusterdUtils.py b/src/com.gluster.storage.management.server.scripts/src/GlusterdUtils.py new file mode 100644 index 00000000..7c0e899c --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/GlusterdUtils.py @@ -0,0 +1,250 @@ +# Copyright (c) 2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import os +import Utils + +import ServerUtils + + +def getGlusterVolumeInfo(volumeName=None): + volumeNameList = None + if Utils.isString(volumeName): + volumeNameList = [volumeName] + if type(volumeName) == type([]): + volumeNameList = volumeName + + status = Utils.runCommand("gluster volume info", output=True, root=True) + if status["Status"] != 0: + Utils.log("Failed to execute 'gluster volume info' command") + return None + + volumeInfoDict = {} + volumeInfo = {} + volumeName = None + brickList = [] + for line in status['Stdout'].split("\n"): + if not line: + if volumeName and volumeInfo: + volumeInfo["Bricks"] = brickList + volumeInfoDict[volumeName] = volumeInfo + volumeInfo = {} + volumeName = None + brickList = [] + continue + + tokens = line.split(":") + if tokens[0].strip().upper() == "BRICKS": + continue + elif tokens[0].strip().upper() == "VOLUME NAME": + volumeName = tokens[1].strip() + volumeInfo["VolumeName"] = volumeName + elif tokens[0].strip().upper() == "TYPE": + volumeInfo["VolumeType"] = tokens[1].strip() + elif tokens[0].strip().upper() == "STATUS": + volumeInfo["VolumeStatus"] = tokens[1].strip() + elif tokens[0].strip().upper() == "TRANSPORT-TYPE": + volumeInfo["TransportType"] = tokens[1].strip() + elif tokens[0].strip().upper().startswith("BRICK"): + brickList.append(":".join(tokens[1:]).strip()) + + if volumeName and volumeInfo: + volumeInfoDict[volumeName] = volumeInfo + + if not volumeNameList: + return volumeInfoDict + + # remove unwanted volume info + for volumeName in list(set(volumeInfoDict.keys()) - set(volumeNameList)): + del volumeInfoDict[volumeName] + + return volumeInfoDict + + +def isVolumeRunning(volumeName): + if not volumeName: + return False + volumeInfo = getGlusterVolumeInfo(volumeName) + if not volumeInfo: + return False + status = volumeInfo[volumeName]["VolumeStatus"] + if not status: + return False + if status.upper() == "STARTED": + return True + return False + + +def isVolumeExist(volumeName): + if not volumeName: + return False + if getGlusterVolumeInfo(volumeName): + return True + return False + + +def peerProbe(serverName): + command = "gluster peer probe %s" % serverName + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] == 0: + return True + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return False + + +def setAuthAllow(volumeName, authList, includeServers=True): + if not (volumeName and authList): + return False + vacl = [] + if includeServers: + for serverName in ServerUtils.getAllServerList(): + vacl += ServerUtils.getServerIpList(serverName) + vacl += authList + + command = "gluster volume set %s auth.allow %s" % (volumeName, ",".join(list(set(vacl)))) + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] == 0: + return True + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return False + + +def volumeCreate(volumeName, volumeType, transportTypeList, brickList): + command = "gluster volume create %s" % volumeName + + if volumeType.upper() == "MIRROR": + command += " replica 2" + elif volumeType.upper() == "STRIPE": + command += " stripe 4" + + if "RDMA" in transportTypeList: + command += " transport rdma" + + command += " " + " ".join(brickList) + + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] == 0: + return True + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return False + + +def volumeDelete(volumeName): + command = "gluster --mode=script volume delete %s" % volumeName + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] == 0: + return True + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return False + + +def volumeLogFileName(volumeName, brick, logDir): + command = "gluster volume log filename %s %s %s" % (volumeName, brick, logDir) + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] == 0: + return True + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return False + + +def startVolumeMigration(volumeName, sourcePath, destinationPath): + command = "gluster volume replace-brick %s %s %s start" % (volumeName, sourcePath, destinationPath) + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] == 0: + lines = status["Stdout"].split("\n") + if lines[0].split()[-1] == "successfully": + return True + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return False + + +def stopVolumeMigration(volumeName, sourcePath, destinationPath): + command = "gluster volume replace-brick %s %s %s abort" % (volumeName, sourcePath, destinationPath) + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] == 0: + lines = status["Stdout"].split("\n") + if lines[0].split()[-1] == "successful": + return True + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return False + + +def commitVolumeMigration(volumeName, sourcePath, destinationPath): + command = "gluster volume replace-brick %s %s %s commit" % (volumeName, sourcePath, destinationPath) + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] == 0: + lines = status["Stdout"].split("\n") + if lines[0].split()[-1] == "successful": + return True + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return False + + +def getMigrationStatus(volumeName, sourcePath, destinationPath): + command = "gluster volume replace-brick %s %s %s status" % (volumeName, sourcePath, destinationPath) + status = Utils.runCommand(command, output=True, root=True) + if status['Status'] == 0 and status['Stdout']: + lines = status["Stdout"].split("\n") + if "Current file" in lines[0]: + return "started" + if "Migration complete" in lines[0]: + return "completed" + Utils.log("command [%s] returns unknown status:%s" % (command, lines[0])) + return "failed" + #if status['Status'] == 0 and status['Stdout']: + # for line in status['Stdout'].split('\n'): + # words = line.split() + # if words and words[0].upper() == "STATUS:": + # return " ".join(words[1:]).upper() + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return None + + +def volumeRebalanceStart(volumeName): + command = "gluster volume rebalance %s start" % volumeName + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] == 0: + lines = status["Stdout"].split("\n") + if lines[0].split()[-1] == "successful": + return True + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return False + + +def volumeRebalanceStop(volumeName): + command = "gluster volume rebalance %s stop" % volumeName + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] == 0: + lines = status["Stdout"].split("\n") + if lines[0].split()[0] == "stopped": + return True + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return False + + +def volumeRebalanceStatus(volumeName): + command = "gluster volume rebalance %s status" % volumeName + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] == 0: + lines = status["Stdout"].split("\n") + if "rebalance not started" in lines[0]: + return "not started" + if "rebalance completed" in lines[0]: + return "completed" + return "running" + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return False diff --git a/src/com.gluster.storage.management.server.scripts/src/NetworkUtils.py b/src/com.gluster.storage.management.server.scripts/src/NetworkUtils.py new file mode 100755 index 00000000..7a854564 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/NetworkUtils.py @@ -0,0 +1,450 @@ +# Copyright (c) 2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import sys + +if not "/usr/share/system-config-network/" in sys.path: + sys.path.append("/usr/share/system-config-network") + +import os +import tempfile +import Globals + +from Utils import * +#from netconfpkg.NCHardwareList import getHardwareList + +def readHostFile(fileName=None): + hostEntryList = [] + if not fileName: + fileName = "/etc/hosts" + try: + for line in open(fileName): + tokens = line.split("#")[0].strip().split() + if len(tokens) < 2: + continue + hostEntryList.append({tokens[0] : tokens[1:]}) + return hostEntryList + except IOError: + log("failed to read %s file" % fileName) + return None + + +def writeHostFile(hostEntryList, fileName=None): + if fileName: + hostFile = fileName + else: + hostFile = tempfile.mktemp(prefix="GSPSA") + try: + fp = open(hostFile, "w") + for host in hostEntryList: + fp.write("%s\t%s\n" % (host.keys()[0], " ".join(host.values()[0]))) + fp.close() + if hostFile == fileName: + return True + except IOError: + log("failed to write %s file" % hostFile) + return False + if runCommandFG("mv -f %s /etc/hosts" % hostFile, root=True) != 0: + log("failed to rename file %s to /etc/hosts" % hostFile) + return False + return True + + +def readResolvConfFile(fileName=None, includeLocalHost=False): + nameServerList = [] + domain = None + searchDomain = None + if not fileName: + fileName = Globals.RESOLV_CONF_FILE + try: + for line in open(fileName): + tokens = line.split("#")[0].strip().split() + if len(tokens) < 2: + continue + if tokens[0].upper() == "NAMESERVER": + if includeLocalHost == False and tokens[1] == "127.0.0.1": + continue + nameServerList.append(tokens[1]) + continue + if tokens[0].upper() == "DOMAIN": + domain = tokens[1:] + continue + if tokens[0].upper() == "SEARCH": + searchDomain = tokens[1:] + continue + return nameServerList, domain, searchDomain + except IOError: + log("failed to read %s file" % fileName) + return None, None, None + + +def writeResolvConfFile(nameServerList, domain, searchDomain, fileName=None, appendLocalHost=True): + if fileName: + resolvConfFile = fileName + else: + resolvConfFile = tempfile.mktemp(prefix="GSPSA") + try: + fp = open(resolvConfFile, "w") + if appendLocalHost: + fp.write("nameserver 127.0.0.1\n") + for nameServer in nameServerList: + fp.write("nameserver %s\n" % nameServer) + if domain: + fp.write("domain %s\n" % " ".join(domain)) + if searchDomain: + fp.write("search %s\n" % " ".join(searchDomain)) + fp.close() + if resolvConfFile == fileName: + return True + except IOError: + log("failed to write %s file" % resolvConfFile) + return False + if runCommandFG("mv -f %s %s" % (resolvConfFile, Globals.RESOLV_CONF_FILE), root=True) != 0: + log("failed to rename file %s to %s" % (resolvConfFile, Globals.RESOLV_CONF_FILE)) + return False + return True + + +def readIfcfgConfFile(deviceName, root=""): + conf = {} + fileName = "%s%s/ifcfg-%s" % (root, Globals.SYSCONFIG_NETWORK_DIR, deviceName) + try: + for line in open(fileName): + tokens = line.split("#")[0].split("=") + if len(tokens) != 2: + continue + conf[tokens[0].strip().lower()] = tokens[1].strip() + return conf + except IOError: + log("failed to read %s file" % fileName) + return None + + +def writeIfcfgConfFile(deviceName, conf, root="", deviceFile=None): + if not deviceFile: + deviceFile = "%s%s/ifcfg-%s" % (root, Globals.SYSCONFIG_NETWORK_DIR, deviceName) + if root: + ifcfgConfFile = deviceFile + else: + ifcfgConfFile = tempfile.mktemp(prefix="GSPSA") + try: + fp = open(ifcfgConfFile, "w") + for key in conf.keys(): + if key == "description": + fp.write("#%s=%s\n" % (key.upper(), conf[key])) + continue + if key in ['link', 'mode']: + continue + if conf["device"].startswith("bond") and key in ['hwaddr', 'master', 'slave']: + continue + if key == "slave" and conf['master']: + fp.write("SLAVE=yes\n") + continue + if key == "onboot": + if conf[key] == True: + fp.write("ONBOOT=yes\n") + elif isString(conf[key]) and conf[key].upper() == "YES": + fp.write("ONBOOT=yes\n") + else: + fp.write("ONBOOT=no\n") + continue + if not conf[key]: + continue + fp.write("%s=%s\n" % (key.upper(), conf[key])) + fp.close() + if ifcfgConfFile == deviceFile: + return True + except IOError: + log("failed to write %s file" % ifcfgConfFile) + return False + if runCommandFG("mv -f %s %s" % (ifcfgConfFile, deviceFile), root=True) != 0: + log("failed to rename file %s to %s" % (ifcfgConfFile, deviceFile)) + return False + return True + + +def getNetModel(deviceName): + rv = runCommandFG("ifconfig %s" % deviceName, stdout=True, root=True) + if rv["Status"] != 0: + return False + for line in rv["Stdout"].split(): + tokens = line.strip().split(":") + if tokens[0].upper() == "ENCAP": + return tokens[1].strip().upper() + return None + +def getNetSpeed(deviceName): + rv = runCommandFG("ethtool %s" % deviceName, stdout=True, root=True) + if rv["Status"] != 0: + return False + for line in rv["Stdout"].split("\n"): + tokens = line.strip().split(":") + if tokens[0].upper() == "SPEED": + return tokens[1].strip().upper() + return None + +def getLinkStatus(deviceName): + return True + ## ethtool takes very long time to respond. So its disabled now + rv = runCommandFG("ethtool %s" % deviceName, stdout=True, root=True) + if rv["Status"] != 0: + return False + for line in rv["Stdout"].split("\n"): + tokens = line.strip().split(":") + if tokens[0].upper() == "LINK DETECTED": + if tokens[1].strip().upper() == "YES": + return True + else: + return False + return False + + +def getBondMode(deviceName, fileName=None): + if not fileName: + fileName = Globals.MODPROBE_CONF_FILE + try: + for line in open(fileName): + tokens = line.split("#")[0].split() + if len(tokens) < 4: + continue + if tokens[0].upper() == "OPTIONS" and tokens[1] == deviceName: + if tokens[2].startswith("mode="): + return tokens[2].split("=")[1] + if tokens[3].startswith("mode="): + return tokens[3].split("=")[1] + if tokens[4].startswith("mode="): + return tokens[4].split("=")[1] + if tokens[5].startswith("mode="): + return tokens[5].split("=")[1] + return None + except IOError: + log("failed to read %s file" % fileName) + return None + + +def setBondMode(deviceName, mode, fileName=None): + if not fileName: + fileName = Globals.MODPROBE_CONF_FILE + tempFileName = getTempFileName() + try: + fp = open(tempFileName, "w") + lines = open(fileName).readlines() + except IOError: + log("unable to open file %s" % Globals.MODPROBE_CONF_FILE) + return False + for line in lines: + tokens = line.split() + if len(tokens) > 1 and "OPTIONS" == tokens[0].upper() and "BOND" in tokens[1].upper() and deviceName == tokens[1]: + fp.write("options %s max_bonds=2 mode=%s miimon=100\n" % (deviceName, mode)) + deviceName = None + continue + fp.write(line) + if deviceName: + fp.write("alias %s bonding\n" % deviceName) + fp.write("options %s max_bonds=2 mode=%s miimon=100\n" % (deviceName, mode)) + fp.close() + if runCommandFG(["mv", "-f", tempFileName, fileName], root=True) != 0: + log("unable to move file from %s to %s" % (tempFileName, fileName)) + return False + return True + +def getNetDeviceList(root=""): + netDeviceList = [] + + for deviceName in os.listdir("/sys/class/net/"): + #for device in getHardwareList(): + netDevice = {} + netDevice["device"] = None + netDevice["description"] = None + netDevice["hwaddr"] = None + netDevice["type"] = None + netDevice["onboot"] = None + netDevice["bootproto"] = None + netDevice["ipaddr"] = None + netDevice["netmask"] = None + netDevice["gateway"] = None + netDevice["peerdns"] = None + netDevice["autodns"] = None + netDevice["dns1"] = None + netDevice["dns2"] = None + netDevice["dns3"] = None + netDevice["master"] = None + netDevice["slave"] = None + netDevice["nmcontrolled"] = None + netDevice["link"] = None + netDevice["mode"] = None + + #netDevice["device"] = device.Name + netDevice["device"] = deviceName + #netDevice["description"] = device.Description + netDevice["description"] = deviceName + #netDevice["type"] = device.Type + netDevice["type"] = None + netDevice["link"] = getLinkStatus(deviceName) + 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) + if not conf: + continue + try: + netDevice["onboot"] = conf["onboot"] + except KeyError: + pass + try: + netDevice["bootproto"] = conf["bootproto"] + except KeyError: + pass + try: + netDevice["ipaddr"] = conf["ipaddr"] + except KeyError: + pass + try: + netDevice["netmask"] = conf["netmask"] + except KeyError: + pass + try: + netDevice["gateway"] = conf["gateway"] + except KeyError: + pass + try: + netDevice["peerdns"] = conf["peerdns"] + except KeyError: + pass + try: + netDevice["autodns"] = conf["autodns"] + except KeyError: + pass + try: + netDevice["dns1"] = conf["dns1"] + except KeyError: + pass + try: + netDevice["dns2"] = conf["dns2"] + except KeyError: + pass + try: + netDevice["dns3"] = conf["dns3"] + except KeyError: + pass + try: + netDevice["master"] = conf["master"] + except KeyError: + pass + try: + netDevice["slave"] = conf["slave"] + except KeyError: + pass + try: + netDevice["nmcontrolled"] = conf["nmcontrolled"] + except KeyError: + pass + + return netDeviceList + + ## bondDevices = [os.path.basename(device) for device in glob.glob("/sys/class/net/bond*")] + + ## bondDevices = [os.path.basename(device) for device in glob.glob("/sys/class/net/bond*")] + ## for deviceName in bondDevices: + ## if deviceName in linkedBondList: + ## if deviceName in sysConfigDeviceList: + ## deviceList[deviceName] = sysConfigDeviceList[deviceName] + ## else: + ## deviceList[deviceName] = {'device':deviceName, 'onboot':'no', 'bootproto':'none'} + ## continue + ## if len(ethDevices) > 2: + ## deviceList[deviceName] = {'device':deviceName, 'onboot':'no', 'bootproto':'none'} + + +def configureDhcpServer(serverIpAddress, dhcpIpAddress): + tmpDhcpConfFile = tempfile.mktemp(prefix="GSPSA") + + 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(tmpDhcpConfFile, "w") + 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-alternate-port=%s\n" % serverPort) + fp.write("dhcp-leasefile=%s\n" % Globals.DNSMASQ_LEASE_FILE) + #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 dhcp configuration %s" % tmpDhcpConfFile) + return False + if runCommandFG("mv -f %s %s" % (tmpDhcpConfFile, Globals.DNSMASQ_DHCP_CONF_FILE), root=True) != 0: + log(syslog.LOG_ERR, "unable to copy dnsmasq dhcp configuration to %s" % Globals.DNSMASQ_DHCP_CONF_FILE) + return False + return True + + +def isDhcpServer(): + return os.path.exists(Globals.DNSMASQ_DHCP_CONF_FILE) + + +def getDhcpServerStatus(): + if runCommandFG("service dnsmasq status", root=True) == 0: + return True + return False + + +def startDhcpServer(): + if runCommandFG("service dnsmasq start", root=True) == 0: + return True + return False + + +def stopDhcpServer(): + if runCommandFG("service dnsmasq stop", root=True) == 0: + runCommandFG("rm -f %s" % Globals.DNSMASQ_LEASE_FILE, root=True) + return True + return False + + +def restartDhcpServer(): + stopDhcpServer() + runCommandFG("rm -f %s" % Globals.DNSMASQ_LEASE_FILE, root=True) + return startDhcpServer() + + +def reloadDhcpServer(): + if runCommandFG("service dnsmasq reload", root=True) == 0: + return True + return False diff --git a/src/com.gluster.storage.management.server.scripts/src/Protocol.py b/src/com.gluster.storage.management.server.scripts/src/Protocol.py new file mode 100644 index 00000000..ff073593 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/Protocol.py @@ -0,0 +1,438 @@ +# Copyright (C) 2009 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import xml +import xml.parsers.expat +import xml.dom.minidom as MDOM +import os +import Globals +import copy +import Utils + +XML_STRING = 0 +XML_FILE = 1 + +class XDOM: + _domObj = None + + def __init__(self): + self._domObj = MDOM.Document() + return + + @classmethod + def getText(self, nodeList): + rc = "" + for node in nodeList: + if node.nodeType == node.TEXT_NODE: + rc = rc + node.data + return rc.strip() + + def parseString(self, requestString): + try: + self._domObj = MDOM.parseString(requestString) + except xml.parsers.expat.ExpatError, e: + Utils.log("XML string parse error: %s" % str(e)) + return False + return True + + def parseFile(self, fileName): + try: + self._domObj = MDOM.parse(fileName) + except IOError, e: + Utils.log("error reading file: %s" % str(e)) + return False + except xml.parsers.expat.ExpatError, e: + Utils.log("XML file %s parse error: %s" % (fileName, str(e))) + return False + return True + + def setDomObj(self, dom): + if dom and type(dom) != type([]): + self._domObj = dom + return True + return False + + def createTextNode(self, text): + if not self._domObj: + return False + if not text: + return False + return self._domObj.createTextNode(str(text)) + + def createTag(self, tag, text=None): + if not self._domObj: + return None + if tag == None: + return None + + tagE = self._domObj.createElement(str(tag)) + if text: + tagEText = self._domObj.createTextNode(str(text)) + tagE.appendChild(tagEText) + return tagE + + def addTag(self, tag): + if not self._domObj: + return False + if not tag: + return False + + self._domObj.appendChild(tag) + return True + + def createTagRoute(self, tagRoute, text=None): + if not tagRoute: + return False + + tagList = tagRoute.split(".") + tag = None + previousTag = None + for tagName in tagList[:-1]: + newTag = self.createTag(tagName, None) + if not tag: + tag = newTag + previousTag = newTag + continue + previousTag.appendChild(newTag) + previousTag = newTag + + if previousTag: + previousTag.appendChild(self.createTag(tagList[-1], text)) + else: + tag = self.createTag(tagList[-1], text) + return tag + + def appendTagRoute(self, tagRoute, value=None): + if not self._domObj: + return False + if not tagRoute: + return False + + parentTagE = self._domObj + + tagNameList = tagRoute.split(".") + newTagRoute = tagNameList.pop(-1) + + for i in range(len(tagNameList), 0, -1): + tagE = self.getElementsByTagRoute(".".join(tagNameList[:i])) + if tagE: + parentTagE = tagE[0] + break + newTagRoute = tagNameList[i-1] + "." + newTagRoute + + newTagE = self.createTagRoute(newTagRoute, value) + if not newTagE: + return False + try: + parentTagE.appendChild(newTagE) + except xml.dom.HierarchyRequestErr, e: + Utils.log("error occured. %s" + str(e)) + return False + return True + + def setTextByTagRoute(self, tagRoute, tagValue): + if not self._domObj: + return None + + if not tagRoute: + return None + + tagE = self.getElementsByTagRoute(tagRoute) + if not tagE: + return False + + parentTagE = self.getElementsByTagRoute(".".join(tagRoute.split(".")[:-1])) + if not parentTagE: + return False + + parentTagE[0].childNodes.remove(tagE[0]) + parentTagE[0].appendChild(self.createTag(tagRoute.split(".")[-1], tagValue)) + return True + + def getElementsByTagRoute(self, tagRoute): + if not self._domObj: + return None + + if not tagRoute: + return None + + x = None + for tag in tagRoute.split("."): + if x is None: + x = self._domObj.getElementsByTagName(tag) + continue + if x == []: + break + x = x[0].getElementsByTagName(tag) + return x + + def getTextByTagRoute(self, tagRoute): + if not self._domObj: + return None + + x = self.getElementsByTagRoute(tagRoute) + if x: + return self.getText(x[0].childNodes) + return None + + def getElementsByTagName(self, name): + if not self._domObj: + return None + return self._domObj.getElementsByTagName(name) + + def writexml(self, fileName, indent="", addindent="", newl=""): + if not self._domObj: + return None + try: + fp = open(fileName, "w") + self._domObj.writexml(fp, indent, addindent, newl) + fp.close() + return True + except IOError: + return False + + def toString(self, indent=" ", newl="\n", encoding = None): + if not self._domObj: + return None + return self._domObj.toprettyxml(indent, newl, encoding) + + def toxml(self, encoding = None): + if not self._domObj: + return None + return self._domObj.toxml(encoding) + + def toprettyxml(self, indent=" ", newl="\n", encoding = None): + return self.toString(indent, newl, encoding) + + def getAttribute(self, attributeName): + if not attributeName: + return None + try: + return self.getElementsByTagName("command")[0].getAttribute(attributeName) + except IndexError: + return False + + def setAttribute(self, attributeName, attributeValue): + if not (attributeName and attributeValue): + return None + try: + return self.getElementsByTagName("command")[0].setAttribute(attributeName, attributeValue) + except IndexError: + return False + + def getRequestCommand(self): + return self.getAttribute("request") + + def getResponseCommand(self): + return self.getAttribute("response") + + def getResponseCode(self): + return self.getAttribute("response-code") + + def getMessageId(self): + return self.getAttribute("id") + + def getVersion(self): + return self.getAttribute("version") + + def getRequestAction(self): + return self.getAttribute("action") + + def setVersion(self, value): + return self.setAttribute("version", value) + + def setRequestAction(self, value): + return self.setAttribute("action", value) + + def createCommandTag(self, command, responseCode, id, version=Globals.GLUSTER_PLATFORM_VERSION): + commandTag = self._domObj.createElement("command") + commandTag.setAttribute("response", command) + commandTag.setAttribute("response-code", responseCode) + commandTag.setAttribute("id", id) + commandTag.setAttribute("version", version) + return commandTag +##--end of XDOM + +class RequestXml(XDOM): + def __init__(self, requestString, type=None): + if None == requestString: + XDOM.__init__(self) + return + try: + if None == type: + if os.path.isfile(requestString): + self._domObj = MDOM.parse(requestString) + else: + self._domObj = MDOM.parseString(requestString) + elif XML_FILE == type: + self._domObj = MDOM.parse(requestString) + elif XML_STRING == type: + self._domObj = MDOM.parseString(requestString) + except IOError: + XDOM.__init__(self) + except xml.parsers.expat.ExpatError: + XDOM.__init__(self) + +##--end of RequestXML + +class ResponseXml(XDOM): + _commandTag = None + def __init__(self, command, responseCode, id, version=Globals.GLUSTER_PLATFORM_VERSION): + XDOM.__init__(self) + if command and responseCode and id: + self._commandTag = self.createCommandTag(command, responseCode, id, version) + self._domObj.appendChild(self._commandTag) + + def appendCommand(self, command, responseCode, id, version=Globals.GLUSTER_PLATFORM_VERSION): + if command and responseCode and id: + self._commandTag = self.createCommandTag(command, responseCode, id, version) + self._domObj.appendChild(self._commandTag) + return True + return False + + def append(self, tagName, tagValue=None): + if not self._commandTag: + return False + tag = self.createTag(tagName, tagValue) + if tag: + self._commandTag.appendChild(tag) + return True + return False + + def appendTag(self, tag): + if not tag: + return False + if not self._commandTag: + return False + self._commandTag.appendChild(tag) + return True + + def appendTagRoute(self, tagRoute, value=None): + if not self._commandTag: + return False + if not tagRoute: + return False + + parentTagE = self._commandTag + + tagNameList = tagRoute.split(".") + newTagRoute = tagNameList.pop(-1) + + for i in range(len(tagNameList), 0, -1): + tagE = self.getElementsByTagRoute(".".join(["command"] + tagNameList[:i])) + if tagE: + parentTagE = tagE[0] + break + newTagRoute = tagNameList[i-1] + "." + newTagRoute + + newTagE = self.createTagRoute(newTagRoute, value) + if not newTagE: + return False + try: + parentTagE.appendChild(newTagE) + except xml.dom.HierarchyRequestErr, e: + Utils.log("error occured. %s" + str(e)) + return False + return True + + def appendTagRouteOld(self, tagRoute, value=None): + if not tagRoute: + return False + if not self._commandTag: + return False + + tmpTagRoute = "" + previousTagE = self._commandTag + tagE = None + for tagName in tagRoute.split("."): + if not tmpTagRoute: + tagE = self.getElementsByTagRoute("command." + tagName) + else: + tagE = self.getElementsByTagRoute("command." + tmpTagRoute + "." + tagName) + if not tagE: + break + if len(tagE) != 1: + return False + previousTagE = tagE[0] + if not tmpTagRoute: + tmpTagRoute = tagName + else: + tmpTagRoute = tmpTagRoute + "." + tagName + + if tmpTagRoute == tagRoute: + return False + newTagRoute = tagRoute[len(tmpTagRoute):] + if newTagRoute[0] == '.': + newTagRoute = newTagRoute[1:] + + if previousTagE.childNodes and previousTagE.childNodes[0].nodeType == previousTagE.TEXT_NODE: + return False + previousTagE.appendChild(self.createTagRoute(newTagRoute, value)) + return True +##--end of ResponseXml + +def test(): + #volumes = RequestXml(VolumeFile, XML_FILE).getElementsByTagRoute("volume-list.volume") + requestStr = ''' + +movies1 +cluster mirror +512000 +zresearch +192.168.20.* +192.168.30.* + +no + + +no + + +no + + +''' + + requestXml = RequestXml(requestStr) + print requestXml.getAttribute("") + +def test1(): + rs = ResponseXml("create-volume", "OK", "xyz") + rs.appendTagRoute("volume.detail.name", "music") + print rs.toprettyxml() + rs.append("volume", "data") + print rs.toprettyxml() + rs.appendTagRoute("volume.detail.ipaddr", "192.168.10.1") + print rs.toprettyxml() + print rs.appendTagRoute("volume.detail.ipaddr.v6", "ff:ff::ff::") + print rs.toprettyxml() + + print rs.getTextByTagRoute("command.volume.detail") + +def test2(): + rs = ResponseXml("download-volume-logs", "OK", "xyz") + te = rs.createTag("interface", None) + te.appendChild(rs.createTag("device", "DEVICE1")) + te.appendChild(rs.createTag("description", "my device one")) + rs.appendTag(te) + + te = rs.createTag("interface", None) + te.appendChild(rs.createTag("device", "DEVICE2")) + te.appendChild(rs.createTag("description", "my device two")) + rs.appendTag(te) + print rs.toprettyxml() + diff --git a/src/com.gluster.storage.management.server.scripts/src/ServerUtils.py b/src/com.gluster.storage.management.server.scripts/src/ServerUtils.py new file mode 100644 index 00000000..1fec994c --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/ServerUtils.py @@ -0,0 +1,308 @@ +# Copyright (c) 2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import os +import re +import subprocess +import glob +import Globals +from Protocol import * +from Utils import * + +def isValidServer(serverName): + for profile in getProfileList(): + if profile.ProfileName == "default" and profile.Active: + if serverName == profile.DNS.Hostname: + return True + return False + +def getHostname(): + for profile in getProfileList(): + if profile.ProfileName == "default" and profile.Active: + return profile.DNS.Hostname + return None + +def getDomainName(): + try: + domainName = open(Globals.DOMAINNAME_FILE).read() + except IOError: + return None + return domainName.split()[0] + +def replaceServerIp(fileName, findWhat, replaceWith): + try: + data = open(fileName).read() + fp = open(fileName, "w") + fp.write(re.sub(findWhat, replaceWith, data)) + fp.close() + return True + except IOError: + return False + except ValueError: + return False + except OSError: + return False + +def serverName2IpAddress(serverName): + command = "dig %s | grep '^%s'" % (serverName, serverName) + ps = subprocess.Popen(command, + shell=True, + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + close_fds=True) + ipAddress = serverName + if ps.wait() == 0: + output = ps.communicate() + ipAddress = output[0].split()[-1] + return ipAddress + +def getInstallerIp(): + if not os.path.exists(Globals.INSTALLER_INFO_FILE): + return None + try: + for line in open(Globals.INSTALLER_INFO_FILE): + tokens = line.split("=") + if tokens[0] == "IP-ADDRESS": + return tokens[1].split(",")[0].strip() + except IOError: + syslog.syslog(syslog.LOG_ERR, "unable to read %s file" % Globals.INSTALLER_INFO_FILE) + return False + +def setInstallerIp(installerIp): + try: + open(Globals.INSTALLER_INFO_FILE, "w").write("IP-ADDRESS=%s\n" % installerIp) + return True + except IOError: + log(syslog.LOG_ERR, "unable to create %s file" % Globals.INSTALLER_INFO_FILE) + return False + +def getCurrentServerName(): + try: + for line in open(Globals.SYSCONFIG_NETWORK_FILE): + tokens = line.split("=") + if tokens[0] == "HOSTNAME": + return tokens[1].strip() + except IOError: + syslog.syslog(syslog.LOG_ERR, "unable to read %s file" % Globals.SYSCONFIG_NETWORK_FILE) + return False + +def getLastAccessedNetwork(serverName): + lastAccessedNetworkFile = ("/%s/servers/%s/%s" % + (Globals.GLUSTER_CONF_DIR, serverName, Globals.LAST_ACCESSED_NETWORK_FILE)) + try: + return open(lastAccessedNetworkFile).read().strip() + except IOError: + log(syslog.LOG_ERR, "failed to read last accessed network file %s" % lastAccessedNetworkFile) + pass + return False + +def setLastAccessedNetwork(serverName, ipAddress): + lastAccessedNetworkFile = ("/%s/servers/%s/%s" % + (Globals.GLUSTER_CONF_DIR, serverName, Globals.LAST_ACCESSED_NETWORK_FILE)) + try: + open(lastAccessedNetworkFile, "w").write(ipAddress.strip() + "\n") + except IOError: + log(syslog.LOG_ERR, "failed to write last accessed network file %s" % lastAccessedNetworkFile) + return False + return True + +def getServerIpList(serverName, preferredNetworkOnly=False): + networkXmlFile = ("%s/servers/%s/network.xml" % (Globals.GLUSTER_CONF_DIR, serverName)) + configDom = XDOM() + if not configDom.parseFile(networkXmlFile): + log(syslog.LOG_ERR, "failed to read %s file" % networkXmlFile) + return None + preferredNetwork = configDom.getTextByTagRoute("preferred-network") + ipList = [] + interfaceDom = XDOM() + for tagE in configDom.getElementsByTagName("interface"): + interfaceDom.setDomObj(tagE) + deviceName = interfaceDom.getTextByTagRoute("device") + hostIp = interfaceDom.getTextByTagRoute("ipaddr") + if not hostIp: + continue + if preferredNetworkOnly: + if preferredNetwork.upper() == "ANY" or preferredNetwork.upper() == deviceName.upper(): + ipList.append(hostIp) + else: + ipList.append(hostIp) + if preferredNetworkOnly: + lastAccessedNetworkIp = getLastAccessedNetwork(serverName) + if lastAccessedNetworkIp in ipList: + ipList.remove(lastAccessedNetworkIp) + ipList = [lastAccessedNetworkIp] + ipList + return ipList + +def getServerPreferredIpList(serverName): + return getServerIpList(serverName, True) + +def getExecuteServerList(serverList): + executeServerList = {} + for serverName in serverList: + if serverName == Globals.INSTALLER_SERVER_NAME: + installerIp = getInstallerIp() + if installerIp: + executeServerList[serverName] = [installerIp] + continue + executeServerList[serverName] = getServerPreferredIpList(serverName) + return executeServerList + +def getAllServerList(): + serverList = [] + for filePath in glob.glob("%s/servers/*" % Globals.GLUSTER_CONF_DIR): + if os.path.isdir(filePath): + serverList.append(os.path.basename(filePath)) + try: + serverList.remove(Globals.INSTALLER_SERVER_NAME) + except ValueError: + pass + return serverList + +def getServerNetworkConfigFromLocalFile(serverName): + configDom = XDOM() + configDom.parseFile("%s/servers/%s/network.xml" % (Globals.GLUSTER_CONF_DIR, serverName)) + return configDom + +def updateServerNetworkConfigXmlFile(serverName, serverNetworkDom): + configDom = XDOM() + serverTag = serverNetworkDom.getElementsByTagRoute("server")[0] + configDom.setDomObj(serverTag) + if not configDom.writexml("%s/%s/network.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)): + log("Faild to write xml file %s/%s/network.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)) + +def compareServerNetworkDom(serverNetworkDomA, serverNetworkDomB, requestFlag=True): + command = "command.server." + if not requestFlag: + command = "" + sourceServer = {} + tagText = serverNetworkDomA.getTextByTagRoute("name") + if not tagText: + taxText = None + sourceServer["name"] = tagText + tagText = serverNetworkDomA.getTextByTagRoute("domain-name") + if not tagText: + tagText = None + sourceServer["domain-name"] = tagText + tagText = serverNetworkDomA.getTextByTagRoute("search-domain") + if not tagText: + tagText = None + sourceServer["search-domain"] = tagText + tagText = serverNetworkDomA.getTextByTagRoute("dns1") + if not tagText: + tagText = None + sourceServer["dns1"] = tagText + tagText = serverNetworkDomA.getTextByTagRoute("dns2") + if not tagText: + tagText = None + sourceServer["dns2"] = tagText + tagText = serverNetworkDomA.getTextByTagRoute("dns3") + if not tagText: + tagText = None + sourceServer["dns3"] = tagText + for tagE in serverNetworkDomA.getElementsByTagRoute("interface"): + interfaceDom = XDOM() + interfaceDom.setDomObj(tagE) + sourceServerList = {} + tagText = interfaceDom.getTextByTagRoute("description") + if not tagText: + tagText = None + sourceServerList["description"] = tagText + tagText = interfaceDom.getTextByTagRoute("hwaddr") + if not tagText: + tagText = None + sourceServerList["hwaddr"] = tagText + tagText = interfaceDom.getTextByTagRoute("onboot") + if not tagText: + tagText = None + sourceServerList["onboot"] = tagText + tagText = interfaceDom.getTextByTagRoute("bootproto") + if not tagText: + tagText = None + sourceServerList["bootproto"] = tagText + tagText = interfaceDom.getTextByTagRoute("ipaddr") + if not tagText: + tagText = None + sourceServerList["ipaddr"] = tagText + tagText = interfaceDom.getTextByTagRoute("netmask") + if not tagText: + tagText = None + sourceServerList["netmask"] = tagText + tagText = interfaceDom.getTextByTagRoute("gateway") + if not tagText: + tagText = None + sourceServerList["gateway"] = tagText + sourceServer[interfaceDom.getTextByTagRoute("device")] = sourceServerList + objServer = {} + tagText = serverNetworkDomB.getTextByTagRoute(command + "name") + if not tagText: + taxText = None + objServer["name"] = tagText + tagText = serverNetworkDomB.getTextByTagRoute(command + "domain-name") + if not tagText: + tagText = None + objServer["domain-name"] = tagText + tagText = serverNetworkDomB.getTextByTagRoute(command + "search-domain") + if not tagText: + tagText = None + objServer["search-domain"] = tagText + tagText = serverNetworkDomB.getTextByTagRoute(command + "dns1") + if not tagText: + tagText = None + objServer["dns1"] = tagText + tagText = serverNetworkDomB.getTextByTagRoute(command + "dns2") + if not tagText: + tagText = None + objServer["dns2"] = tagText + tagText = serverNetworkDomB.getTextByTagRoute(command + "dns3") + if not tagText: + tagText = None + objServer["dns3"] = tagText + for tagE in serverNetworkDomB.getElementsByTagRoute(command + "interface"): + interfaceDom = XDOM() + interfaceDom.setDomObj(tagE) + objServerList = {} + tagText = interfaceDom.getTextByTagRoute("description") + if not tagText: + tagText = None + objServerList["description"] = tagText + tagText = interfaceDom.getTextByTagRoute("hwaddr") + if not tagText: + tagText = None + objServerList["hwaddr"] = tagText + tagText = interfaceDom.getTextByTagRoute("onboot") + if not tagText: + tagText = None + objServerList["onboot"] = tagText + tagText = interfaceDom.getTextByTagRoute("bootproto") + if not tagText: + tagText = None + objServerList["bootproto"] = tagText + tagText = interfaceDom.getTextByTagRoute("ipaddr") + if not tagText: + tagText = None + objServerList["ipaddr"] = tagText + tagText = interfaceDom.getTextByTagRoute("netmask") + if not tagText: + tagText = None + objServerList["netmask"] = tagText + tagText = interfaceDom.getTextByTagRoute("gateway") + if not tagText: + tagText = None + objServerList["gateway"] = tagText + objServer[interfaceDom.getTextByTagRoute("device")] = objServerList + return sourceServer == objServer diff --git a/src/com.gluster.storage.management.server.scripts/src/Utils.py b/src/com.gluster.storage.management.server.scripts/src/Utils.py new file mode 100644 index 00000000..5140b641 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/Utils.py @@ -0,0 +1,703 @@ +# Copyright (c) 2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import sys +import os +import re +import socket +import struct +import syslog +import subprocess +#import spwd +import time +#import uuid +import tempfile +import grp +import pwd +import inspect +from datetime import datetime +import urllib + +import Globals +import Protocol +from Common import * + +RUN_COMMAND_ERROR = -1024 +LOG_SYSLOG = 1 +SYSLOG_REQUIRED = False +LOG_FILE_NAME = None +LOG_FILE_OBJ = None + + +def _getLogCode(priority): + if syslog.LOG_EMERG == priority: + return "M" + elif syslog.LOG_ALERT == priority: + return "A" + elif syslog.LOG_CRIT == priority: + return "C" + elif syslog.LOG_ERR == priority: + return "E" + elif syslog.LOG_WARNING == priority: + return "W" + elif syslog.LOG_NOTICE == priority: + return "N" + elif syslog.LOG_INFO == priority: + return "I" + elif syslog.LOG_DEBUG == priority: + return "D" + else: # UNKNOWN + return "X" + + +def setLogFile(fileName): + global LOG_FILE_NAME + + if fileName: + LOG_FILE_NAME = fileName + return True + return False + + +def closeLog(): + global LOG_FILE_OBJ + global SYSLOG_REQUIRED + + if SYSLOG_REQUIRED: + syslog.closelog() + SYSLOG_REQUIRED = False + return True + + if LOG_FILE_OBJ: + try: + LOG_FILE_OBJ.close() + LOG_FILE_OBJ = None + except IOError, e: + sys.stderr.write("Failed to close file: %s\n" % e) + return False + return True + + +def openLog(fileName=None): + global LOG_FILE_NAME + global LOG_FILE_OBJ + global SYSLOG_REQUIRED + + if fileName == LOG_SYSLOG: + syslog.openlog(os.path.basename(sys.argv[0])) + SYSLOG_REQUIRED = True + return True + + if fileName: + LOG_FILE_NAME = fileName + + if not LOG_FILE_NAME: + return False + + closeLog() + + try: + LOG_FILE_OBJ = open(LOG_FILE_NAME, "a") + except IOError, e: + sys.stderr.write("Failed to open file %s: %s\n" % (LOG_FILE_NAME, e)) + return False + return True + +def record(priority, message=None): + global LOG_FILE_OBJ + global SYSLOG_REQUIRED + + stack = inspect.stack()[1] + if stack[3] == "": + prefix = "%s:%s:%s" % (stack[1], stack[2], stack[3]) + else: + prefix = "%s:%s:%s()" % (stack[1], stack[2], stack[3]) + + if type(priority) == type("") or type(priority) == type(u""): + logPriority = syslog.LOG_INFO + logMessage = priority + else: + logPriority = priority + logMessage = message + + if SYSLOG_REQUIRED: + syslog.syslog(logPriority, "[%s]: %s" % (prefix, logMessage)) + return + + fp = sys.stderr + if LOG_FILE_OBJ: + fp = LOG_FILE_OBJ + + fp.write("[%s] %s [%s]: %s" % (str(datetime.now()), _getLogCode(logPriority), prefix, logMessage)) + if logMessage[-1] != '\n': + fp.write("\n") + fp.flush() + return + + +def trace(message): + if message: + log(syslog.LOG_DEBUG, message) + + +def isString(value): + return (type(value) == type("") or type(value) == type(u"")) + + +def getTempFileName(): + return tempfile.mkstemp(prefix="GSP_")[1] + + +def runCommandBG(command, stdinFileObj=None, stdoutFileObj=None, stderrFileObj=None, + shell=False, root=None): + log("runCommandBG(): Trying to execute command [%s]" % command) + + if shell: + if not isString(command): + return None + else: + if isString(command): + command = command.split() + + if root == True: + if shell: + command = "sudo " + command + else: + command = ['sudo'] + command + elif isString(root): + if shell: + command = "sudo -u " + root + " " + command + else: + command = ['sudo', '-u', root] + command + + if not stdinFileObj: + stdinFileObj=subprocess.PIPE + if not stdoutFileObj: + stdoutFileObj=subprocess.PIPE + if not stderrFileObj: + stderrFileObj=subprocess.PIPE + + try: + process = subprocess.Popen(command, + bufsize=-1, + stdin=stdinFileObj, + stdout=stdoutFileObj, + stderr=stderrFileObj, + shell=shell) + return process + except OSError, e: + log("runCommandBG(): Failed to run command [%s]: %s" % (command, e)) + return None + + +def runCommand(command, + input='', output=False, + shell=False, root=None): + rv = {} + rv["Status"] = RUN_COMMAND_ERROR + rv["Stdout"] = None + rv["Stderr"] = None + + try: + stdinFileName = getTempFileName() + stdinFileObj = open(stdinFileName, "w") + stdinFileObj.write(input) + stdinFileObj.close() + stdinFileObj = open(stdinFileName, "r") + + stdoutFileName = getTempFileName() + stdoutFileObj = open(stdoutFileName, "w") + + stderrFileName = getTempFileName() + stderrFileObj = open(stderrFileName, "w") + except IOError, e: + log("Failed to create temporary file for executing command [%s]: %s" % (command, e)) + if output: + return rv + return rv["Status"] + + stdoutContent = None + stderrContent = None + + process = runCommandBG(command, + stdinFileObj=stdinFileObj, + stdoutFileObj=stdoutFileObj, + stderrFileObj=stderrFileObj, + shell=shell, root=root) + if process: + rv['Status'] = process.wait() + rv['Stdout'] = open(stdoutFileName).read() + rv['Stderr'] = open(stderrFileName).read() + + os.remove(stdinFileName) + os.remove(stdoutFileName) + os.remove(stderrFileName) + + log("runCommand(): execution status of command [%s] = [%s]" % (command, rv)) + + if output: + return rv + return rv["Status"] + + +def runCommandFG(command, stdout=False, stderr=False, + shell=False, root=None): + if stdout or stderr: + output = True + else: + output = False + return runCommand(command, output=output, shell=shell, root=root) + + +def IP2Number(ipString): + try: + return socket.htonl(struct.unpack("I", socket.inet_aton(ipString))[0]) + except socket.error: + return None + except TypeError: + return None + except struct.error: + return None + + +def Number2IP(number): + try: + return socket.inet_ntoa(struct.pack("I", socket.ntohl(number))) + except socket.error: + return None + except AttributeError: + return None + except ValueError: + return None + + +def computeHostName(hostName): + if not hostName: + return False + + hostPrefix = "" + for i in range(len(hostName), 0, -1): + pos = i - 1 + if hostName[pos].isdigit(): + continue + break + hostPrefix = hostName[:pos+1] + try: + hostIndex = int(hostName[pos+1:]) + except ValueError: + hostIndex = 0 + # TODO: Check the availablity of the (server) name + return "%s%s" % (hostPrefix, hostIndex + 1) + + +def daemonize(): + try: + pid = os.fork() + if pid > 0: + # exit first parent + sys.exit(0) + except OSError, e: + #sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) + return False + + # decouple from parent environment + os.chdir("/") + os.setsid() + os.umask(0) + + # do second fork + try: + pid = os.fork() + if pid > 0: + # exit from second parent + sys.exit(0) + except OSError, e: + #sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) + return False + + # redirect standard file descriptors + sys.stdout.flush() + sys.stderr.flush() + si = file("/dev/null", 'r') + so = file("/dev/null", 'a+') + se = file("/dev/null", 'a+', 0) + os.dup2(si.fileno(), sys.stdin.fileno()) + os.dup2(so.fileno(), sys.stdout.fileno()) + os.dup2(se.fileno(), sys.stderr.fileno()) + return True + + +def getDownloadStatus(fileName): + try: + lines = [line for line in open(fileName) + if "saved" in line or "%" in line] + except IOError: + return 0 + if not lines: + return 0 + if "saved" in lines[-1]: + return 100 + return lines[-1].split("%")[0].split()[-1] + + +def getMeminfo(): + """-> dict of data from meminfo (str:int). + Values are in kilobytes. + """ + import re + re_parser = re.compile(r'^(?P\S*):\s*(?P\d*)\s*kB' ) + result = {} + for line in open('/proc/meminfo'): + match = re_parser.match(line) + if not match: + continue # skip lines that don't parse + key, value = match.groups(['key', 'value']) + result[key] = int(value) + return result + + +def getCpuUsage(): + """-> dict of cpuid : (usertime, nicetime, systemtime, idletime) + cpuid "cpu" means the total for all CPUs. + cpuid "cpuN" means the value for CPU N. + """ + wanted_records = [line for line in open('/proc/stat') if + line.startswith('cpu')] + result = {} + for cpuline in wanted_records: + fields = cpuline.split()[:5] + data = map(int, fields[1:]) + result[fields[0]] = tuple(data) + return result + + +def getLoadavg(): + """-> 5-tuple containing the following numbers in order: + - 1-minute load average (float) + - 5-minute load average (float) + - 15-minute load average (float) + - Number of threads/processes currently executing (<= number of + CPUs) (int) + - Number of threads/processes that exist on the system (int) + - The PID of the most recently-created process on the system (int) + """ + loadavgstr = open('/proc/loadavg', 'r').readline().strip() + data = loadavgstr.split() + avg1, avg5, avg15 = map(float, data[:3]) + threads_and_procs_running, threads_and_procs_total = map(int, + data[3].split('/')) + most_recent_pid = int(data[4]) + ncpus = 1 + final_avg = "" + if hasattr(os, "sysconf"): + if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"): + # Linux + ncpus = os.sysconf("SC_NPROCESSORS_ONLN") + if isinstance(ncpus, int) and ncpus > 0: + final_avg = "%.2f" % (1.0 * avg1 / ncpus) + + # Future return everything when needed + # Commenting this for the time being + # avg5, avg15, threads_and_procs_running, threads_and_procs_total, most_recent_pid + return final_avg + + +def getInfinibandPortStatus(): + + """ Check for availability of infiniband port + and return which port is active in a key pair value + """ + + # Check for existence of infiniband ports + value = os.popen ("ls /sys/class/infiniband").readline().strip() + + if not value: + return None + + portlist = os.popen ("echo /sys/class/infiniband/*/ports/*").readline().split() + + portkeys = {} + + for port in portlist: + value = os.popen ("cat %s/state" % + port.strip()).readline().split(':')[1].strip() + portkeys[port.strip()] = value + + return portkeys + + +def getServerCount(): + try: + return int(open(Globals.SERVER_COUNT_FILE).read().strip()) + except IOError: + log("failed to read file %s" % Globals.SERVER_COUNT_FILE) + return 1 + except ValueError: + log("invalid number format in file %s" % Globals.SERVER_COUNT_FILE) + return 1 + + +def setServerCount(count): + try: + open(Globals.SERVER_COUNT_FILE, "w").write("%s\n" % count) + return True + except IOError: + log("failed to write file %s" % Globals.SERVER_COUNT_FILE) + return False + + +def getInstalledServerCount(): + try: + return int(open(Globals.INSTALLED_SERVER_COUNT_FILE).read().strip()) + except IOError: + log("failed to read file %s" % Globals.INSTALLED_SERVER_COUNT_FILE) + return 1 + except ValueError: + log("invalid number format in file %s" % Globals.INSTALLED_SERVER_COUNT_FILE) + return 1 + + +def setInstalledServerCount(count): + try: + open(Globals.INSTALLED_SERVER_COUNT_FILE, "w").write("%s\n" % count) + return True + except IOError: + log("failed to write file %s" % Globals.INSTALLED_SERVER_COUNT_FILE) + return False + + +def getLastInstalledServerIpList(): + ipList = {} + networkDom = Protocol.XDOM() + if not networkDom.parseFile(Globals.GLOBAL_NETWORK_FILE): + log("failed to parse file %s" % Globals.GLOBAL_NETWORK_FILE) + for tagE in networkDom.getElementsByTagRoute("server.interface"): + interfaceDom = Protocol.XDOM() + interfaceDom.setDomObj(tagE) + ipAddress = interfaceDom.getTextByTagRoute("ipaddr") + if ipAddress: + ipList[interfaceDom.getTextByTagRoute("device")] = ipAddress + return ipList + + +def getFreeIpAddress(device=None): + serverCount = getServerCount() + installedServerCount = getInstalledServerCount() + if serverCount == installedServerCount: + return None + + availableServerCount = serverCount - installedServerCount + ipList = getLastInstalledServerIpList() + + if not ipList: + return None + + if device: + if device not in ipList.keys(): + return None + deviceIpAddress = ipList[device] + else: + deviceIpAddress = ipList.values()[0] + ipNumber = IP2Number(deviceIpAddress) + + for i in range((ipNumber + availableServerCount), ipNumber, -1): + ipAddress = Number2IP(i) + if runCommandFG(["ping", "-qnc", "1", ipAddress]) != 0: + return ipAddress + return None + + +def getPasswordHash(userName): + try: + #return spwd.getspnam(userName).sp_pwd + return "Not implimented" + except KeyError: + return None + + +def getTransactionKey(): + try: + tokens = open(Globals.TRANSACTION_KEY_FILE).read().split(',') + except IOError: + return None, None + return tokens + + +def generateSignature(): + #return str(uuid.uuid4()) + ('--%f' % time.time()) + return ('--%f' % time.time()) + + +def getSignature(): + try: + return open(Globals.SIGNATURE_FILE).read().strip() + except IOError: + log(syslog.LOG_ERR, "unable to read signaure from %s file" % Globals.SIGNATURE_FILE) + return False + + +def storeSignature(signature, fileName=Globals.SIGNATURE_FILE): + try: + open(fileName, "w").write(signature + "\n") + except IOError: + log(syslog.LOG_ERR, "unable to write signature %s to %s file" % (signature, fileName)) + return False + return True + + +def isUserExist(userName): + try: + grp.getgrnam(userName).gr_gid + return True + except KeyError: + pass + try: + pwd.getpwnam(userName).pw_uid + return True + except KeyError: + pass + return False + + +def getGsnUserInfo(fileName=Globals.GSN_USER_INFO_FILE): + userInfo = {} + userInfo["UserId"] = None + userInfo["Password"] = None + try: + for line in open(fileName): + line = line.strip() + k = line[:line.index("=")] + v = line[line.index("=") + 1:] + if v[0] == "'" or v[0] == '"': + v = v[1:] + if v[-1] == "'" or v[-1] == '"': + v = v[:-1] + if k.upper() == "GSN_ID": + userInfo["UserId"] = v + if k.upper() == "GSN_PASSWORD": + userInfo["Password"] = v + except IOError, e: + log("Failed to read file %s: %s" % (fileName, e)) + return userInfo + + +def setGsnUserInfo(userInfo, fileName=Globals.GSN_USER_INFO_FILE): + try: + fp = open(fileName, "w") + fp.write("GSN_ID=%s\n" % userInfo["UserId"]) + fp.write("GSN_PASSWORD=%s\n" % userInfo["Password"]) + fp.close() + return True + except IOError, e: + log("Failed to write file %s: %s" % (fileName, e)) + return False + + +def getPlatformVersion(fileName=Globals.GLUSTER_VERSION_FILE): + versionInfo = {} + versionInfo["Version"] = None + versionInfo["Update"] = None + try: + lines = open(Globals.GLUSTER_VERSION_FILE).readlines() + for line in open(fileName): + line = line.strip() + k = line[:line.index("=")] + v = line[line.index("=") + 1:] + if v[0] == "'" or v[0] == '"': + v = v[1:] + if v[-1] == "'" or v[-1] == '"': + v = v[:-1] + if k.upper() == "VERSION": + versionInfo["Version"] = v + if k.upper() == "UPDATE": + versionInfo["Update"] = v + except IOError, e: + log("Failed to read file %s: %s" % (fileName, e)) + return versionInfo + + +def setPlatformVersion(versionInfo, fileName=Globals.GLUSTER_VERSION_FILE): + if isString(versionInfo): + tokens = versionInfo.strip().split(".") + if len(tokens) < 2: + log("Invalid version format %s. Expecting .." % versionInfo) + return False + version = ".".join(tokens[:2]) + update = ".".join(tokens[2:]) + if not update: + update = "0" + else: + version = versionInfo["Version"] + update = versionInfo["Update"] + try: + fp = open(fileName, "w") + fp.write("VERSION=%s\n" % version) + fp.write("UPDATE=%s\n" % update) + fp.close() + return True + except IOError, e: + log("Failed to write file %s: %s" % (fileName, e)) + return False + + +def getGlusterUpdateDom(serverVersion): + errorMessage = "" + updateInfoDom = None + try: + baseUrl = open(Globals.GLUSTER_UPDATE_SITE_FILE).read().strip() + except IOError, e: + log("Failed to read file %s: %s" % (Globals.GLUSTER_UPDATE_SITE_FILE, e)) + errorMessage = "Failed to read update site file" + return updateInfoDom, errorMessage + + try: + url = "%s/%s/%s" % (baseUrl, serverVersion, Globals.GLUSTER_UPDATES_FILE) + connection = urllib.urlopen(url) + if connection.getcode() != 200: + connection.close() + errorMessage = "Error received from server to open URL %s" % url + return updateInfoDom, errorMessage + updateInfoString = connection.read() + connection.close() + except IOError, e: + log("Failed to get update information from URL %s: %s" % (url, e)) + errorMessage = "Error getting update information" + return updateInfoDom, errorMessage + + updateInfoDom = Protocol.XDOM() + if not updateInfoDom.parseString(updateInfoString): + log("XML parse error on update information content [%s]" % updateInfoString) + errorMessage = "Parse error on update information" + updateInfoDom = None + return updateInfoDom, errorMessage + + +def removeFile(fileName, root=False): + if root: + if runCommand("rm %s" % fileName, root=True) == 0: + return True + return False + try: + os.remove(fileName) + return True + except OSError, e: + Utils.log("Failed to remove file %s: %s" % (fileName, e)) + return False + + +def isLiveMode(): + return os.path.exists(Globals.LIVE_MODE_FILE) diff --git a/src/com.gluster.storage.management.server.scripts/src/VolumeUtils.py b/src/com.gluster.storage.management.server.scripts/src/VolumeUtils.py new file mode 100644 index 00000000..a19ccd62 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/VolumeUtils.py @@ -0,0 +1,610 @@ +# Copyright (c) 2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import os +import glob +import tempfile +from operator import itemgetter +import Globals +from Protocol import * +from Utils import * +from DiskUtils import * +from ServerUtils import * +import GlusterdUtils as Glusterd + + +def isVolumeExist(volumeName): + volumeDom = XDOM() + return volumeDom.parseFile("%s/%s.xml" % (Globals.VOLUME_CONF_DIR, volumeName)) and \ + Glusterd.isVolumeExist(volumeName) + + +def getVolumeUuid(volumeName): + fileName = "%s/%s.xml" % (Globals.VOLUME_CONF_DIR, volumeName) + volumeDom = XDOM() + if not volumeDom.parseFile(fileName): + log("Failed to parse volume configuration file %s of %s" % (fileName, volumeName)) + return None + return volumeDom.getTextByTagRoute("uuid") + + +def readVolumeSmbConfFile(fileName=Globals.VOLUME_SMBCONF_FILE): + entryList = [] + try: + fp = open(fileName) + for line in fp: + tokens = line.split("#")[0].strip().split(";")[0].strip().split("=") + if len(tokens) != 2: + continue + if tokens[0].strip().upper() == "INCLUDE": + entryList.append(tokens[1].strip()) + fp.close() + except IOError, e: + log("Failed to open file %s: %s" % (fileName, str(e))) + return entryList + + +def writeVolumeSmbConfFile(entryList, fileName=Globals.VOLUME_SMBCONF_FILE): + try: + fp = open(fileName, "w") + for entry in entryList: + fp.write("include = %s\n" % entry) + fp.close() + return True + except IOError, e: + log("Failed to write file %s: %s" % (fileName, str(e))) + return False + + +def includeVolume(volumeName, fileName=Globals.VOLUME_SMBCONF_FILE): + volumeFile = "%s/%s.smbconf" % (Globals.VOLUME_CONF_DIR, volumeName) + if not os.path.exists(volumeFile): + return False + entryList = readVolumeSmbConfFile(fileName) + if volumeFile in entryList: + return True + entryList.append(volumeFile) + return writeVolumeSmbConfFile(entryList, fileName) + + +def excludeVolume(volumeName, fileName=Globals.VOLUME_SMBCONF_FILE): + volumeFile = "%s/%s.smbconf" % (Globals.VOLUME_CONF_DIR, volumeName) + if not os.path.exists(volumeFile): + return False + entryList = readVolumeSmbConfFile(fileName) + if volumeFile not in entryList: + return True + entryList.remove(volumeFile) + log("entryList = %s" % entryList) + return writeVolumeSmbConfFile(entryList, fileName) + + +def writeVolumeCifsConfiguration(volumeName, userList, adminUser=None): + volumeFile = "%s/%s.smbconf" % (Globals.VOLUME_CONF_DIR, volumeName) + try: + fp = open(volumeFile, "w") + fp.write("[%s]\n" % volumeName) + fp.write(" comment = %s volume served by Gluster\n" % volumeName) + fp.write(" path = %s/%s\n" % (Globals.CIFS_EXPORT_DIR, volumeName)) + fp.write(" guest ok = yes\n") + fp.write(" public = yes\n") + fp.write(" writable = yes\n") + if adminUser: + fp.write(" admin users = %s, %s\n" % (adminUser, ", ".join(userList))) + fp.write(" valid users = %s, %s\n" % (adminUser, ", ".join(userList))) + else: + fp.write(" admin users = %s\n" % (", ".join(userList))) + fp.write(" valid users = %s\n" % (", ".join(userList))) + fp.close() + return True + except IOError, e: + log("Failed to write file %s: %s" % (volumeFile, str(e))) + return False + + +def removeVolumeCifsConfiguration(volumeName): + volumeFile = "%s/%s.smbconf" % (Globals.VOLUME_CONF_DIR, volumeName) + try: + os.remove(volumeFile) + except OSError, e: + log("Failed to remove file %s: %s" % (volumeFile, str(e))) + + +def getVolumeListByPartitionName(partitionName): + volumeConfigFileList = glob.glob(Globals.VOLUME_CONF_DIR + "/*.xml") + if not volumeConfigFileList: + return None + + volumeList = [] + for volumeXmlFile in volumeConfigFileList: + volumeDom = XDOM() + volumeDom.parseFile(volumeXmlFile) + serverTopology = volumeDom.getElementsByTagRoute("volume.topology.group") + serverPartitionFound = False + for topology in serverTopology: + partitionDom = XDOM() + for partition in topology.getElementsByTagName("partition"): + partitionDom.setDomObj(partition) + if partitionDom.getTextByTagRoute("name") == partitionName: + serverPartitionFound = True + break + if serverPartitionFound: + volumeList.append(volumeDom.getElementsByTagRoute("volume")[0]) + break + return volumeList + + +def addServerPartitionConfig(inputDom, groupOrder, partitionTag): + if not(inputDom and groupOrder and partitionTag): + return False + groupDom = XDOM() + for group in inputDom.getElementsByTagRoute("topology.group"): + groupDom.setDomObj(group) + order = groupDom.getTextByTagRoute("order") + if order and int(order) == groupOrder: + group.appendChild(partitionTag) + return inputDom + return False + + +def removeServerPartitionConfig(inputDom, partitionName): + if not(inputDom and partitionName): + return False + for group in inputDom.getElementsByTagRoute("topology.group"): + partitionDom = XDOM() + for partition in group.getElementsByTagName("partition"): + partitionDom.setDomObj(partition) + if partitionDom.getTextByTagRoute("name") == partitionName: + group.removeChild(partition) + return inputDom + return False + + +def updateServerPartitionConfig(inputDom, partitionName, partitionTag): + if not(inputDom and partitionName and partitionTag): + return False + for group in inputDom.getElementsByTagRoute("topology.group"): + partitionDom = XDOM() + for partition in group.getElementsByTagName("partition"): + partitionDom.setDomObj(partition) + if partitionDom.getTextByTagRoute("name") == partitionName: + try: + group.replaceChild(partitionTag, partition) + return inputDom + except AttributeError: + return False + return False + + +def getServerPartitionConfigUuid(serverGroupList, serverPartition): + for group in serverGroupList: + if not group: + continue + partitionDom = XDOM() + for partition in group.getElementsByTagName("partition"): + partitionDom.setDomObj(partition) + partitionName = partition.getTextByTagName("name") + if not partitionName: + continue + if partitionName == serverPartition: + return partitionDom.getTextByTagName("uuid") + return False + + +def setServerPartitionConfigProperty(inputDom, partitionName, propertyDict): + if not(inputDom and partitionName and propertyDict): + return False + for group in inputDom.getElementsByTagRoute("topology.group"): + partitionDom = XDOM() + for partition in group.getElementsByTagName("partition"): + partitionDom.setDomObj(partition) + if partitionDom.getTextByTagRoute("name") == partitionName: + for part in propertyDict.keys(): + x = partition.getElementsByTagName(part) + if x: + x[0].childNodes[0].nodeValue = propertyDict[part] + return inputDom + return False + + +def getSortedServerPartitionConfigProperty(inputDom): + groupDict = {} + if not inputDom: + return None + groupDom = XDOM() + for group in inputDom.getElementsByTagRoute("topology.group"): + groupDom.setDomObj(group) + groupOrder = groupDom.getTextByTagRoute("order") + if not groupOrder: + return None + groupOrder = int(groupOrder) + if groupOrder < 1: + return None + partitionDom = XDOM() + partitionDict = {} + for partition in group.getElementsByTagName("partition"): + partitionDom.setDomObj(partition) + partitionName = partitionDom.getTextByTagRoute("name") + if not partitionName: + return None + partitionOrder = partitionDom.getTextByTagRoute("order") + if not partitionOrder: + return None + partitionUuid = partitionDom.getTextByTagRoute("uuid") + partitionOrder = int(partitionOrder) + if partitionOrder < 1: + return None + partitionDetails = partitionName.split(":") + if not partitionDetails or len(partitionDetails) < 1: + return None + partitionDict[partitionOrder] = { "order":partitionOrder, + "servername":partitionDetails[0], + "name":partitionDetails[1], + "uuid":partitionUuid} + groupDict[groupOrder] = partitionDict + + serverList = [] + groupOrderList = groupDict.keys() + groupOrderList.sort() + for groupOrder in groupOrderList: + partitionOrderList = groupDict[groupOrder].keys() + partitionOrderList.sort() + for partitionOrder in partitionOrderList: + serverList.append(groupDict[groupOrder][partitionOrder]) + + return serverList + + +def getSortedServerPartitionList(serverGroupElements): + serverPartitionDict = {} + groupOrderList = [] + serverList = [] + partitionDom = XDOM() + for group in serverGroupElements: + if not group: + continue + groupOrderE = group.getElementsByTagName("order") + if not (groupOrderE and groupOrderE[0].childNodes): + return None + value = int(XDOM.getText(groupOrderE[0].childNodes)) + if value > 0: + groupOrderList.append(value) + partitionDict = {} + for partition in group.getElementsByTagName("partition"): + partitionDom.setDomObj(partition) + + partitionName = partitionDom.getTextByTagRoute("name") + if not partitionName: + return None + partitionOrder = partitionDom.getTextByTagRoute("order") + if not partitionOrder: + return None + partitionUuid = partitionDom.getTextByTagRoute("uuid") + partitionDict[int(partitionOrder)] = [partitionName, partitionUuid] + serverPartitionDict[value] = partitionDict + groupOrderList.sort() + + for groupOrder in groupOrderList: + items = serverPartitionDict[groupOrder].items() + items.sort(key = itemgetter(0)) + serverList = serverList + [ items[i][1] for i in range(0,len(items))] + return serverList + + +def clearExportDirectory(serverList, volumeName, volumeUuid): + thisServerName = getCurrentServerName() + for exportServer in serverList: + serverName, partition = exportServer[0].split(":") + if thisServerName != serverName: + continue + partitionUuid = getUuidByDiskPartition(getDevice(partition)) + if not partitionUuid: + log("unable to find uuid of partition %s" % partition) + return False + volumeDirName = "%s/%s/%s" % (Globals.GLUSTER_LUN_DIR, partitionUuid, volumeUuid) + if os.path.exists(volumeDirName): + ## Removing /data/PARTITION-UUID/VOLUME-UUID/ + ## TODO: Get an option to remove it at this time + if runCommandFG("mv -f %s %s.delete" % (volumeDirName, volumeDirName), root=True) != 0: + return False + if runCommandFG("rm -f %s/%s/volumes/%s" % (Globals.GLUSTER_LUN_DIR, partitionUuid, volumeName), root=True) != 0: + return False + return True + + +def createExportDirectory(serverList, volumeName, volumeUuid): + thisServerName = getCurrentServerName() + tempVolumeNameFile = getTempFileName() + + try: + fp = open(tempVolumeNameFile, "w") + fp.write("VOLUME_NAME=%s\n" % volumeName) + fp.write("VOLUME_UUID=%s\n" % volumeUuid) + fp.close() + except IOError, e: + log("failed to create temporary file for volume-name: %s" % (volumeName, str(e))) + return False + + for exportServer in serverList: + serverName, partition = exportServer[0].split(":") + if thisServerName != serverName: + continue + partitionUuid = getUuidByDiskPartition(getDevice(partition)) + if not partitionUuid: + log("unable to find uuid of partition %s" % partition) + return False + + volumeDirName = "%s/%s/%s" % (Globals.GLUSTER_LUN_DIR, partitionUuid, volumeUuid) + ## Creating /data/PARTITION-UUID/VOLUME-UUID/ + if runCommandFG("mkdir %s" % volumeDirName, root=True) != 0: + return False + + ## Creating /data/PARTITION-UUID/VOLUME-UUID/exports/ + ## Creating /data/PARTITION-UUID/VOLUME-UUID/exports/brick1/ + if runCommandFG("mkdir -p %s/exports/brick1" % volumeDirName, root=True) != 0: + return False + + ## Creating /data/PARTITION-UUID/VOLUME-UUID/log/ + if runCommandFG("mkdir %s/log" % volumeDirName, root=True) != 0: + return False + + ## Creating /data/PARTITION-UUID/VOLUME-UUID/config/ + if runCommandFG("mkdir %s/config" % volumeDirName, root=True) != 0: + return False + + volumeLinkDirName = "%s/%s/volumes" % (Globals.GLUSTER_LUN_DIR, partitionUuid) + if not os.path.exists(volumeLinkDirName): + if runCommandFG("mkdir %s" % volumeLinkDirName, root=True) != 0: + return False + + ## Creating symlink + ## /data/PARTITION-UUID/volumes/VOLUME-NAME -> /data/PARTITION-UUID/VOLUME-UUID/ + command = "ln -fTs %s %s/%s" % (volumeDirName, + volumeLinkDirName, volumeName) + if runCommandFG(command, root=True) != 0: + return False + + if runCommandFG("cp -f %s %s/config/volume-name" % (tempVolumeNameFile, volumeDirName), root=True) != 0: + return False + + try: + os.remove(tempVolumeNameFile) + except OSError, e: + log("Failed to remove file %s: %s" % (tempVolumeNameFile, str(e))) + + return True + + +def getPartitionListByServerName(volumeDom, serverName, serverPartitionList=None): + partitionList = {} + if serverPartitionList: + for partitionName in serverPartitionList: + partitionUuid = getServerDiskPartitionUuid(serverName, partitionName) + if not partitionUuid: + log(syslog.LOG_ERR, "failed to get disk partition %s uuid of server %s" % (partitionName, serverName)) + return None + partitionList[partitionName] = partitionUuid + return partitionList + for group in volumeDom.getElementsByTagRoute("topology.group"): + for partitionTag in group.getElementsByTagName("partition"): + nameE = partitionTag.getElementsByTagName("name") + if not nameE: + continue + partition = XDOM.getText(nameE[0].childNodes) + if not partition: + continue + server, partitionName = partition.split(":") + if server != serverName: + continue + partitionUuid = getServerDiskPartitionUuid(serverName, partitionName) + if not partitionUuid: + log(syslog.LOG_ERR, "failed to get disk partition %s uuid of server %s" % (partitionName, serverName)) + return None + partitionList[partitionName] = partitionUuid + return partitionList + + +def isVolumeRunning(volumeName): + return Glusterd.isVolumeRunning(volumeName) + +def addVolumeMigrationDetails(sourcePartition, destinationPartition, volumeName): + migrationDom = XDOM() + if not os.path.exists(Globals.VOLUME_MIGRATION_LIST_FILE): + migrationDom.appendTagRoute("volume-migration") + else: + if not migrationDom.parseFile(Globals.VOLUME_MIGRATION_LIST_FILE): + log("Failed to load volume-migration.xml file") + return None + migrationList = migrationDom.getElementsByTagRoute("volume-migration.migration") + for tagE in migrationList: + dom = XDOM() + dom.setDomObj(tagE) + if dom.getTextByTagRoute("source-partition") == sourcePartition and \ + dom.getTextByTagRoute("destination-partition") == destinationPartition and \ + dom.getTextByTagRoute("volume-name") == volumeName: + return False + migrationTag = migrationDom.getElementsByTagRoute("volume-migration") + if not migrationTag: + return None + partitionTag = migrationDom.createTag("migration") + partitionTag.appendChild(migrationDom.createTag("source-partition", sourcePartition)) + partitionTag.appendChild(migrationDom.createTag("destination-partition", destinationPartition)) + partitionTag.appendChild(migrationDom.createTag("volume-name", volumeName)) + migrationTag[0].appendChild(partitionTag) + if not migrationDom.writexml(Globals.VOLUME_MIGRATION_LIST_FILE): + log("Unable to write disk migration details into %s/volume-migration.xml" % Globals.GLUSTER_BASE_DIR) + return False + return True + + +def removeVolumeMigrationDetails(sourcePartition, destinationPartition, volumeName): + migrationDom = XDOM() + if not os.path.exists(Globals.VOLUME_MIGRATION_LIST_FILE): + return None + if not migrationDom.parseFile(Globals.VOLUME_MIGRATION_LIST_FILE): + log("Failed to load volume-migration.xml file") + return None + migrationList = migrationDom.getElementsByTagRoute("volume-migration.migration") + for tagE in migrationList: + dom = XDOM() + dom.setDomObj(tagE) + if dom.getTextByTagRoute("source-partition") == sourcePartition and \ + dom.getTextByTagRoute("destination-partition") == destinationPartition and \ + dom.getTextByTagRoute("volume-name") == volumeName: + migrationDom.getElementsByTagRoute("volume-migration")[0].removeChild(tagE) + if not migrationDom.writexml(Globals.VOLUME_MIGRATION_LIST_FILE): + log("Unable to write disk migration details into %s/volume-migration.xml" % Globals.GLUSTER_BASE_DIR) + return False + return True + + +def addPartitionMigrationDetails(sourcePartition, destinationPartition, volumeList=None): + migrationDom = XDOM() + if not os.path.exists(Globals.MIGRATE_PARTITION_LIST_FILE): + migrationDom.appendTagRoute("partition-migration") + else: + if not migrationDom.parseFile(Globals.MIGRATE_PARTITION_LIST_FILE): + log("Failed to load migration.xml file") + return None + migrationList = migrationDom.getElementsByTagRoute("partition-migration.migration") + for tagE in migrationList: + dom = XDOM() + dom.setDomObj(tagE) + if dom.getTextByTagRoute("source-partition") == sourcePartition: + return False + if dom.getTextByTagRoute("destination-partition") == destinationPartition: + return False + migrationTag = migrationDom.getElementsByTagRoute("partition-migration") + if not migrationTag: + return None + partitionTag = migrationDom.createTag("migration") + partitionTag.appendChild(migrationDom.createTag("source-partition", sourcePartition)) + partitionTag.appendChild(migrationDom.createTag("destination-partition", destinationPartition)) + migrationTag[0].appendChild(partitionTag) + if not migrationDom.writexml(Globals.MIGRATE_PARTITION_LIST_FILE): + log("Unable to write disk migration details into %s/migration.xml" % Globals.GLUSTER_BASE_DIR) + return False + if volumeList: + for volumeName in volumeList: + addVolumeMigrationDetails(sourcePartition, destinationPartition, volumeName) + return True + + +def removePartitionMigrationDetails(sourcePartition, destinationPartition, volumeList=None): + migrationDom = XDOM() + if not os.path.exists(Globals.MIGRATE_PARTITION_LIST_FILE): + return None + if not migrationDom.parseFile(Globals.MIGRATE_PARTITION_LIST_FILE): + log("Failed to load migration.xml file") + return None + migrationList = migrationDom.getElementsByTagRoute("partition-migration.migration") + for tagE in migrationList: + dom = XDOM() + dom.setDomObj(tagE) + if dom.getTextByTagRoute("source-partition") == sourcePartition and \ + dom.getTextByTagRoute("destination-partition") == destinationPartition: + migrationDom.getElementsByTagRoute("partition-migration")[0].removeChild(tagE) + if not migrationDom.writexml(Globals.MIGRATE_PARTITION_LIST_FILE): + log("Unable to write disk migration details into %s/migration.xml" % Globals.GLUSTER_BASE_DIR) + return False + if volumeList: + for volumeName in volumeList: + removeVolumeMigrationDetails(sourcePartition, destinationPartition, volumeName) + return True + + +def isMigrationInProgress(partition): + migrationDom = XDOM() + if not os.path.exists(Globals.MIGRATE_PARTITION_LIST_FILE): + return None + if not migrationDom.parseFile(Globals.MIGRATE_PARTITION_LIST_FILE): + log("Failed to load migration.xml file") + return None + migrationList = migrationDom.getElementsByTagRoute("partition-migration.migration") + for tagE in migrationList: + dom = XDOM() + dom.setDomObj(tagE) + if migrationDom.getTextByTagRoute("source-partition") == partition or \ + migrationDom.getTextByTagRoute("destination-partition") == partition: + return True + return False + + +def getServerDiskPartitionUuid(serverName, partition): + diskConfigDom = XDOM() + if not diskConfigDom.parseFile("%s/%s/disk.xml" % (Globals.SERVER_CONF_DIR, serverName)): + return None + for disk in diskConfigDom.getElementsByTagRoute("disks.disk"): + diskDom = XDOM() + diskDom.setDomObj(disk) + partitionList = diskDom.getElementsByTagRoute("partition") + for tagE in partitionList: + partitionDom = XDOM() + partitionDom.setDomObj(tagE) + if partitionDom.getTextByTagRoute("device") == partition: + return partitionDom.getTextByTagRoute("uuid") + + +def getVolumeServerList(requestDom, requestFlag=True): + if requestFlag: + serverGroupElementList = requestDom.getElementsByTagRoute("command.volume.topology.group") + else: + serverGroupElementList = requestDom.getElementsByTagRoute("volume.topology.group") + if not serverGroupElementList: + return None + serverList = [] + partitionDom = XDOM() + for group in serverGroupElementList: + for partition in group.getElementsByTagName("partition"): + partitionDom.setDomObj(partition) + partitionName = partitionDom.getTextByTagRoute("name") + if not partitionName: + continue + serverPartition = partitionName.split(":") + if not(len(serverPartition) > 1 and serverPartition[1]): + return None + if serverPartition[0] not in serverList: + serverList.append(serverPartition[0]) + return serverList + + +def getVolumeServerListByName(volumeName): + serverList = [] + serverDom = XDOM() + volumeDom = XDOM() + if not os.path.exists("%s/%s.xml" % (Globals.VOLUME_CONF_DIR, volumeName)): + return False + if not volumeDom.parseFile("%s/%s.xml" % (Globals.VOLUME_CONF_DIR, volumeName)): + return False + return getVolumeServerList(volumeDom, False) + + +def getMigrateVolumeServerPartitionInfo(volumeName): + volumeMigrationDom = XDOM() + if not volumeMigrationDom.parseFile(Globals.VOLUME_MIGRATION_LIST_FILE): + Utils.log("Failed to parse file %s" % Globals.VOLUME_MIGRATION_LIST_FILE) + return None + volumeInfo = {} + dom = XDOM() + for tagE in volumeMigrationDom.getElementsByTagRoute("volume-migration.migration"): + dom.setDomObj(tagE) + if dom.getTextByTagRoute("volume-name") == volumeName: + volumeInfo['Name'] = volumeName + volumeInfo['SourcePartition'] = dom.getTextByTagRoute("source-partition") + volumeInfo['DestinationPartition'] = dom.getTextByTagRoute("destination-partition") + return volumeInfo + return None diff --git a/src/com.gluster.storage.management.server.scripts/src/XmlHandler.py b/src/com.gluster.storage.management.server.scripts/src/XmlHandler.py new file mode 100644 index 00000000..72164ffb --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/XmlHandler.py @@ -0,0 +1,346 @@ +# Copyright (C) 2009 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import xml +import xml.parsers.expat +import xml.dom.minidom as MDOM +import os +import Globals +import copy +import Utils + +XML_STRING = 0 +XML_FILE = 1 + +class XDOM: + _domObj = None + + def __init__(self): + self._domObj = MDOM.Document() + return + + @classmethod + def getText(self, nodeList): + rc = "" + for node in nodeList: + if node.nodeType == node.TEXT_NODE: + rc = rc + node.data + return rc + + def parseString(self, requestString): + try: + self._domObj = MDOM.parseString(requestString) + except xml.parsers.expat.ExpatError, e: + Utils.log("XML string parse error: %s" % str(e)) + return False + return True + + def parseFile(self, fileName): + try: + self._domObj = MDOM.parse(fileName) + except IOError, e: + Utils.log("error reading file: %s" % str(e)) + return False + except xml.parsers.expat.ExpatError, e: + Utils.log("XML file %s parse error: %s" % (fileName, str(e))) + return False + return True + + def setDomObj(self, dom): + if dom and type(dom) != type([]): + self._domObj = dom + return True + return False + + def createTag(self, tag, text=None): + if not self._domObj: + return None + if tag == None: + return None + + tagE = self._domObj.createElement(str(tag)) + if text: + tagEText = self._domObj.createTextNode(str(text)) + tagE.appendChild(tagEText) + return tagE + + def addTag(self, tag): + if not self._domObj: + return False + if not tag: + return False + + self._domObj.appendChild(tag) + return True + + def createTagRoute(self, tagRoute, text=None): + if not tagRoute: + return False + + tagList = tagRoute.split(".") + tag = None + previousTag = None + for tagName in tagList[:-1]: + newTag = self.createTag(tagName, None) + if not tag: + tag = newTag + previousTag = newTag + continue + previousTag.appendChild(newTag) + previousTag = newTag + + if previousTag: + previousTag.appendChild(self.createTag(tagList[-1], text)) + else: + tag = self.createTag(tagList[-1], text) + return tag + + def appendTagRoute(self, tagRoute, value=None): + if not self._domObj: + return False + if not tagRoute: + return False + + parentTagE = self._domObj + + tagNameList = tagRoute.split(".") + newTagRoute = tagNameList.pop(-1) + + for i in range(len(tagNameList), 0, -1): + tagE = self.getElementsByTagRoute(".".join(tagNameList[:i])) + if tagE: + parentTagE = tagE[0] + break + newTagRoute = tagNameList[i-1] + "." + newTagRoute + + newTagE = self.createTagRoute(newTagRoute, value) + if not newTagE: + return False + try: + parentTagE.appendChild(newTagE) + except xml.dom.HierarchyRequestErr, e: + Utils.log("error occured. %s" + str(e)) + return False + return True + + def setTextByTagRoute(self, tagRoute, tagValue): + if not self._domObj: + return None + + if not tagRoute: + return None + + tagE = self.getElementsByTagRoute(tagRoute) + if not tagE: + return False + + parentTagE = self.getElementsByTagRoute(".".join(tagRoute.split(".")[:-1])) + if not parentTagE: + return False + + parentTagE[0].childNodes.remove(tagE[0]) + parentTagE[0].appendChild(self.createTag(tagRoute.split(".")[-1], tagValue)) + return True + + def getElementsByTagRoute(self, tagRoute): + if not self._domObj: + return None + + if not tagRoute: + return None + + x = None + for tag in tagRoute.split("."): + if x is None: + x = self._domObj.getElementsByTagName(tag) + continue + if x == []: + break + x = x[0].getElementsByTagName(tag) + return x + + def getTextByTagRoute(self, tagRoute): + if not self._domObj: + return None + + x = self.getElementsByTagRoute(tagRoute) + if x: + return self.getText(x[0].childNodes) + return None + + def getElementsByTagName(self, name): + if not self._domObj: + return None + return self._domObj.getElementsByTagName(name) + + def writexml(self, fileName, indent="", addindent="", newl=""): + if not self._domObj: + return None + try: + fp = open(fileName, "w") + self._domObj.writexml(fp, indent, addindent, newl) + fp.close() + return True + except IOError: + return False + + def toString(self, indent=" ", newl="\n", encoding = None): + if not self._domObj: + return None + return self._domObj.toprettyxml(indent, newl, encoding) + + def toxml(self, encoding = None): + if not self._domObj: + return None + return self._domObj.toxml(encoding) + + def toprettyxml(self, indent=" ", newl="\n", encoding = None): + return self.toString(indent, newl, encoding) + + def createResponseTag(self): + responseTag = self._domObj.createElement("response") + return responseTag +##--end of XDOM + +class RequestXml(XDOM): + def __init__(self, requestString, type=None): + if None == requestString: + XDOM.__init__(self) + return + try: + if None == type: + if os.path.isfile(requestString): + self._domObj = MDOM.parse(requestString) + else: + self._domObj = MDOM.parseString(requestString) + elif XML_FILE == type: + self._domObj = MDOM.parse(requestString) + elif XML_STRING == type: + self._domObj = MDOM.parseString(requestString) + except IOError: + XDOM.__init__(self) + except xml.parsers.expat.ExpatError: + XDOM.__init__(self) + +##--end of RequestXML + + +class ResponseXml(XDOM): + _responseTag = None + def __init__(self): + XDOM.__init__(self) + self._responseTag = self.createResponseTag() + self._domObj.appendChild(self._responseTag) + + @classmethod + def errorResponse(self, message): + if not self.responseTag: + return False + self.appendTagRoute("status.code", "-1"); + self.appendTagRoute("status.message", message) + + def append(self, tagName, tagValue=None): + if not self._responseTag: + return False + tag = self.createTag(tagName, tagValue) + if tag: + self._responseTag.appendChild(tag) + return True + return False + + def appendTag(self, tag): + if not tag: + return False + if not self._responseTag: + return False + self._responseTag.appendChild(tag) + return True + + def appendTagRoute(self, tagRoute, value=None): + if not self._responseTag: + return None + if not tagRoute: + return None + + parentTagE = self._responseTag + + tagNameList = tagRoute.split(".") + newTagRoute = tagNameList.pop(-1) + + for i in range(len(tagNameList), 0, -1): + tagE = self.getElementsByTagRoute(".".join(["response"] + tagNameList[:i])) + if tagE: + parentTagE = tagE[0] + break + newTagRoute = tagNameList[i-1] + "." + newTagRoute + + newTagE = self.createTagRoute(newTagRoute, value) + if not newTagE: + return None + try: + parentTagE.appendChild(newTagE) + except xml.dom.HierarchyRequestErr, e: + Utils.log("error occured. %s" + str(e)) + return None + return newTagE + + def appendTagRouteOld(self, tagRoute, value=None): + if not self._responseTag: + return False + if not tagRoute: + return False + + parentTagE = self._responseTag + + tagNameList = tagRoute.split(".") + newTagRoute = tagNameList.pop(-1) + + for i in range(len(tagNameList), 0, -1): + tagE = self.getElementsByTagRoute(".".join(["response"] + tagNameList[:i])) + if tagE: + parentTagE = tagE[0] + break + newTagRoute = tagNameList[i-1] + "." + newTagRoute + + newTagE = self.createTagRoute(newTagRoute, value) + if not newTagE: + return False + try: + parentTagE.appendChild(newTagE) + except xml.dom.HierarchyRequestErr, e: + Utils.log("error occured. %s" + str(e)) + return False + return True +##--end of ResponseXml + +def test(): + rs = ResponseXml() + rs.appendTagRoute("status.code", "0"); + rs.appendTagRoute("status.message", "SUCCESS") + serverTag = rs.appendTagRoute("server.name", "Server1") + networkInterfaces = rs.appendTagRoute("server.networkInterfaces", None) + networkTag = rs.createTag("networkInterface", None) + networkTag.appendChild(rs.createTag("name", "interface1")) + networkTag.appendChild(rs.createTag("ipaddress", "192.168.1.40")) + networkInterfaces.appendChild(networkTag) + networkTag = rs.createTag("networkInterface", None) + networkTag.appendChild(rs.createTag("name", "interface2")) + networkTag.appendChild(rs.createTag("ipaddress", "192.168.1.41")) + networkInterfaces.appendChild(networkTag) + print rs.toprettyxml() + +#test() diff --git a/src/com.gluster.storage.management.server.scripts/src/clear_volume_directory.py b/src/com.gluster.storage.management.server.scripts/src/clear_volume_directory.py new file mode 100755 index 00000000..3bd0ab6f --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/clear_volume_directory.py @@ -0,0 +1,101 @@ +#!/usr/bin/python +# Copyright (C) 2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . +import os +import sys +import syslog +import time +from XmlHandler import ResponseXml +import DiskUtils +import Utils +import Common +from optparse import OptionParser + +def clearVolumeDirectory(disk, volumeName, todelete): + + # Retrieving disk uuid + diskUuid = DiskUtils.getUuidByDiskPartition(DiskUtils.getDevice(disk)) + + rs = ResponseXml() + if not diskUuid: + Common.log(syslog.LOG_ERR, "failed to find disk:%s uuid" % disk) + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "Error: Unable to find disk uuid") + return rs.toprettyxml() + + # Retrieving disk mount point using disk uuid + diskMountPoint = DiskUtils.getMountPointByUuid(diskUuid) + if not os.path.exists(diskMountPoint): + Common.log(syslog.LOG_ERR, "failed to retrieve disk:%s mount point" % disk) + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "Error: Failed to retrieve disk details") + return rs.toprettyxml() + + # clear volume directory from the disk + volumeDirectory = "%s/%s" % (diskMountPoint, volumeName) + newVolumeDirectoryName = "%s_%s" % (volumeDirectory, time.time()) + command = ["sudo", "mv", "-f", volumeDirectory, newVolumeDirectoryName] + rv = Utils.runCommandFG(command, stdout=True, root=True) + message = Common.stripEmptyLines(rv["Stdout"]) + if rv["Stderr"]: + error = Common.stripEmptyLines(rv["Stderr"]) + message += "Error: [%s]" % (error) + Common.log(syslog.LOG_ERR, "failed to rename volume directory %s, %s" % (volumeDirectory, error)) + rs.appendTagRoute("status.code", rv["Status"]) + rs.appendTagRoute("status.message", message) + return rs.toprettyxml() + + if not todelete: + rv["Status"] = "0" + rs.appendTagRoute("status.code", rv["Status"]) + rs.appendTagRoute("status.message", message) + return rs.toprettyxml() + + command = ["sudo", "rm", "-fr", newVolumeDirectoryName] + rv = Utils.runCommandFG(command, stdout=True, root=True) + message = Common.stripEmptyLines(rv["Stdout"]) + if rv["Stderr"]: + error = Common.stripEmptyLines(rv["Stderr"]) + message += "Error: [%s]" % (error) + Common.log(syslog.LOG_ERR, "failed to clear volume directory %s, %s" % (newVolumeDirectoryName, error)) + rs.appendTagRoute("status.code", rv["Status"]) + rs.appendTagRoute("status.message", message) + return rs.toprettyxml() + + if not rv["Status"]: + rv["Status"] = "0" + rs.appendTagRoute("status.code", rv["Status"]) + rs.appendTagRoute("status.message", message) + return rs.toprettyxml() + +def main(): + parser = OptionParser() + parser.add_option("-d", "--delete", dest="deletedir", action="store_true", default=False, help="force delete") + (options, args) = parser.parse_args() + + if len(args) != 2: + print >> sys.stderr, "usage: %s [-d/--delete]" % sys.argv[0] + sys.exit(-1) + + disk = args[0] + volumeName = args[1] + print clearVolumeDirectory(disk, volumeName, options.deletedir) + sys.exit(0) + +if __name__ == "__main__": + main() + diff --git a/src/com.gluster.storage.management.server.scripts/src/common/Commands.py b/src/com.gluster.storage.management.server.scripts/src/common/Commands.py deleted file mode 100644 index c728b565..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/common/Commands.py +++ /dev/null @@ -1,78 +0,0 @@ -COMMAND_CREATE_VOLUME = "create-volume" -COMMAND_DELETE_VOLUME = "delete-volume" -COMMAND_START_VOLUME = "start-volume" -COMMAND_STOP_VOLUME = "stop-volume" -COMMAND_GET_VOLUME_HEALTH_STATUS = "get-volume-health-status" -COMMAND_GET_VOLUME_LIST = "get-volume-list" -COMMAND_GET_VOLUME_LOG = "get-volume-log" -COMMAND_CLEAR_VOLUME_LOGS = "clear-volume-logs" -COMMAND_GET_VOLUME_PROPERTY = "get-volume-property" -COMMAND_SET_VOLUME_PROPERTY = "set-volume-property" -COMMAND_GET_VOLUME_STATUS = "get-volume-status" -COMMAND_DOWNLOAD_VOLUME_LOGS = "download-volume-logs" -COMMAND_DELETE_SERVER = "delete-server" -COMMAND_GET_SERVER_DATE = "get-server-date" -COMMAND_GET_SERVER_VERSION_INFO = "get-server-version-info" -COMMAND_GET_INSTALLER_INFO = "get-installer-info" -COMMAND_GET_SERVER_LIST = "get-server-list" -COMMAND_GET_SERVER_SERVICE_STATUS = "get-server-service-status" -COMMAND_GET_STORAGE_SERVER_POOL_INFO = "get-storage-server-pool-info" -COMMAND_INSTALL_SERVER_BACKGROUND = "install-server-background" -COMMAND_PREPARE_DATA_DISK_BACKGROUND = "prepare-data-disk-background" -COMMAND_SET_SERVER_DATE = "set-server-date" -COMMAND_SET_SERVER_NETWORK_CONFIG = "set-server-network-config" -COMMAND_SET_STORAGE_SERVER_POOL_INFO = "set-storage-server-pool-info" -COMMAND_GET_SERVER_NETWORK_CONFIG = "get-server-network-config" -COMMAND_INSTALL_SERVER_STATUS = "install-server-status" -COMMAND_GET_SERVER_DISK_LIST = "get-server-disk-list" -COMMAND_PREPARE_DATA_DISK_STATUS = "prepare-data-disk-status" -COMMAND_GET_SERVER_SYSTEM_RESOURCE = "get-server-system-resource" -COMMAND_GET_SERVER_RESOURCE_RRD = "get-server-resource-rrd" -COMMAND_RUN_SERVER_SERVICE = "run-server-service" -COMMAND_SHUTDOWN_SERVER = "shutdown-server" -COMMAND_GET_SERVER_STATUS = "get-server-status" -COMMAND_GET_SERVER_LOG = "get-server-log" -COMMAND_DOWNLOAD_SERVER_LOGS = "download-server-logs" -COMMAND_CLEAR_SERVER_LOGS = "clear-server-logs" -COMMAND_GET_SERVER_RESOURCE_RRD = "get-server-resource-rrd" -COMMAND_GET_GSN_USER_INFO = "get-gsn-user-info" -COMMAND_SET_GSN_USER_INFO = "set-gsn-user-info" -COMMAND_GET_GLUSTER_UPDATE_INFO = "get-gluster-update-info" -COMMAND_DOWNLOAD_GLUSTER_UPDATE_BACKGROUND = "download-gluster-update-background" -COMMAND_DOWNLOAD_GLUSTER_UPDATE_STATUS = "download-gluster-update-status" -COMMAND_INSTALL_GLUSTER_UPDATE = "install-gluster-update" -COMMAND_EXPORT_CONFIG = "export-config" -COMMAND_IMPORT_CONFIG = "import-config" -COMMAND_SET_SYSTEM_PASSWORD = "set-system-password" -COMMAND_GET_SERVER_VOLUME_LIST = "get-server-volume-list" -COMMAND_RECONFIGURE_VOLUME = "reconfigure-volume" -COMMAND_SET_SERVER_DIRECTORY_SERVICE_CONFIG = "set-server-directory-service-config" -COMMAND_GET_SERVER_DIRECTORY_SERVICE_CONFIG = "get-server-directory-service-config" -COMMAND_JOIN_SERVER_TO_DIRECTORY_SERVICE = "join-server-to-directory-service" -COMMAND_SET_SERVER_TIME_CONFIG = "set-server-time-config" -COMMAND_GET_SERVER_TIME_CONFIG = "get-server-time-config" -COMMAND_LOGIN = "login" -COMMAND_LOGOUT = "logout" -COMMAND_GET_LOGIN_STATUS = "get-login-status" -COMMAND_GET_SERVER_TRANSPORT_LIST = "get-server-transport-list" -COMMAND_ADD_SERVER_PARTITION = "add-server-partition" -COMMAND_ADD_VOLUME_USER = "add-volume-user" -COMMAND_GET_PARTITION_VOLUME_LIST = "get-partition-volume-list" -COMMAND_GET_VOLUME_USER_INFO = "get-volume-user-info" -COMMAND_GET_VOLUME_USER_LIST = "get-volume-user-list" -COMMAND_MIGRATE_PARTITION_BACKGROUND = "migrate-partition-background" -COMMAND_MIGRATE_PARTITION_STATUS = "migrate-partition-status" -COMMAND_MIGRATE_VOLUME_SERVER_PARTITION_BACKGROUND = "migrate-volume-server-partition-background" -COMMAND_MIGRATE_VOLUME_SERVER_PARTITION_STATUS = "migrate-volume-server-partition-status" -COMMAND_REMOVE_SERVER_PARTITION = "remove-server-partition" -COMMAND_REMOVE_VOLUME_USER = "remove-volume-user" -COMMAND_RENAME_VOLUME_USER = "rename-volume-user" -COMMAND_RENAME_VOLUME = "rename-volume" -COMMAND_RUN_SERVER_SERVICE = "run-server-service" -COMMAND_SET_VOLUME_USER_PASSWORD = "set-volume-user-password" -COMMAND_STOP_PARTITION_MIGRATION = "stop-partition-migration" -COMMAND_STOP_VOLUME_SERVER_PARTITION_MIGRATION = "stop-volume-server-partition-migration" -COMMAND_GET_SERVER_DISK_INFO = "get-server-disk-info" -COMMAND_INITIALIZE_SERVER_DISK = "initialize-server-disk" -COMMAND_SET_SERVER_COUNT = "set-server-count" -COMMAND_GET_SERVER_COUNT = "get-server-count" diff --git a/src/com.gluster.storage.management.server.scripts/src/common/Common.py b/src/com.gluster.storage.management.server.scripts/src/common/Common.py deleted file mode 100644 index 99c2f440..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/common/Common.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2009 Gluster, Inc. -# This file is part of GlusterSP. -# -# GlusterSP is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published -# by the Free Software Foundation; either version 3 of the License, -# or (at your option) any later version. -# -# GlusterSP is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import sys -import syslog - -def log(priority, message=None): - if type(priority) == type(""): - logPriority = syslog.LOG_INFO - logMessage = priority - else: - logPriority = priority - logMessage = message - if not logMessage: - return - #if Globals.DEBUG: - # sys.stderr.write(logMessage) - else: - syslog.syslog(logPriority, logMessage) - return - - -def stripEmptyLines(content): - ret = "" - for line in content.split("\n"): - if line.strip() != "": - ret += line - return ret - diff --git a/src/com.gluster.storage.management.server.scripts/src/common/DiskUtils.py b/src/com.gluster.storage.management.server.scripts/src/common/DiskUtils.py deleted file mode 100644 index 0e42bba2..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/common/DiskUtils.py +++ /dev/null @@ -1,226 +0,0 @@ -# Copyright (c) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import os -import glob -import dbus - -import Globals -from Utils import * - -ONE_MB_SIZE = 1048576 - - -def _stripDev(device): - if isString(device) and device.startswith("/dev/"): - return device[5:] - return device - - -def _addDev(deviceName): - if isString(deviceName) and not deviceName.startswith("/dev/"): - return "/dev/" + deviceName - return deviceName - - -def getDeviceName(device): - if type(device) == type([]): - nameList = [] - for d in device: - nameList.append(_stripDev(d)) - return nameList - return _stripDev(device) - - -def getDevice(deviceName): - if isString(deviceName): - return _addDev(deviceName) - if type(deviceName) == type([]): - nameList = [] - for d in deviceName: - nameList.append(_addDev(d)) - return nameList - return _addDev(deviceName) - - -def getDiskPartitionByUuid(uuid): - uuidFile = "/dev/disk/by-uuid/%s" % uuid - if os.path.exists(uuidFile): - return getDeviceName(os.path.realpath(uuidFile)) - return None - - -def getUuidByDiskPartition(device): - for uuidFile in glob.glob("/dev/disk/by-uuid/*"): - if os.path.realpath(uuidFile) == device: - return os.path.basename(uuidFile) - return None - - -def getDiskPartitionUuid(partition): - log("WARNING: getDiskPartitionUuid() is deprecated by getUuidByDiskPartition()") - return getUuidByDiskPartition(partition) - - -def getDiskPartitionByLabel(label): - ## TODO: Finding needs to be enhanced - labelFile = "/dev/disk/by-label/%s" % label - if os.path.exists(labelFile): - return getDeviceName(os.path.realpath(labelFile)) - return None - - -def getDeviceByLabel(label): - log("WARNING: getDeviceByLabel() is deprecated by getDiskPartitionByLabel()") - return getDiskPartitionByLabel(label) - - -def getDiskPartitionLabel(device): - rv = runCommandFG(["sudo", "e2label", device], stdout=True) - if rv["Status"] == 0: - return rv["Stdout"].strip() - return False - - -def getRootPartition(fsTabFile=Globals.FSTAB_FILE): - fsTabEntryList = readFsTab(fsTabFile) - for fsTabEntry in fsTabEntryList: - if fsTabEntry["MountPoint"] == "/": - if fsTabEntry["Device"].startswith("UUID="): - return getDiskPartitionByUuid(fsTabEntry["Device"].split("UUID=")[-1]) - if fsTabEntry["Device"].startswith("LABEL="): - return getDiskPartitionByLabel(fsTabEntry["Device"].split("LABEL=")[-1]) - return getDeviceName(fsTabEntry["Device"]) - return None - - -def getOsDisk(): - log("WARNING: getOsDisk() is deprecated by getRootPartition()") - return getRootPartition() - - -def getDiskList(diskDeviceList=None): - diskDeviceList = getDevice(diskDeviceList) - if isString(diskDeviceList): - diskDeviceList = [diskDeviceList] - - dbusSystemBus = dbus.SystemBus() - halObj = dbusSystemBus.get_object("org.freedesktop.Hal", - "/org/freedesktop/Hal/Manager") - halManager = dbus.Interface(halObj, "org.freedesktop.Hal.Manager") - storageUdiList = halManager.FindDeviceByCapability("storage") - - diskList = [] - for udi in storageUdiList: - halDeviceObj = dbusSystemBus.get_object("org.freedesktop.Hal", udi) - halDevice = dbus.Interface(halDeviceObj, - "org.freedesktop.Hal.Device") - if halDevice.GetProperty("storage.drive_type") == "cdrom" or \ - halDevice.GetProperty("block.is_volume"): - continue - - disk = {} - disk["Device"] = str(halDevice.GetProperty('block.device')) - if diskDeviceList and disk["Device"] not in diskDeviceList: - continue - disk["Description"] = str(halDevice.GetProperty('storage.vendor')) + " " + str(halDevice.GetProperty('storage.model')) - if halDevice.GetProperty('storage.removable'): - disk["Size"] = long(halDevice.GetProperty('storage.removable.media_size')) - else: - disk["Size"] = long(halDevice.GetProperty('storage.size')) - disk["Interface"] = str(halDevice.GetProperty('storage.bus')) - disk["DriveType"] = str(halDevice.GetProperty('storage.drive_type')) - partitionList = [] - partitionUdiList = halManager.FindDeviceStringMatch("info.parent", udi) - for partitionUdi in partitionUdiList: - partitionHalDeviceObj = dbusSystemBus.get_object("org.freedesktop.Hal", - partitionUdi) - partitionHalDevice = dbus.Interface(partitionHalDeviceObj, - "org.freedesktop.Hal.Device") - if not partitionHalDevice.GetProperty("block.is_volume"): - continue - partition = {} - partition["Device"] = str(partitionHalDevice.GetProperty('block.device')) - partition["Uuid"] = str(partitionHalDevice.GetProperty('volume.uuid')) - partition["Size"] = long(partitionHalDevice.GetProperty('volume.size')) - partition["Fstype"] = str(partitionHalDevice.GetProperty('volume.fstype')) - partition["Fsversion"] = str(partitionHalDevice.GetProperty('volume.fsversion')) - partition["Label"] = str(partitionHalDevice.GetProperty('volume.label')) - partition["Used"] = 0L - if partitionHalDevice.GetProperty("volume.is_mounted"): - rv = runCommandFG(["df", str(partitionHalDevice.GetProperty('volume.mount_point'))], stdout=True) - if rv["Status"] == 0: - try: - partition["Used"] = long(rv["Stdout"].split("\n")[1].split()[2]) - except IndexError: - pass - except ValueError: - pass - partitionList.append(partition) - disk["Partitions"] = partitionList - diskList.append(disk) - return diskList - -def readFsTab(fsTabFile=Globals.FSTAB_FILE): - try: - fsTabfp = open(fsTabFile) - except IOError, e: - Utils.log("readFsTab(): " + str(e)) - return None - - fsTabEntryList = [] - for line in fsTabfp: - tokens = line.strip().split() - if not tokens or tokens[0].startswith('#'): - continue - fsTabEntry = {} - fsTabEntry["Device"] = None - fsTabEntry["MountPoint"] = None - fsTabEntry["FsType"] = None - fsTabEntry["Options"] = None - fsTabEntry["DumpOption"] = 0 - fsTabEntry["fsckOrder"] = 0 - try: - fsTabEntry["Device"] = tokens[0] - fsTabEntry["MountPoint"] = tokens[1] - fsTabEntry["FsType"] = tokens[2] - fsTabEntry["Options"] = tokens[3] - fsTabEntry["DumpOption"] = tokens[4] - fsTabEntry["fsckOrder"] = tokens[5] - except IndexError: - pass - if fsTabEntry["Device"] and fsTabEntry["MountPoint"] and fsTabEntry["FsType"] and fsTabEntry["Options"]: - fsTabEntryList.append(fsTabEntry) - - fsTabfp.close() - return fsTabEntryList - - -def getMountPointByUuid(partitionUuid): - # check uuid in etc/fstab - try: - fstabEntries = open(Globals.FSTAB_FILE).readlines() - except IOError: - fstabEntries = [] - found = False - for entry in fstabEntries: - entry = entry.strip() - if not entry: - continue - if entry.split()[0] == "UUID=" + partitionUuid: - return entry.split()[1] - return None diff --git a/src/com.gluster.storage.management.server.scripts/src/common/Globals.py b/src/com.gluster.storage.management.server.scripts/src/common/Globals.py deleted file mode 100644 index 9ae53491..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/common/Globals.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright (C) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -MULTICAST_GROUP = '224.224.1.1' -MULTICAST_PORT = 5353 -GLUSTER_PLATFORM_VERSION = "3.2" - -## System configuration constants -SYSCONFIG_NETWORK_DIR = "/etc/sysconfig/network-scripts" -DNSMASQ_CONF_DIR = "/etc/dnsmasq.d" - -FSTAB_FILE = "/etc/fstab" -NFS_EXPORTS_FILE = "/etc/exports" -SAMBA_CONF_FILE = "/etc/samba/smb.conf" -TIMEZONE_FILE = "/etc/timezone" -ZONEINFO_DIR = "/usr/share/zoneinfo" -LOCALTIME_FILE = "/etc/localtime" -KERBEROS_CONF_FILE = "/etc/krb5.conf" -NSSWITCH_CONF_FILE = "/etc/nsswitch.conf" -NTP_CONF_FILE = "/etc/ntp.conf" -MODPROBE_CONF_FILE = "/etc/modprobe.d/bonding.conf" -SYSCONFIG_NETWORK_FILE = "/etc/sysconfig/network" -RESOLV_CONF_FILE = "/etc/resolv.conf" -DNSMASQ_LEASE_FILE = "/var/tmp/dnsmasq.leases" -LIVE_MODE_FILE = "/etc/live" -ADD_SERVER_COMPLETED_FILE = "/var/tmp/installation-completed" - -DNSMASQ_DNS_CONF_FILE = DNSMASQ_CONF_DIR + "/dns.conf" -DNSMASQ_DHCP_CONF_FILE = DNSMASQ_CONF_DIR + "/dhcp.conf" -## - -## Base constants -MAX_PARTITION_SIZE = 16777216 # 16 TB -OS_PARTITION_SIZE = 4000 # 4 GB -SESSION_TIMEOUT = 1800 # 30 minutes -SERVER_AGENT_PORT = 50000 - -BOOT_PARTITION_LABEL = "GLUSTEROS" -DATA_PARTITION_LABEL = "GLUSTERDATA" -VOLUME_USER_DESCRIPTION = "Gluster Volume User" -SERVER_AGENT_RUN_USERNAME = "gluster" -INSTALLER_SERVER_NAME = "$installer$" - -GLUSTER_BASE_DIR = "/GLUSTER" -GLUSTER_LUN_DIR = "/data" -REEXPORT_DIR = "/reexport" -NFS_EXPORT_DIR = "/nfs" -CIFS_EXPORT_DIR = "/cifs" -WEBDAV_DOCUMENT_ROOT_DIR = "/var/www/html" -UPDATES_DIR = "/UPDATES" -TRANSPORT_HOME_DIR = "/transport" -GLUSTERFS_LOG_DIR = "/var/log/glusterfs" -LOG_DIR = "/var/log/glustermc" - -GLUSTER_UPDATES_FILE = "updates.xml" -INSTALLER_STATUS_FILE = "/var/log/install-server-status.log" -INSTALL_PLATFORM_LOCK_FILE = "/var/lock/install-gluster-platform.lock" -LAST_ACCESSED_NETWORK_FILE = "last-accessed-network" -PREPARE_DATA_DISK_LOCK_FILE = "/var/tmp/prepare-data-disk.lock" -## - -## Derived constants -GLUSTER_CONF_DIR = GLUSTER_BASE_DIR + "/conf" -GLUSTER_TMP_DIR = GLUSTER_BASE_DIR + "/tmp" -VOLUME_CONF_DIR = GLUSTER_BASE_DIR + "/volumes" -SERVER_CONF_DIR = GLUSTER_BASE_DIR + "/servers" -DNS_RECORDS_DIR = GLUSTER_BASE_DIR + "/dns-records" -INSTALLER_CONF_DIR = SERVER_CONF_DIR + "/" + INSTALLER_SERVER_NAME - -GSN_USER_INFO_FILE = GLUSTER_BASE_DIR + "/gsn-user.info" -GLUSTER_VERSION_FILE = GLUSTER_BASE_DIR + "/version" -GLUSTER_UPDATE_SITE_FILE = GLUSTER_BASE_DIR + "/update-site" -GLUSTER_DIRECTORY_SERVICE_CONF_FILE = GLUSTER_BASE_DIR + "/directory.xml" -GLUSTER_TIME_CONF_FILE = GLUSTER_BASE_DIR + "/timeconfig.xml" -TRANSACTION_KEY_FILE = GLUSTER_BASE_DIR + "/transaction.key" -SERVER_COUNT_FILE = GLUSTER_BASE_DIR + "/server-count" -SIGNATURE_FILE = GLUSTER_BASE_DIR + "/.signature" -GLUSTER_SERVER_POOL_FILE = GLUSTER_BASE_DIR + "/pool" -GLUSTER_ADMIN_FILE = GLUSTER_BASE_DIR + "/.password" - -VOLUME_SMBCONF_FILE = VOLUME_CONF_DIR + "/volumes.smbconf.list" - -GLOBAL_NETWORK_FILE = INSTALLER_CONF_DIR + "/network.xml" -INSTALL_SERVER_CONF_FILE = INSTALLER_CONF_DIR + "/installer.xml" -INSTALLER_INFO_FILE = INSTALLER_CONF_DIR + "/installer.info" -INSTALLED_SERVER_COUNT_FILE = INSTALLER_CONF_DIR + "/installed-server-count" - -SESSION_FILE = GLUSTER_TMP_DIR + "/login.sessions" - -GENERAL_LOG_FILE = LOG_DIR + "/general.log" -INSTALLER_LOG_FILE = LOG_DIR + "/installer.log" -PEER_AGENT_LOG_FILE = LOG_DIR + "/peeragent.log" -SERVER_AGENT_LOG_FILE = LOG_DIR + "/serveragent.log" -TRANSPORT_AGENT_LOG_FILE = LOG_DIR + "/transport.log" -## - - -## Global variables -## TODO: These should be removed -DOWNLOAD_GLUSTER_UPDATE_PROCESS = None -DOWNLOAD_GLUSTER_UPDATE_LEVEL = None -DOWNLOAD_GLUSTER_CURRENT_UPDATE_LEVEL = None -DOWNLOAD_GLUSTER_UPDATE_MD5SUM = None -REQUEST_MAP = {} -VERSION_DICTONARY = {} -## diff --git a/src/com.gluster.storage.management.server.scripts/src/common/NetworkUtils.py b/src/com.gluster.storage.management.server.scripts/src/common/NetworkUtils.py deleted file mode 100755 index 7a854564..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/common/NetworkUtils.py +++ /dev/null @@ -1,450 +0,0 @@ -# Copyright (c) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import sys - -if not "/usr/share/system-config-network/" in sys.path: - sys.path.append("/usr/share/system-config-network") - -import os -import tempfile -import Globals - -from Utils import * -#from netconfpkg.NCHardwareList import getHardwareList - -def readHostFile(fileName=None): - hostEntryList = [] - if not fileName: - fileName = "/etc/hosts" - try: - for line in open(fileName): - tokens = line.split("#")[0].strip().split() - if len(tokens) < 2: - continue - hostEntryList.append({tokens[0] : tokens[1:]}) - return hostEntryList - except IOError: - log("failed to read %s file" % fileName) - return None - - -def writeHostFile(hostEntryList, fileName=None): - if fileName: - hostFile = fileName - else: - hostFile = tempfile.mktemp(prefix="GSPSA") - try: - fp = open(hostFile, "w") - for host in hostEntryList: - fp.write("%s\t%s\n" % (host.keys()[0], " ".join(host.values()[0]))) - fp.close() - if hostFile == fileName: - return True - except IOError: - log("failed to write %s file" % hostFile) - return False - if runCommandFG("mv -f %s /etc/hosts" % hostFile, root=True) != 0: - log("failed to rename file %s to /etc/hosts" % hostFile) - return False - return True - - -def readResolvConfFile(fileName=None, includeLocalHost=False): - nameServerList = [] - domain = None - searchDomain = None - if not fileName: - fileName = Globals.RESOLV_CONF_FILE - try: - for line in open(fileName): - tokens = line.split("#")[0].strip().split() - if len(tokens) < 2: - continue - if tokens[0].upper() == "NAMESERVER": - if includeLocalHost == False and tokens[1] == "127.0.0.1": - continue - nameServerList.append(tokens[1]) - continue - if tokens[0].upper() == "DOMAIN": - domain = tokens[1:] - continue - if tokens[0].upper() == "SEARCH": - searchDomain = tokens[1:] - continue - return nameServerList, domain, searchDomain - except IOError: - log("failed to read %s file" % fileName) - return None, None, None - - -def writeResolvConfFile(nameServerList, domain, searchDomain, fileName=None, appendLocalHost=True): - if fileName: - resolvConfFile = fileName - else: - resolvConfFile = tempfile.mktemp(prefix="GSPSA") - try: - fp = open(resolvConfFile, "w") - if appendLocalHost: - fp.write("nameserver 127.0.0.1\n") - for nameServer in nameServerList: - fp.write("nameserver %s\n" % nameServer) - if domain: - fp.write("domain %s\n" % " ".join(domain)) - if searchDomain: - fp.write("search %s\n" % " ".join(searchDomain)) - fp.close() - if resolvConfFile == fileName: - return True - except IOError: - log("failed to write %s file" % resolvConfFile) - return False - if runCommandFG("mv -f %s %s" % (resolvConfFile, Globals.RESOLV_CONF_FILE), root=True) != 0: - log("failed to rename file %s to %s" % (resolvConfFile, Globals.RESOLV_CONF_FILE)) - return False - return True - - -def readIfcfgConfFile(deviceName, root=""): - conf = {} - fileName = "%s%s/ifcfg-%s" % (root, Globals.SYSCONFIG_NETWORK_DIR, deviceName) - try: - for line in open(fileName): - tokens = line.split("#")[0].split("=") - if len(tokens) != 2: - continue - conf[tokens[0].strip().lower()] = tokens[1].strip() - return conf - except IOError: - log("failed to read %s file" % fileName) - return None - - -def writeIfcfgConfFile(deviceName, conf, root="", deviceFile=None): - if not deviceFile: - deviceFile = "%s%s/ifcfg-%s" % (root, Globals.SYSCONFIG_NETWORK_DIR, deviceName) - if root: - ifcfgConfFile = deviceFile - else: - ifcfgConfFile = tempfile.mktemp(prefix="GSPSA") - try: - fp = open(ifcfgConfFile, "w") - for key in conf.keys(): - if key == "description": - fp.write("#%s=%s\n" % (key.upper(), conf[key])) - continue - if key in ['link', 'mode']: - continue - if conf["device"].startswith("bond") and key in ['hwaddr', 'master', 'slave']: - continue - if key == "slave" and conf['master']: - fp.write("SLAVE=yes\n") - continue - if key == "onboot": - if conf[key] == True: - fp.write("ONBOOT=yes\n") - elif isString(conf[key]) and conf[key].upper() == "YES": - fp.write("ONBOOT=yes\n") - else: - fp.write("ONBOOT=no\n") - continue - if not conf[key]: - continue - fp.write("%s=%s\n" % (key.upper(), conf[key])) - fp.close() - if ifcfgConfFile == deviceFile: - return True - except IOError: - log("failed to write %s file" % ifcfgConfFile) - return False - if runCommandFG("mv -f %s %s" % (ifcfgConfFile, deviceFile), root=True) != 0: - log("failed to rename file %s to %s" % (ifcfgConfFile, deviceFile)) - return False - return True - - -def getNetModel(deviceName): - rv = runCommandFG("ifconfig %s" % deviceName, stdout=True, root=True) - if rv["Status"] != 0: - return False - for line in rv["Stdout"].split(): - tokens = line.strip().split(":") - if tokens[0].upper() == "ENCAP": - return tokens[1].strip().upper() - return None - -def getNetSpeed(deviceName): - rv = runCommandFG("ethtool %s" % deviceName, stdout=True, root=True) - if rv["Status"] != 0: - return False - for line in rv["Stdout"].split("\n"): - tokens = line.strip().split(":") - if tokens[0].upper() == "SPEED": - return tokens[1].strip().upper() - return None - -def getLinkStatus(deviceName): - return True - ## ethtool takes very long time to respond. So its disabled now - rv = runCommandFG("ethtool %s" % deviceName, stdout=True, root=True) - if rv["Status"] != 0: - return False - for line in rv["Stdout"].split("\n"): - tokens = line.strip().split(":") - if tokens[0].upper() == "LINK DETECTED": - if tokens[1].strip().upper() == "YES": - return True - else: - return False - return False - - -def getBondMode(deviceName, fileName=None): - if not fileName: - fileName = Globals.MODPROBE_CONF_FILE - try: - for line in open(fileName): - tokens = line.split("#")[0].split() - if len(tokens) < 4: - continue - if tokens[0].upper() == "OPTIONS" and tokens[1] == deviceName: - if tokens[2].startswith("mode="): - return tokens[2].split("=")[1] - if tokens[3].startswith("mode="): - return tokens[3].split("=")[1] - if tokens[4].startswith("mode="): - return tokens[4].split("=")[1] - if tokens[5].startswith("mode="): - return tokens[5].split("=")[1] - return None - except IOError: - log("failed to read %s file" % fileName) - return None - - -def setBondMode(deviceName, mode, fileName=None): - if not fileName: - fileName = Globals.MODPROBE_CONF_FILE - tempFileName = getTempFileName() - try: - fp = open(tempFileName, "w") - lines = open(fileName).readlines() - except IOError: - log("unable to open file %s" % Globals.MODPROBE_CONF_FILE) - return False - for line in lines: - tokens = line.split() - if len(tokens) > 1 and "OPTIONS" == tokens[0].upper() and "BOND" in tokens[1].upper() and deviceName == tokens[1]: - fp.write("options %s max_bonds=2 mode=%s miimon=100\n" % (deviceName, mode)) - deviceName = None - continue - fp.write(line) - if deviceName: - fp.write("alias %s bonding\n" % deviceName) - fp.write("options %s max_bonds=2 mode=%s miimon=100\n" % (deviceName, mode)) - fp.close() - if runCommandFG(["mv", "-f", tempFileName, fileName], root=True) != 0: - log("unable to move file from %s to %s" % (tempFileName, fileName)) - return False - return True - -def getNetDeviceList(root=""): - netDeviceList = [] - - for deviceName in os.listdir("/sys/class/net/"): - #for device in getHardwareList(): - netDevice = {} - netDevice["device"] = None - netDevice["description"] = None - netDevice["hwaddr"] = None - netDevice["type"] = None - netDevice["onboot"] = None - netDevice["bootproto"] = None - netDevice["ipaddr"] = None - netDevice["netmask"] = None - netDevice["gateway"] = None - netDevice["peerdns"] = None - netDevice["autodns"] = None - netDevice["dns1"] = None - netDevice["dns2"] = None - netDevice["dns3"] = None - netDevice["master"] = None - netDevice["slave"] = None - netDevice["nmcontrolled"] = None - netDevice["link"] = None - netDevice["mode"] = None - - #netDevice["device"] = device.Name - netDevice["device"] = deviceName - #netDevice["description"] = device.Description - netDevice["description"] = deviceName - #netDevice["type"] = device.Type - netDevice["type"] = None - netDevice["link"] = getLinkStatus(deviceName) - 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) - if not conf: - continue - try: - netDevice["onboot"] = conf["onboot"] - except KeyError: - pass - try: - netDevice["bootproto"] = conf["bootproto"] - except KeyError: - pass - try: - netDevice["ipaddr"] = conf["ipaddr"] - except KeyError: - pass - try: - netDevice["netmask"] = conf["netmask"] - except KeyError: - pass - try: - netDevice["gateway"] = conf["gateway"] - except KeyError: - pass - try: - netDevice["peerdns"] = conf["peerdns"] - except KeyError: - pass - try: - netDevice["autodns"] = conf["autodns"] - except KeyError: - pass - try: - netDevice["dns1"] = conf["dns1"] - except KeyError: - pass - try: - netDevice["dns2"] = conf["dns2"] - except KeyError: - pass - try: - netDevice["dns3"] = conf["dns3"] - except KeyError: - pass - try: - netDevice["master"] = conf["master"] - except KeyError: - pass - try: - netDevice["slave"] = conf["slave"] - except KeyError: - pass - try: - netDevice["nmcontrolled"] = conf["nmcontrolled"] - except KeyError: - pass - - return netDeviceList - - ## bondDevices = [os.path.basename(device) for device in glob.glob("/sys/class/net/bond*")] - - ## bondDevices = [os.path.basename(device) for device in glob.glob("/sys/class/net/bond*")] - ## for deviceName in bondDevices: - ## if deviceName in linkedBondList: - ## if deviceName in sysConfigDeviceList: - ## deviceList[deviceName] = sysConfigDeviceList[deviceName] - ## else: - ## deviceList[deviceName] = {'device':deviceName, 'onboot':'no', 'bootproto':'none'} - ## continue - ## if len(ethDevices) > 2: - ## deviceList[deviceName] = {'device':deviceName, 'onboot':'no', 'bootproto':'none'} - - -def configureDhcpServer(serverIpAddress, dhcpIpAddress): - tmpDhcpConfFile = tempfile.mktemp(prefix="GSPSA") - - 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(tmpDhcpConfFile, "w") - 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-alternate-port=%s\n" % serverPort) - fp.write("dhcp-leasefile=%s\n" % Globals.DNSMASQ_LEASE_FILE) - #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 dhcp configuration %s" % tmpDhcpConfFile) - return False - if runCommandFG("mv -f %s %s" % (tmpDhcpConfFile, Globals.DNSMASQ_DHCP_CONF_FILE), root=True) != 0: - log(syslog.LOG_ERR, "unable to copy dnsmasq dhcp configuration to %s" % Globals.DNSMASQ_DHCP_CONF_FILE) - return False - return True - - -def isDhcpServer(): - return os.path.exists(Globals.DNSMASQ_DHCP_CONF_FILE) - - -def getDhcpServerStatus(): - if runCommandFG("service dnsmasq status", root=True) == 0: - return True - return False - - -def startDhcpServer(): - if runCommandFG("service dnsmasq start", root=True) == 0: - return True - return False - - -def stopDhcpServer(): - if runCommandFG("service dnsmasq stop", root=True) == 0: - runCommandFG("rm -f %s" % Globals.DNSMASQ_LEASE_FILE, root=True) - return True - return False - - -def restartDhcpServer(): - stopDhcpServer() - runCommandFG("rm -f %s" % Globals.DNSMASQ_LEASE_FILE, root=True) - return startDhcpServer() - - -def reloadDhcpServer(): - if runCommandFG("service dnsmasq reload", root=True) == 0: - return True - return False diff --git a/src/com.gluster.storage.management.server.scripts/src/common/Protocol.py b/src/com.gluster.storage.management.server.scripts/src/common/Protocol.py deleted file mode 100644 index ff073593..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/common/Protocol.py +++ /dev/null @@ -1,438 +0,0 @@ -# Copyright (C) 2009 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import xml -import xml.parsers.expat -import xml.dom.minidom as MDOM -import os -import Globals -import copy -import Utils - -XML_STRING = 0 -XML_FILE = 1 - -class XDOM: - _domObj = None - - def __init__(self): - self._domObj = MDOM.Document() - return - - @classmethod - def getText(self, nodeList): - rc = "" - for node in nodeList: - if node.nodeType == node.TEXT_NODE: - rc = rc + node.data - return rc.strip() - - def parseString(self, requestString): - try: - self._domObj = MDOM.parseString(requestString) - except xml.parsers.expat.ExpatError, e: - Utils.log("XML string parse error: %s" % str(e)) - return False - return True - - def parseFile(self, fileName): - try: - self._domObj = MDOM.parse(fileName) - except IOError, e: - Utils.log("error reading file: %s" % str(e)) - return False - except xml.parsers.expat.ExpatError, e: - Utils.log("XML file %s parse error: %s" % (fileName, str(e))) - return False - return True - - def setDomObj(self, dom): - if dom and type(dom) != type([]): - self._domObj = dom - return True - return False - - def createTextNode(self, text): - if not self._domObj: - return False - if not text: - return False - return self._domObj.createTextNode(str(text)) - - def createTag(self, tag, text=None): - if not self._domObj: - return None - if tag == None: - return None - - tagE = self._domObj.createElement(str(tag)) - if text: - tagEText = self._domObj.createTextNode(str(text)) - tagE.appendChild(tagEText) - return tagE - - def addTag(self, tag): - if not self._domObj: - return False - if not tag: - return False - - self._domObj.appendChild(tag) - return True - - def createTagRoute(self, tagRoute, text=None): - if not tagRoute: - return False - - tagList = tagRoute.split(".") - tag = None - previousTag = None - for tagName in tagList[:-1]: - newTag = self.createTag(tagName, None) - if not tag: - tag = newTag - previousTag = newTag - continue - previousTag.appendChild(newTag) - previousTag = newTag - - if previousTag: - previousTag.appendChild(self.createTag(tagList[-1], text)) - else: - tag = self.createTag(tagList[-1], text) - return tag - - def appendTagRoute(self, tagRoute, value=None): - if not self._domObj: - return False - if not tagRoute: - return False - - parentTagE = self._domObj - - tagNameList = tagRoute.split(".") - newTagRoute = tagNameList.pop(-1) - - for i in range(len(tagNameList), 0, -1): - tagE = self.getElementsByTagRoute(".".join(tagNameList[:i])) - if tagE: - parentTagE = tagE[0] - break - newTagRoute = tagNameList[i-1] + "." + newTagRoute - - newTagE = self.createTagRoute(newTagRoute, value) - if not newTagE: - return False - try: - parentTagE.appendChild(newTagE) - except xml.dom.HierarchyRequestErr, e: - Utils.log("error occured. %s" + str(e)) - return False - return True - - def setTextByTagRoute(self, tagRoute, tagValue): - if not self._domObj: - return None - - if not tagRoute: - return None - - tagE = self.getElementsByTagRoute(tagRoute) - if not tagE: - return False - - parentTagE = self.getElementsByTagRoute(".".join(tagRoute.split(".")[:-1])) - if not parentTagE: - return False - - parentTagE[0].childNodes.remove(tagE[0]) - parentTagE[0].appendChild(self.createTag(tagRoute.split(".")[-1], tagValue)) - return True - - def getElementsByTagRoute(self, tagRoute): - if not self._domObj: - return None - - if not tagRoute: - return None - - x = None - for tag in tagRoute.split("."): - if x is None: - x = self._domObj.getElementsByTagName(tag) - continue - if x == []: - break - x = x[0].getElementsByTagName(tag) - return x - - def getTextByTagRoute(self, tagRoute): - if not self._domObj: - return None - - x = self.getElementsByTagRoute(tagRoute) - if x: - return self.getText(x[0].childNodes) - return None - - def getElementsByTagName(self, name): - if not self._domObj: - return None - return self._domObj.getElementsByTagName(name) - - def writexml(self, fileName, indent="", addindent="", newl=""): - if not self._domObj: - return None - try: - fp = open(fileName, "w") - self._domObj.writexml(fp, indent, addindent, newl) - fp.close() - return True - except IOError: - return False - - def toString(self, indent=" ", newl="\n", encoding = None): - if not self._domObj: - return None - return self._domObj.toprettyxml(indent, newl, encoding) - - def toxml(self, encoding = None): - if not self._domObj: - return None - return self._domObj.toxml(encoding) - - def toprettyxml(self, indent=" ", newl="\n", encoding = None): - return self.toString(indent, newl, encoding) - - def getAttribute(self, attributeName): - if not attributeName: - return None - try: - return self.getElementsByTagName("command")[0].getAttribute(attributeName) - except IndexError: - return False - - def setAttribute(self, attributeName, attributeValue): - if not (attributeName and attributeValue): - return None - try: - return self.getElementsByTagName("command")[0].setAttribute(attributeName, attributeValue) - except IndexError: - return False - - def getRequestCommand(self): - return self.getAttribute("request") - - def getResponseCommand(self): - return self.getAttribute("response") - - def getResponseCode(self): - return self.getAttribute("response-code") - - def getMessageId(self): - return self.getAttribute("id") - - def getVersion(self): - return self.getAttribute("version") - - def getRequestAction(self): - return self.getAttribute("action") - - def setVersion(self, value): - return self.setAttribute("version", value) - - def setRequestAction(self, value): - return self.setAttribute("action", value) - - def createCommandTag(self, command, responseCode, id, version=Globals.GLUSTER_PLATFORM_VERSION): - commandTag = self._domObj.createElement("command") - commandTag.setAttribute("response", command) - commandTag.setAttribute("response-code", responseCode) - commandTag.setAttribute("id", id) - commandTag.setAttribute("version", version) - return commandTag -##--end of XDOM - -class RequestXml(XDOM): - def __init__(self, requestString, type=None): - if None == requestString: - XDOM.__init__(self) - return - try: - if None == type: - if os.path.isfile(requestString): - self._domObj = MDOM.parse(requestString) - else: - self._domObj = MDOM.parseString(requestString) - elif XML_FILE == type: - self._domObj = MDOM.parse(requestString) - elif XML_STRING == type: - self._domObj = MDOM.parseString(requestString) - except IOError: - XDOM.__init__(self) - except xml.parsers.expat.ExpatError: - XDOM.__init__(self) - -##--end of RequestXML - -class ResponseXml(XDOM): - _commandTag = None - def __init__(self, command, responseCode, id, version=Globals.GLUSTER_PLATFORM_VERSION): - XDOM.__init__(self) - if command and responseCode and id: - self._commandTag = self.createCommandTag(command, responseCode, id, version) - self._domObj.appendChild(self._commandTag) - - def appendCommand(self, command, responseCode, id, version=Globals.GLUSTER_PLATFORM_VERSION): - if command and responseCode and id: - self._commandTag = self.createCommandTag(command, responseCode, id, version) - self._domObj.appendChild(self._commandTag) - return True - return False - - def append(self, tagName, tagValue=None): - if not self._commandTag: - return False - tag = self.createTag(tagName, tagValue) - if tag: - self._commandTag.appendChild(tag) - return True - return False - - def appendTag(self, tag): - if not tag: - return False - if not self._commandTag: - return False - self._commandTag.appendChild(tag) - return True - - def appendTagRoute(self, tagRoute, value=None): - if not self._commandTag: - return False - if not tagRoute: - return False - - parentTagE = self._commandTag - - tagNameList = tagRoute.split(".") - newTagRoute = tagNameList.pop(-1) - - for i in range(len(tagNameList), 0, -1): - tagE = self.getElementsByTagRoute(".".join(["command"] + tagNameList[:i])) - if tagE: - parentTagE = tagE[0] - break - newTagRoute = tagNameList[i-1] + "." + newTagRoute - - newTagE = self.createTagRoute(newTagRoute, value) - if not newTagE: - return False - try: - parentTagE.appendChild(newTagE) - except xml.dom.HierarchyRequestErr, e: - Utils.log("error occured. %s" + str(e)) - return False - return True - - def appendTagRouteOld(self, tagRoute, value=None): - if not tagRoute: - return False - if not self._commandTag: - return False - - tmpTagRoute = "" - previousTagE = self._commandTag - tagE = None - for tagName in tagRoute.split("."): - if not tmpTagRoute: - tagE = self.getElementsByTagRoute("command." + tagName) - else: - tagE = self.getElementsByTagRoute("command." + tmpTagRoute + "." + tagName) - if not tagE: - break - if len(tagE) != 1: - return False - previousTagE = tagE[0] - if not tmpTagRoute: - tmpTagRoute = tagName - else: - tmpTagRoute = tmpTagRoute + "." + tagName - - if tmpTagRoute == tagRoute: - return False - newTagRoute = tagRoute[len(tmpTagRoute):] - if newTagRoute[0] == '.': - newTagRoute = newTagRoute[1:] - - if previousTagE.childNodes and previousTagE.childNodes[0].nodeType == previousTagE.TEXT_NODE: - return False - previousTagE.appendChild(self.createTagRoute(newTagRoute, value)) - return True -##--end of ResponseXml - -def test(): - #volumes = RequestXml(VolumeFile, XML_FILE).getElementsByTagRoute("volume-list.volume") - requestStr = ''' - -movies1 -cluster mirror -512000 -zresearch -192.168.20.* -192.168.30.* - -no - - -no - - -no - - -''' - - requestXml = RequestXml(requestStr) - print requestXml.getAttribute("") - -def test1(): - rs = ResponseXml("create-volume", "OK", "xyz") - rs.appendTagRoute("volume.detail.name", "music") - print rs.toprettyxml() - rs.append("volume", "data") - print rs.toprettyxml() - rs.appendTagRoute("volume.detail.ipaddr", "192.168.10.1") - print rs.toprettyxml() - print rs.appendTagRoute("volume.detail.ipaddr.v6", "ff:ff::ff::") - print rs.toprettyxml() - - print rs.getTextByTagRoute("command.volume.detail") - -def test2(): - rs = ResponseXml("download-volume-logs", "OK", "xyz") - te = rs.createTag("interface", None) - te.appendChild(rs.createTag("device", "DEVICE1")) - te.appendChild(rs.createTag("description", "my device one")) - rs.appendTag(te) - - te = rs.createTag("interface", None) - te.appendChild(rs.createTag("device", "DEVICE2")) - te.appendChild(rs.createTag("description", "my device two")) - rs.appendTag(te) - print rs.toprettyxml() - diff --git a/src/com.gluster.storage.management.server.scripts/src/common/Utils.py b/src/com.gluster.storage.management.server.scripts/src/common/Utils.py deleted file mode 100644 index 5140b641..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/common/Utils.py +++ /dev/null @@ -1,703 +0,0 @@ -# Copyright (c) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import sys -import os -import re -import socket -import struct -import syslog -import subprocess -#import spwd -import time -#import uuid -import tempfile -import grp -import pwd -import inspect -from datetime import datetime -import urllib - -import Globals -import Protocol -from Common import * - -RUN_COMMAND_ERROR = -1024 -LOG_SYSLOG = 1 -SYSLOG_REQUIRED = False -LOG_FILE_NAME = None -LOG_FILE_OBJ = None - - -def _getLogCode(priority): - if syslog.LOG_EMERG == priority: - return "M" - elif syslog.LOG_ALERT == priority: - return "A" - elif syslog.LOG_CRIT == priority: - return "C" - elif syslog.LOG_ERR == priority: - return "E" - elif syslog.LOG_WARNING == priority: - return "W" - elif syslog.LOG_NOTICE == priority: - return "N" - elif syslog.LOG_INFO == priority: - return "I" - elif syslog.LOG_DEBUG == priority: - return "D" - else: # UNKNOWN - return "X" - - -def setLogFile(fileName): - global LOG_FILE_NAME - - if fileName: - LOG_FILE_NAME = fileName - return True - return False - - -def closeLog(): - global LOG_FILE_OBJ - global SYSLOG_REQUIRED - - if SYSLOG_REQUIRED: - syslog.closelog() - SYSLOG_REQUIRED = False - return True - - if LOG_FILE_OBJ: - try: - LOG_FILE_OBJ.close() - LOG_FILE_OBJ = None - except IOError, e: - sys.stderr.write("Failed to close file: %s\n" % e) - return False - return True - - -def openLog(fileName=None): - global LOG_FILE_NAME - global LOG_FILE_OBJ - global SYSLOG_REQUIRED - - if fileName == LOG_SYSLOG: - syslog.openlog(os.path.basename(sys.argv[0])) - SYSLOG_REQUIRED = True - return True - - if fileName: - LOG_FILE_NAME = fileName - - if not LOG_FILE_NAME: - return False - - closeLog() - - try: - LOG_FILE_OBJ = open(LOG_FILE_NAME, "a") - except IOError, e: - sys.stderr.write("Failed to open file %s: %s\n" % (LOG_FILE_NAME, e)) - return False - return True - -def record(priority, message=None): - global LOG_FILE_OBJ - global SYSLOG_REQUIRED - - stack = inspect.stack()[1] - if stack[3] == "": - prefix = "%s:%s:%s" % (stack[1], stack[2], stack[3]) - else: - prefix = "%s:%s:%s()" % (stack[1], stack[2], stack[3]) - - if type(priority) == type("") or type(priority) == type(u""): - logPriority = syslog.LOG_INFO - logMessage = priority - else: - logPriority = priority - logMessage = message - - if SYSLOG_REQUIRED: - syslog.syslog(logPriority, "[%s]: %s" % (prefix, logMessage)) - return - - fp = sys.stderr - if LOG_FILE_OBJ: - fp = LOG_FILE_OBJ - - fp.write("[%s] %s [%s]: %s" % (str(datetime.now()), _getLogCode(logPriority), prefix, logMessage)) - if logMessage[-1] != '\n': - fp.write("\n") - fp.flush() - return - - -def trace(message): - if message: - log(syslog.LOG_DEBUG, message) - - -def isString(value): - return (type(value) == type("") or type(value) == type(u"")) - - -def getTempFileName(): - return tempfile.mkstemp(prefix="GSP_")[1] - - -def runCommandBG(command, stdinFileObj=None, stdoutFileObj=None, stderrFileObj=None, - shell=False, root=None): - log("runCommandBG(): Trying to execute command [%s]" % command) - - if shell: - if not isString(command): - return None - else: - if isString(command): - command = command.split() - - if root == True: - if shell: - command = "sudo " + command - else: - command = ['sudo'] + command - elif isString(root): - if shell: - command = "sudo -u " + root + " " + command - else: - command = ['sudo', '-u', root] + command - - if not stdinFileObj: - stdinFileObj=subprocess.PIPE - if not stdoutFileObj: - stdoutFileObj=subprocess.PIPE - if not stderrFileObj: - stderrFileObj=subprocess.PIPE - - try: - process = subprocess.Popen(command, - bufsize=-1, - stdin=stdinFileObj, - stdout=stdoutFileObj, - stderr=stderrFileObj, - shell=shell) - return process - except OSError, e: - log("runCommandBG(): Failed to run command [%s]: %s" % (command, e)) - return None - - -def runCommand(command, - input='', output=False, - shell=False, root=None): - rv = {} - rv["Status"] = RUN_COMMAND_ERROR - rv["Stdout"] = None - rv["Stderr"] = None - - try: - stdinFileName = getTempFileName() - stdinFileObj = open(stdinFileName, "w") - stdinFileObj.write(input) - stdinFileObj.close() - stdinFileObj = open(stdinFileName, "r") - - stdoutFileName = getTempFileName() - stdoutFileObj = open(stdoutFileName, "w") - - stderrFileName = getTempFileName() - stderrFileObj = open(stderrFileName, "w") - except IOError, e: - log("Failed to create temporary file for executing command [%s]: %s" % (command, e)) - if output: - return rv - return rv["Status"] - - stdoutContent = None - stderrContent = None - - process = runCommandBG(command, - stdinFileObj=stdinFileObj, - stdoutFileObj=stdoutFileObj, - stderrFileObj=stderrFileObj, - shell=shell, root=root) - if process: - rv['Status'] = process.wait() - rv['Stdout'] = open(stdoutFileName).read() - rv['Stderr'] = open(stderrFileName).read() - - os.remove(stdinFileName) - os.remove(stdoutFileName) - os.remove(stderrFileName) - - log("runCommand(): execution status of command [%s] = [%s]" % (command, rv)) - - if output: - return rv - return rv["Status"] - - -def runCommandFG(command, stdout=False, stderr=False, - shell=False, root=None): - if stdout or stderr: - output = True - else: - output = False - return runCommand(command, output=output, shell=shell, root=root) - - -def IP2Number(ipString): - try: - return socket.htonl(struct.unpack("I", socket.inet_aton(ipString))[0]) - except socket.error: - return None - except TypeError: - return None - except struct.error: - return None - - -def Number2IP(number): - try: - return socket.inet_ntoa(struct.pack("I", socket.ntohl(number))) - except socket.error: - return None - except AttributeError: - return None - except ValueError: - return None - - -def computeHostName(hostName): - if not hostName: - return False - - hostPrefix = "" - for i in range(len(hostName), 0, -1): - pos = i - 1 - if hostName[pos].isdigit(): - continue - break - hostPrefix = hostName[:pos+1] - try: - hostIndex = int(hostName[pos+1:]) - except ValueError: - hostIndex = 0 - # TODO: Check the availablity of the (server) name - return "%s%s" % (hostPrefix, hostIndex + 1) - - -def daemonize(): - try: - pid = os.fork() - if pid > 0: - # exit first parent - sys.exit(0) - except OSError, e: - #sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) - return False - - # decouple from parent environment - os.chdir("/") - os.setsid() - os.umask(0) - - # do second fork - try: - pid = os.fork() - if pid > 0: - # exit from second parent - sys.exit(0) - except OSError, e: - #sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) - return False - - # redirect standard file descriptors - sys.stdout.flush() - sys.stderr.flush() - si = file("/dev/null", 'r') - so = file("/dev/null", 'a+') - se = file("/dev/null", 'a+', 0) - os.dup2(si.fileno(), sys.stdin.fileno()) - os.dup2(so.fileno(), sys.stdout.fileno()) - os.dup2(se.fileno(), sys.stderr.fileno()) - return True - - -def getDownloadStatus(fileName): - try: - lines = [line for line in open(fileName) - if "saved" in line or "%" in line] - except IOError: - return 0 - if not lines: - return 0 - if "saved" in lines[-1]: - return 100 - return lines[-1].split("%")[0].split()[-1] - - -def getMeminfo(): - """-> dict of data from meminfo (str:int). - Values are in kilobytes. - """ - import re - re_parser = re.compile(r'^(?P\S*):\s*(?P\d*)\s*kB' ) - result = {} - for line in open('/proc/meminfo'): - match = re_parser.match(line) - if not match: - continue # skip lines that don't parse - key, value = match.groups(['key', 'value']) - result[key] = int(value) - return result - - -def getCpuUsage(): - """-> dict of cpuid : (usertime, nicetime, systemtime, idletime) - cpuid "cpu" means the total for all CPUs. - cpuid "cpuN" means the value for CPU N. - """ - wanted_records = [line for line in open('/proc/stat') if - line.startswith('cpu')] - result = {} - for cpuline in wanted_records: - fields = cpuline.split()[:5] - data = map(int, fields[1:]) - result[fields[0]] = tuple(data) - return result - - -def getLoadavg(): - """-> 5-tuple containing the following numbers in order: - - 1-minute load average (float) - - 5-minute load average (float) - - 15-minute load average (float) - - Number of threads/processes currently executing (<= number of - CPUs) (int) - - Number of threads/processes that exist on the system (int) - - The PID of the most recently-created process on the system (int) - """ - loadavgstr = open('/proc/loadavg', 'r').readline().strip() - data = loadavgstr.split() - avg1, avg5, avg15 = map(float, data[:3]) - threads_and_procs_running, threads_and_procs_total = map(int, - data[3].split('/')) - most_recent_pid = int(data[4]) - ncpus = 1 - final_avg = "" - if hasattr(os, "sysconf"): - if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"): - # Linux - ncpus = os.sysconf("SC_NPROCESSORS_ONLN") - if isinstance(ncpus, int) and ncpus > 0: - final_avg = "%.2f" % (1.0 * avg1 / ncpus) - - # Future return everything when needed - # Commenting this for the time being - # avg5, avg15, threads_and_procs_running, threads_and_procs_total, most_recent_pid - return final_avg - - -def getInfinibandPortStatus(): - - """ Check for availability of infiniband port - and return which port is active in a key pair value - """ - - # Check for existence of infiniband ports - value = os.popen ("ls /sys/class/infiniband").readline().strip() - - if not value: - return None - - portlist = os.popen ("echo /sys/class/infiniband/*/ports/*").readline().split() - - portkeys = {} - - for port in portlist: - value = os.popen ("cat %s/state" % - port.strip()).readline().split(':')[1].strip() - portkeys[port.strip()] = value - - return portkeys - - -def getServerCount(): - try: - return int(open(Globals.SERVER_COUNT_FILE).read().strip()) - except IOError: - log("failed to read file %s" % Globals.SERVER_COUNT_FILE) - return 1 - except ValueError: - log("invalid number format in file %s" % Globals.SERVER_COUNT_FILE) - return 1 - - -def setServerCount(count): - try: - open(Globals.SERVER_COUNT_FILE, "w").write("%s\n" % count) - return True - except IOError: - log("failed to write file %s" % Globals.SERVER_COUNT_FILE) - return False - - -def getInstalledServerCount(): - try: - return int(open(Globals.INSTALLED_SERVER_COUNT_FILE).read().strip()) - except IOError: - log("failed to read file %s" % Globals.INSTALLED_SERVER_COUNT_FILE) - return 1 - except ValueError: - log("invalid number format in file %s" % Globals.INSTALLED_SERVER_COUNT_FILE) - return 1 - - -def setInstalledServerCount(count): - try: - open(Globals.INSTALLED_SERVER_COUNT_FILE, "w").write("%s\n" % count) - return True - except IOError: - log("failed to write file %s" % Globals.INSTALLED_SERVER_COUNT_FILE) - return False - - -def getLastInstalledServerIpList(): - ipList = {} - networkDom = Protocol.XDOM() - if not networkDom.parseFile(Globals.GLOBAL_NETWORK_FILE): - log("failed to parse file %s" % Globals.GLOBAL_NETWORK_FILE) - for tagE in networkDom.getElementsByTagRoute("server.interface"): - interfaceDom = Protocol.XDOM() - interfaceDom.setDomObj(tagE) - ipAddress = interfaceDom.getTextByTagRoute("ipaddr") - if ipAddress: - ipList[interfaceDom.getTextByTagRoute("device")] = ipAddress - return ipList - - -def getFreeIpAddress(device=None): - serverCount = getServerCount() - installedServerCount = getInstalledServerCount() - if serverCount == installedServerCount: - return None - - availableServerCount = serverCount - installedServerCount - ipList = getLastInstalledServerIpList() - - if not ipList: - return None - - if device: - if device not in ipList.keys(): - return None - deviceIpAddress = ipList[device] - else: - deviceIpAddress = ipList.values()[0] - ipNumber = IP2Number(deviceIpAddress) - - for i in range((ipNumber + availableServerCount), ipNumber, -1): - ipAddress = Number2IP(i) - if runCommandFG(["ping", "-qnc", "1", ipAddress]) != 0: - return ipAddress - return None - - -def getPasswordHash(userName): - try: - #return spwd.getspnam(userName).sp_pwd - return "Not implimented" - except KeyError: - return None - - -def getTransactionKey(): - try: - tokens = open(Globals.TRANSACTION_KEY_FILE).read().split(',') - except IOError: - return None, None - return tokens - - -def generateSignature(): - #return str(uuid.uuid4()) + ('--%f' % time.time()) - return ('--%f' % time.time()) - - -def getSignature(): - try: - return open(Globals.SIGNATURE_FILE).read().strip() - except IOError: - log(syslog.LOG_ERR, "unable to read signaure from %s file" % Globals.SIGNATURE_FILE) - return False - - -def storeSignature(signature, fileName=Globals.SIGNATURE_FILE): - try: - open(fileName, "w").write(signature + "\n") - except IOError: - log(syslog.LOG_ERR, "unable to write signature %s to %s file" % (signature, fileName)) - return False - return True - - -def isUserExist(userName): - try: - grp.getgrnam(userName).gr_gid - return True - except KeyError: - pass - try: - pwd.getpwnam(userName).pw_uid - return True - except KeyError: - pass - return False - - -def getGsnUserInfo(fileName=Globals.GSN_USER_INFO_FILE): - userInfo = {} - userInfo["UserId"] = None - userInfo["Password"] = None - try: - for line in open(fileName): - line = line.strip() - k = line[:line.index("=")] - v = line[line.index("=") + 1:] - if v[0] == "'" or v[0] == '"': - v = v[1:] - if v[-1] == "'" or v[-1] == '"': - v = v[:-1] - if k.upper() == "GSN_ID": - userInfo["UserId"] = v - if k.upper() == "GSN_PASSWORD": - userInfo["Password"] = v - except IOError, e: - log("Failed to read file %s: %s" % (fileName, e)) - return userInfo - - -def setGsnUserInfo(userInfo, fileName=Globals.GSN_USER_INFO_FILE): - try: - fp = open(fileName, "w") - fp.write("GSN_ID=%s\n" % userInfo["UserId"]) - fp.write("GSN_PASSWORD=%s\n" % userInfo["Password"]) - fp.close() - return True - except IOError, e: - log("Failed to write file %s: %s" % (fileName, e)) - return False - - -def getPlatformVersion(fileName=Globals.GLUSTER_VERSION_FILE): - versionInfo = {} - versionInfo["Version"] = None - versionInfo["Update"] = None - try: - lines = open(Globals.GLUSTER_VERSION_FILE).readlines() - for line in open(fileName): - line = line.strip() - k = line[:line.index("=")] - v = line[line.index("=") + 1:] - if v[0] == "'" or v[0] == '"': - v = v[1:] - if v[-1] == "'" or v[-1] == '"': - v = v[:-1] - if k.upper() == "VERSION": - versionInfo["Version"] = v - if k.upper() == "UPDATE": - versionInfo["Update"] = v - except IOError, e: - log("Failed to read file %s: %s" % (fileName, e)) - return versionInfo - - -def setPlatformVersion(versionInfo, fileName=Globals.GLUSTER_VERSION_FILE): - if isString(versionInfo): - tokens = versionInfo.strip().split(".") - if len(tokens) < 2: - log("Invalid version format %s. Expecting .." % versionInfo) - return False - version = ".".join(tokens[:2]) - update = ".".join(tokens[2:]) - if not update: - update = "0" - else: - version = versionInfo["Version"] - update = versionInfo["Update"] - try: - fp = open(fileName, "w") - fp.write("VERSION=%s\n" % version) - fp.write("UPDATE=%s\n" % update) - fp.close() - return True - except IOError, e: - log("Failed to write file %s: %s" % (fileName, e)) - return False - - -def getGlusterUpdateDom(serverVersion): - errorMessage = "" - updateInfoDom = None - try: - baseUrl = open(Globals.GLUSTER_UPDATE_SITE_FILE).read().strip() - except IOError, e: - log("Failed to read file %s: %s" % (Globals.GLUSTER_UPDATE_SITE_FILE, e)) - errorMessage = "Failed to read update site file" - return updateInfoDom, errorMessage - - try: - url = "%s/%s/%s" % (baseUrl, serverVersion, Globals.GLUSTER_UPDATES_FILE) - connection = urllib.urlopen(url) - if connection.getcode() != 200: - connection.close() - errorMessage = "Error received from server to open URL %s" % url - return updateInfoDom, errorMessage - updateInfoString = connection.read() - connection.close() - except IOError, e: - log("Failed to get update information from URL %s: %s" % (url, e)) - errorMessage = "Error getting update information" - return updateInfoDom, errorMessage - - updateInfoDom = Protocol.XDOM() - if not updateInfoDom.parseString(updateInfoString): - log("XML parse error on update information content [%s]" % updateInfoString) - errorMessage = "Parse error on update information" - updateInfoDom = None - return updateInfoDom, errorMessage - - -def removeFile(fileName, root=False): - if root: - if runCommand("rm %s" % fileName, root=True) == 0: - return True - return False - try: - os.remove(fileName) - return True - except OSError, e: - Utils.log("Failed to remove file %s: %s" % (fileName, e)) - return False - - -def isLiveMode(): - return os.path.exists(Globals.LIVE_MODE_FILE) diff --git a/src/com.gluster.storage.management.server.scripts/src/common/system-config-network-tui-1.3.99.18-1.el5.noarch.rpm b/src/com.gluster.storage.management.server.scripts/src/common/system-config-network-tui-1.3.99.18-1.el5.noarch.rpm deleted file mode 100644 index 4b07c4e4..00000000 Binary files a/src/com.gluster.storage.management.server.scripts/src/common/system-config-network-tui-1.3.99.18-1.el5.noarch.rpm and /dev/null differ diff --git a/src/com.gluster.storage.management.server.scripts/src/create_volume_directory.py b/src/com.gluster.storage.management.server.scripts/src/create_volume_directory.py new file mode 100755 index 00000000..b8fb2166 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/create_volume_directory.py @@ -0,0 +1,85 @@ +#!/usr/bin/python +# Copyright (C) 2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . +import os +import sys +import syslog +from XmlHandler import ResponseXml +import DiskUtils +import Utils +import Common + +def createDirectory(disk, volumeName): + + # Retrieving disk uuid + diskUuid = DiskUtils.getUuidByDiskPartition(DiskUtils.getDevice(disk)) + + rs = ResponseXml() + if not diskUuid: + Common.log(syslog.LOG_ERR, "failed to find disk:%s uuid" % disk) + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "Error: Unable to find disk uuid") + return rs.toprettyxml() + + # Retrieving disk mount point using disk uuid + diskMountPoint = DiskUtils.getMountPointByUuid(diskUuid) + if not os.path.exists(diskMountPoint): + Common.log(syslog.LOG_ERR, "failed to retrieve disk:%s mount point" % disk) + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "Error: Failed to retrieve disk details") + return rs.toprettyxml() + + # creating volume directory under disk mount point + volumeDirectory = "%s/%s" % (diskMountPoint, volumeName) + if os.path.exists(volumeDirectory): + Common.log(syslog.LOG_ERR, "Volume directory:%s already exists" % (volumeDirectory)) + rs.appendTagRoute("status.code", "-2") + rs.appendTagRoute("status.message", "Volume directory already exists!") + return rs.toprettyxml() + + if not os.path.exists(volumeDirectory): + command = ["sudo", "mkdir", volumeDirectory] + rv = Utils.runCommandFG(command, stdout=True, root=True) + message = Common.stripEmptyLines(rv["Stdout"]) + if rv["Stderr"]: + error = Common.stripEmptyLines(rv["Stderr"]) + message += "Error: [%s]" % (error) + Common.log(syslog.LOG_ERR, "failed to create volume directory %s, %s" % (volumeDirectory, error)) + rs.appendTagRoute("status.code", rv["Status"]) + rs.appendTagRoute("status.message", message) + return rs.toprettyxml() + + if not rv["Status"]: + rv["Status"] = "0" + if rv["Status"] == "0": + message = volumeDirectory + rs.appendTagRoute("status.code", rv["Status"]) + rs.appendTagRoute("status.message", message) + return rs.toprettyxml() + +def main(): + if len(sys.argv) != 3: + print >> sys.stderr, "usage: %s " % sys.argv[0] + sys.exit(-1) + + disk = sys.argv[1] + volumeName = sys.argv[2] + print createDirectory(disk, volumeName) + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/com.gluster.storage.management.server.scripts/src/get_disk_mount_point.py b/src/com.gluster.storage.management.server.scripts/src/get_disk_mount_point.py new file mode 100755 index 00000000..b2274b4d --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/get_disk_mount_point.py @@ -0,0 +1,64 @@ +#!/usr/bin/python +# Copyright (C) 2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import os +import syslog +import Common +from DiskUtils import * +from XmlHandler import ResponseXml + + +def getmountpoint(path): + if not path: + Common.log(syslog.LOG_ERR, "Not a valid path:%s" % path) + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "Error: given path name is empty") + return rs.toprettyxml() + + rs = ResponseXml() + mountPoint = None + + for line in readFsTab(): + if path.startswith(line['MountPoint']): + if not mountPoint: + mountPoint = line['MountPoint'] + if len(line['MountPoint']) > len(mountPoint): + mountPoint = line['MountPoint'] + + if "/" == mountPoint or not mountPoint: + Common.log(syslog.LOG_ERR, "failed to find mount point of the given path:%s" % path) + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "Error: Unable to find disk mount point") + return rs.toprettyxml() + + rs.appendTagRoute("status.code", "0") + rs.appendTagRoute("status.message", mountPoint) + return rs.toprettyxml() + +def main(): + if len(sys.argv) != 2: + print >> sys.stderr, "usage: %s " % sys.argv[0] + sys.exit(-1) + + path = sys.argv[1] + print getmountpoint(path) + sys.exit(0) + +if __name__ == "__main__": + main() + diff --git a/src/com.gluster.storage.management.server.scripts/src/get_disk_name_by_path.py b/src/com.gluster.storage.management.server.scripts/src/get_disk_name_by_path.py new file mode 100755 index 00000000..72eb80dd --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/get_disk_name_by_path.py @@ -0,0 +1,69 @@ +#!/usr/bin/python +# Copyright (C) 2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import os +import syslog +import Common +from DiskUtils import * +from XmlHandler import ResponseXml + + +def getmountpoint(path): + if not path: + Common.log(syslog.LOG_ERR, "Not a valid path:%s" % path) + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "Error: given path name is empty") + return rs.toprettyxml() + + rs = ResponseXml() + mountPoint = None + fsTabEntry = None + for line in readFsTab(): + if path.startswith(line['MountPoint']): + if not mountPoint: + mountPoint = line['MountPoint'] + fsTabEntry = line + if len(line['MountPoint']) > len(mountPoint): + mountPoint = line['MountPoint'] + fsTabEntry = line + + if "/" == mountPoint or not mountPoint: + Common.log(syslog.LOG_ERR, "failed to find mount point of the given path:%s" % path) + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "Error: Unable to find disk mount point") + return rs.toprettyxml() + + rs.appendTagRoute("status.code", "0") + if fsTabEntry["Device"].startswith("UUID="): + rs.appendTagRoute("status.message", getDiskPartitionByUuid(fsTabEntry["Device"].split("UUID=")[-1])) + else: + rs.appendTagRoute("status.message", "Unable to find disk name") + return rs.toprettyxml() + +def main(): + if len(sys.argv) != 2: + print >> sys.stderr, "usage: %s " % sys.argv[0] + sys.exit(-1) + + path = sys.argv[1] + print getmountpoint(path) + sys.exit(0) + +if __name__ == "__main__": + main() + diff --git a/src/com.gluster.storage.management.server.scripts/src/get_file.py b/src/com.gluster.storage.management.server.scripts/src/get_file.py new file mode 100755 index 00000000..826ade6e --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/get_file.py @@ -0,0 +1,132 @@ +# Copyright (C) 2009,2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import Globals +import syslog +import Commands +import Utils +from VolumeUtils import * +from XmlHandler import ResponseXml + + +def enumLogType(logCode): + if "M" == logCode.upper(): + return "EMERGENCY" + elif "A" == logCode.upper(): + return "ALERT" + elif "C" == logCode.upper(): + return "CRITICAL" + elif "E" == logCode.upper(): + return "ERROR" + elif "W" == logCode.upper(): + return "WARNING" + elif "N" == logCode.upper(): + return "NOTICE" + elif "I" == logCode.upper(): + return "INFO" + elif "D" == logCode.upper(): + return "DEBUG" + elif "T" == logCode.upper(): + return "TRACE" + else: + return "UNKNOWN" +##--end of enumLogType() + + +def addLog(responseDom, logMessageTag, loginfo): + logTag = responseDom.createTag("log", None) + logTag.appendChild(responseDom.createTag("date", loginfo[0])) + logTag.appendChild(responseDom.createTag("time", loginfo[1])) + logTag.appendChild(responseDom.createTag("type", enumLogType(loginfo[2]))) + logTag.appendChild(responseDom.createTag("message", loginfo[3])) + logMessageTag.appendChild(logTag) + return True +##--end of addLog() + + +def logSplit(log): + loginfo = log.strip().split(None, 3) + loginfo[0] = loginfo[0][1:] #-- Remove '[' + loginfo[1] = loginfo[1][0:-1] #-- Remove ']' + return loginfo +##--end of logSplit() + + +def getVolumeLog(volumeName, tailCount): + rs = ResponseXml() + if not volumeName: + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "No volume name given") + return rs.toprettyxml() + + if not tailCount: + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "No tail count given") + return rs.toprettyxml() + + thisServerName = getCurrentServerName() + if not thisServerName: + rs.appendTagRoute("status.code", "-2") + rs.appendTagRoute("status.message", "Failed to get current server name") + return rs.toprettyxml() + + volumeDom = XDOM() + partitionList = getPartitionListByServerName(volumeDom, thisServerName) + if not partitionList: + rs.appendTagRoute("status.code", "-3") + rs.appendTagRoute("status.message", "Failed to get server partition details") + return rs.toprettyxml() + + pattern = '\[\d{4}-\d{2}-\d{2}\s{1}\d{2}:\d{2}:\d{2}.\d+\]\s{1}([MACEWNIDT]){1}\s+' + logMessagesTag = rs.createTag("response.logMessages") + for partitionName in partitionList: + logMessageTag = rs.createTag("logMessage") + logMessageTag.appendChild("disk", "%s:%s" % (thisServerName, partitionName)) + + logDirectory = "%s/%s/%s/log" % (Globals.GLUSTER_LUN_DIR, partitionList[partitionName], volumeUuid) + logFileName = "%s/%s-%s-%s-exports-brick1.log" % (logDirectory, + Globals.GLUSTER_LUN_DIR[1:], + partitionList[partitionName], + volumeUuid) + if not os.path.exists(logFileName): + Utils.log("volume log file not found %s" % logFileName) + continue + fp = open(logFileName) + lines = [line for line in fp if re.match(pattern, line)] + fp.close() + i = len(lines) - int(tailCount) + if i < 0: + i = 0 + for log in lines[i:]: + loginfo = logSplit(log) + addLog(rs, logMessageTag, loginfo) + logMessagesTag.appendChild(logMessageTag) + return rs.toprettyxml() +##--end of getVolumeLog() + +def main(): + if len(sys.argv) != 3: + print >> sys.stderr, "usage: %s " % sys.argv[0] + sys.exit(-1) + + volumeName = sys.argv[1] + tailCount = sys.argv[2] + print getVolumeLog(volumeName, tailCount) + sys.exit(0) + +if __name__ == "__main__": + main() 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 new file mode 100755 index 00000000..2253ff30 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/get_server_details.py @@ -0,0 +1,224 @@ +#!/usr/bin/python +# Copyright (C) 2009 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import sys +import syslog +import socket +import Globals +import Commands +import re +from ServerUtils import * +from Protocol import * +from NetworkUtils import * +from Disk import * +from XmlHandler import ResponseXml + +def getDiskSizeInfo(partition): + # get values from df output + total = None + used = None + free = None + commandList = ['df', '-kl', '-t', 'ext3', '-t', 'ext4'] + commandOutput = "" + try: + process = subprocess.Popen(commandList, + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + close_fds=True) + status = process.wait() + if status == 0: + commandOutput = process.communicate() + except OSError: + return None,None,None + + for line in commandOutput[0].split("\n"): + tokens = line.split() + if len(tokens) < 4: + continue + if tokens[0] == partition: + total = int(tokens[1]) / 1024.0 + used = int(tokens[2]) / 1024.0 + free = int(tokens[3]) / 1024.0 + break + + if total: + return total, used, free + + # get total size from parted output + for i in range(len(partition), 0, -1): + pos = i - 1 + if not partition[pos].isdigit(): + break + disk = partition[:pos+1] + number = int(partition[pos+1:]) + + commandList = ['parted', '-ms', disk, 'unit', 'kb', 'print'] + commandOutput = "" + try: + process = subprocess.Popen(commandList, + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + close_fds=True) + status = process.wait() + if status == 0: + commandOutput = process.communicate() + except OSError: + return None,None,None + + lines = commandOutput[0].split(";\n") + if len(lines) < 3: + return None,None,None + + for line in lines[2:]: + tokens = line.split(':') + if len(tokens) < 4: + continue + if tokens[0] == str(number): + total = int(tokens[3].split('kB')[0]) / 1024.0 + break + + return total, used, free + +def getServerDetails(): + serverName = socket.gethostname() + responseDom = ResponseXml() + #responseDom.appendTagRoute("status.code", "0") + #responseDom.appendTagRoute("status.message", "success") + serverTag = responseDom.appendTagRoute("server") + serverTag.appendChild(responseDom.createTag("name", serverName)) + + nameServerList, domain, searchDomain = readResolvConfFile() + if domain: + domainName = domain[0] + else: + domainName = None + serverTag.appendChild(responseDom.createTag("domainname", domainName)) + i = 1 + for dns in nameServerList: + serverTag.appendChild(responseDom.createTag("dns%s" % i, dns)) + i += 1 + #TODO: probe and retrieve timezone, ntp-server, preferred-network details and update the tags + + deviceList = {} + interfaces = responseDom.createTag("networkInterfaces", None) + for device in getNetDeviceList(): + deviceList[device["device"]] = device + try: + macAddress = open("/sys/class/net/%s/address" % device["device"]).read().strip() + except IOError: + continue + interfaceTag = responseDom.createTag("networkInterface", None) + interfaceTag.appendChild(responseDom.createTag("name", device["device"])) + interfaceTag.appendChild(responseDom.createTag("hwAddr", macAddress)) + interfaceTag.appendChild(responseDom.createTag("speed", device["speed"])) + interfaceTag.appendChild(responseDom.createTag("model", device["model"])) + if deviceList[device["device"]]: + if deviceList[device["device"]]["onboot"]: + interfaceTag.appendChild(responseDom.createTag("onboot", "yes")) + else: + interfaceTag.appendChild(responseDom.createTag("onBoot", "no")) + interfaceTag.appendChild(responseDom.createTag("bootProto", deviceList[device["device"]]["bootproto"])) + interfaceTag.appendChild(responseDom.createTag("ipAddress", deviceList[device["device"]]["ipaddr"])) + interfaceTag.appendChild(responseDom.createTag("netMask", deviceList[device["device"]]["netmask"])) + interfaceTag.appendChild(responseDom.createTag("defaultGateway", deviceList[device["device"]]["gateway"])) + if deviceList[device["device"]]["mode"]: + interfaceTag.appendChild(responseDom.createTag("mode", deviceList[device["device"]]["mode"])) + if deviceList[device["device"]]["master"]: + interfaceTag.appendChild(responseDom.createTag("bonding", "yes")) + spliter = re.compile(r'[\D]') + interfaceTag.appendChild(responseDom.createTag("bondid", spliter.split(device["master"])[-1])) + else: + interfaceTag.appendChild(responseDom.createTag("onBoot", "no")) + interfaceTag.appendChild(responseDom.createTag("bootProto", "none")) + interfaces.appendChild(interfaceTag) + serverTag.appendChild(interfaces) + + responseDom.appendTag(serverTag) + serverTag.appendChild(responseDom.createTag("numOfCPUs", int(os.sysconf('SC_NPROCESSORS_ONLN')))) + + try: + meminfo = getMeminfo() + mem_total = meminfo['MemTotal'] + mem_free = meminfo['MemFree'] + mem_used = (mem_total - mem_free) + value = "%.2f" % (1.0 * mem_used / mem_total) + mem_percent = 100 * float(value) + cpu = 100 * float(getLoadavg()) + + except IOError: + print "Error" + responseDom.appendTagRoute("server.name", serverName) + syslog.syslog(syslog.LOG_ERR, "Error finding memory information of server:%s" % serverName) + return None + + diskObj = Disk() + ## disks = diskObj.getDiskList() + disks = diskObj.getMountableDiskList() + + if disks is None: + print "No disk found!" + syslog.syslog(syslog.LOG_ERR, "Error finding disk information of server:%s" % serverName) + return None + + serverTag.appendChild(responseDom.createTag("cpuUsage", str(cpu))) + #serverTag.appendChild(responseDom.createTag("totalMemory", str(mem_percent))) + serverTag.appendChild(responseDom.createTag("totalMemory", str(mem_total))) + serverTag.appendChild(responseDom.createTag("memoryInUse", str(mem_used))) + 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 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 = 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", "READY")) + 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))) + return serverTag + +def main(): + print getServerDetails().toxml() + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py b/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py new file mode 100755 index 00000000..7c912412 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py @@ -0,0 +1,109 @@ +#!/usr/bin/python +# Copyright (C) 2009,2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import re +import os +import sys +from XmlHandler import ResponseXml + +def enumLogType(logCode): + if "M" == logCode.upper(): + return "EMERGENCY" + elif "A" == logCode.upper(): + return "ALERT" + elif "C" == logCode.upper(): + return "CRITICAL" + elif "E" == logCode.upper(): + return "ERROR" + elif "W" == logCode.upper(): + return "WARNING" + elif "N" == logCode.upper(): + return "NOTICE" + elif "I" == logCode.upper(): + return "INFO" + elif "D" == logCode.upper(): + return "DEBUG" + elif "T" == logCode.upper(): + return "TRACE" + else: + return "UNKNOWN" +##--end of enumLogType() + +def addLog(responseDom, logMessageTag, loginfo): + logTag = responseDom.createTag("logMessage", None) + logTag.appendChild(responseDom.createTag("timestamp", loginfo[0] + " " + loginfo[1])) + logTag.appendChild(responseDom.createTag("severity", enumLogType(loginfo[2]))) + logTag.appendChild(responseDom.createTag("message", loginfo[3])) + logMessageTag.appendChild(logTag) + return True +##--end of addLog() + +def logSplit(log): + loginfo = log.strip().split(None, 3) + loginfo[0] = loginfo[0][1:] #-- Remove '[' + loginfo[1] = loginfo[1][0:-1] #-- Remove ']' + return loginfo +##--end of logSplit() + +def getVolumeLog(logFilePath, tailCount): + rs = ResponseXml() + if not logFilePath: + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "No log file path given") + return rs.toprettyxml() + + if not tailCount: + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "No tail count given") + return rs.toprettyxml() + + pattern = '\[\d{4}-\d{2}-\d{2}\s{1}\d{2}:\d{2}:\d{2}.\d+\]\s{1}([MACEWNIDT]){1}\s+' + logMessagesTag = rs.createTag("logMessages") + if not os.path.exists(logFilePath): + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "volume log file [%s] not found!" % logFilePath) + return rs.toprettyxml + + fp = open(logFilePath) + #lines = [line for line in fp] + lines = [line for line in fp if re.match(pattern, line)] + fp.close() + i = len(lines) - int(tailCount) + if i < 0: + i = 0 + for log in lines[i:]: + loginfo = logSplit(log) + addLog(rs, logMessagesTag, loginfo) + rs.appendTagRoute("status.code", "0") + rs.appendTagRoute("status.message", "Success") + rs.appendTag(logMessagesTag) + return rs.toprettyxml() +##--end of getVolumeLog() + +def main(): + if len(sys.argv) != 3: + print >> sys.stderr, "usage: %s " % sys.argv[0] + sys.exit(-1) + + logFilePath = sys.argv[1] + tailCount = sys.argv[2] + print getVolumeLog(logFilePath, tailCount) + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/com.gluster.storage.management.server.scripts/src/get_volume_log.py b/src/com.gluster.storage.management.server.scripts/src/get_volume_log.py new file mode 100755 index 00000000..826ade6e --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/get_volume_log.py @@ -0,0 +1,132 @@ +# Copyright (C) 2009,2010 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import Globals +import syslog +import Commands +import Utils +from VolumeUtils import * +from XmlHandler import ResponseXml + + +def enumLogType(logCode): + if "M" == logCode.upper(): + return "EMERGENCY" + elif "A" == logCode.upper(): + return "ALERT" + elif "C" == logCode.upper(): + return "CRITICAL" + elif "E" == logCode.upper(): + return "ERROR" + elif "W" == logCode.upper(): + return "WARNING" + elif "N" == logCode.upper(): + return "NOTICE" + elif "I" == logCode.upper(): + return "INFO" + elif "D" == logCode.upper(): + return "DEBUG" + elif "T" == logCode.upper(): + return "TRACE" + else: + return "UNKNOWN" +##--end of enumLogType() + + +def addLog(responseDom, logMessageTag, loginfo): + logTag = responseDom.createTag("log", None) + logTag.appendChild(responseDom.createTag("date", loginfo[0])) + logTag.appendChild(responseDom.createTag("time", loginfo[1])) + logTag.appendChild(responseDom.createTag("type", enumLogType(loginfo[2]))) + logTag.appendChild(responseDom.createTag("message", loginfo[3])) + logMessageTag.appendChild(logTag) + return True +##--end of addLog() + + +def logSplit(log): + loginfo = log.strip().split(None, 3) + loginfo[0] = loginfo[0][1:] #-- Remove '[' + loginfo[1] = loginfo[1][0:-1] #-- Remove ']' + return loginfo +##--end of logSplit() + + +def getVolumeLog(volumeName, tailCount): + rs = ResponseXml() + if not volumeName: + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "No volume name given") + return rs.toprettyxml() + + if not tailCount: + rs.appendTagRoute("status.code", "-1") + rs.appendTagRoute("status.message", "No tail count given") + return rs.toprettyxml() + + thisServerName = getCurrentServerName() + if not thisServerName: + rs.appendTagRoute("status.code", "-2") + rs.appendTagRoute("status.message", "Failed to get current server name") + return rs.toprettyxml() + + volumeDom = XDOM() + partitionList = getPartitionListByServerName(volumeDom, thisServerName) + if not partitionList: + rs.appendTagRoute("status.code", "-3") + rs.appendTagRoute("status.message", "Failed to get server partition details") + return rs.toprettyxml() + + pattern = '\[\d{4}-\d{2}-\d{2}\s{1}\d{2}:\d{2}:\d{2}.\d+\]\s{1}([MACEWNIDT]){1}\s+' + logMessagesTag = rs.createTag("response.logMessages") + for partitionName in partitionList: + logMessageTag = rs.createTag("logMessage") + logMessageTag.appendChild("disk", "%s:%s" % (thisServerName, partitionName)) + + logDirectory = "%s/%s/%s/log" % (Globals.GLUSTER_LUN_DIR, partitionList[partitionName], volumeUuid) + logFileName = "%s/%s-%s-%s-exports-brick1.log" % (logDirectory, + Globals.GLUSTER_LUN_DIR[1:], + partitionList[partitionName], + volumeUuid) + if not os.path.exists(logFileName): + Utils.log("volume log file not found %s" % logFileName) + continue + fp = open(logFileName) + lines = [line for line in fp if re.match(pattern, line)] + fp.close() + i = len(lines) - int(tailCount) + if i < 0: + i = 0 + for log in lines[i:]: + loginfo = logSplit(log) + addLog(rs, logMessageTag, loginfo) + logMessagesTag.appendChild(logMessageTag) + return rs.toprettyxml() +##--end of getVolumeLog() + +def main(): + if len(sys.argv) != 3: + print >> sys.stderr, "usage: %s " % sys.argv[0] + sys.exit(-1) + + volumeName = sys.argv[1] + tailCount = sys.argv[2] + print getVolumeLog(volumeName, tailCount) + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/src/com.gluster.storage.management.server.scripts/src/multicast_response.py b/src/com.gluster.storage.management.server.scripts/src/multicast_response.py new file mode 100644 index 00000000..dba65c07 --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/multicast_response.py @@ -0,0 +1,64 @@ +#!/usr/bin/python +# Copyright (C) 2009 Gluster, Inc. +# This file is part of Gluster Storage Platform. +# +# Gluster Storage Platform is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# Gluster Storage Platform is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . + +import os +import string +import time +import Utils +import socket +import struct +import Globals + +def isinpeer(): + command = "gluster peer status" + status = Utils.runCommand(command, output=True, root=True) + if status["Status"] == 0: + return True + #lines = status["Stdout"].split("\n") + #for line in lines: + # if string.upper(line).startswith("HOSTNAME: %s" % string.upper(socket.gethostname)): + # return True + Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) + return False + +def response(multiCastGroup, port): + # waiting for the request! + socketRequest = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) + socketRequest.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + socketRequest.bind(('', port)) + mreq = struct.pack("4sl", socket.inet_aton(multiCastGroup), socket.INADDR_ANY) + socketRequest.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) + + socketSend = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) + socketSend.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) + + #TODO: Remove infinite loop and make this as a deamon (service) + while True: + if isinpeer(): + time.sleep(5) + continue + request = socketRequest.recvfrom(1024) + if request and request[0].upper() == "SERVERDISCOVERY": + socketSend.sendto(socket.gethostname(), (multiCastGroup, port)) + request = None + +def main(): + response(Globals.MULTICAST_GROUP, Globals.MULTICAST_PORT) + +if __name__ == "__main__": + main() diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/Agent.py b/src/com.gluster.storage.management.server.scripts/src/nodes/Agent.py deleted file mode 100644 index 6d867d9e..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/Agent.py +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright (C) 2009 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import xmpp -import sys -import syslog - -class Agent: - def __init__(self, jidString, jidResource, password, proxySettings=None): - if jidString and jidResource and password: - self.password = password - self.proxySettings = proxySettings - self.jid = xmpp.protocol.JID(jid=jidString) - self.jid.setResource(jidResource) - self.xmppClient = xmpp.Client(self.jid.getDomain(), debug=[]) - self.presenceHandler = None - self.messageHandler = None - return - raise ValueError("jid, resource and password should not be empty") - - def registerPresenceHandler(self, function): - self.presenceHandler = function - - def registerMessageHandler(self, function): - self.messageHandler = function - - def __defaultMessageHandler(self, connection, event): - syslog.syslog(syslog.LOG_DEBUG, - "[Received]: from_jid=%s, type=%s, message=%s, error=%s\n" % - (event.getFrom(), event.getType(), event.getBody(), event.getError())) - if self.messageHandler: - self.messageHandler(connection, event) - else: - sys.stderr.write("[Message]: from_jid=%s, type=%s, message=%s, error=%s\n" % - (event.getFrom(), event.getType(), event.getBody(), event.getError())) - - def __defaultPresenceHandler(self, connection, event): - syslog.syslog(syslog.LOG_DEBUG, - "[Presence]: from_jid=%s, type=%s, status=%s, error=%s\n" % - (event.getFrom(), event.getType(), event.getShow(), event.getError())) - if self.presenceHandler: - self.presenceHandler(connection, event) - else: - sys.stderr.write("[Presence]: from_jid=%s, type=%s, status=%s, error=%s\n" % - (event.getFrom(), event.getType(), event.getShow(), event.getError())) - - def connect(self): - syslog.syslog("Connecting to server %s\n" % self.jid.getDomain()) - connection = self.xmppClient.connect() - if not connection: - syslog.syslog("failed\n") - if not self.proxySettings: - return False - syslog.syslog("Connecting to server %s through proxy server %s, port %s, username %s\n" % - (self.jid.getDomain(), - self.proxySettings["host"], - self.proxySettings["port"], - self.proxySettings["user"])) - connection = self.xmppClient.connect(proxy=self.proxySettings) - if not connection: - syslog.syslog("failed\n") - return False - - syslog.syslog("Authenticating with username %s\n" % self.jid) - auth = self.xmppClient.auth(self.jid.getNode(), - self.password, - self.jid.getResource()) - if not auth: - syslog.syslog("failed\n") - return False - syslog.syslog("done\n") - syslog.syslog("connection type is %s. authentication type is %s\n" % (connection, auth)) - - self.xmppClient.RegisterHandler("presence", self.__defaultPresenceHandler) - self.xmppClient.RegisterHandler("message", self.__defaultMessageHandler) - - self.xmppClient.sendInitPresence() - return True - - def disconnect(self): - self.xmppClient.disconnect() - - def processMessage(self, timeout=1): - return self.xmppClient.Process(timeout) - #if not self.xmppClient.isConnected(): - # self.xmppClient.reconnectAndReauth() - - def sendMessage(self, jidString, message, messageType="chat"): - syslog.syslog(syslog.LOG_DEBUG, - "[send]: from_jid=%s, type=%s, message=%s\n" % - (jidString, messageType, message)) - self.xmppClient.send(xmpp.protocol.Message(to=jidString, - body=message, - typ=messageType)) - - def getNetworkSocket(self): - return self.xmppClient.Connection._sock; - - def getRoster(self): - return self.xmppClient.getRoster() - - def isConnected(self): - return self.xmppClient.isConnected() -##--end of Agent diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/Disk.py b/src/com.gluster.storage.management.server.scripts/src/nodes/Disk.py deleted file mode 100755 index a1ab9264..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/Disk.py +++ /dev/null @@ -1,141 +0,0 @@ -# Copyright (c) 2009 Gluster, Inc. -# This file is part of GlusterSP. -# -# GlusterSP is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published -# by the Free Software Foundation; either version 3 of the License, -# or (at your option) any later version. -# -# GlusterSP is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import os -import dbus -from Common import * - -class Disk: - def __init__(self): - """init""" - - self.volumes = [] - self.disks = [] - self.bus = dbus.SystemBus() - self.hal_obj = self.bus.get_object("org.freedesktop.Hal", - "/org/freedesktop/Hal/Manager") - self.hal = dbus.Interface(self.hal_obj, "org.freedesktop.Hal.Manager") - self.devices = [] - self.devices = self.hal.FindDeviceByCapability("storage") - - self.detect_disks() - self.detect_mountable_volumes() - - def getDiskList(self): - - return self.disks - - def getMountableDiskList(self): - - return self.volumes - - def detect_disks(self): - for device in self.devices: - dev = self._get_device(device) - if dev.GetProperty("storage.drive_type") != "cdrom": - if not dev.GetProperty("block.is_volume"): - self._add_disks(dev) - continue - - def _add_disks(self, dev): - disk = str(dev.GetProperty('block.device')) - disk_size = str(int(dev.GetProperty('storage.size')) / 1024**2) - - try: - if dev.GetProperty('storage.removable'): - disk_size = str(int(dev.GetProperty('storage.removable.media_size')) / 1024**2) - except: - return - - self.disks.append({ - 'device': disk, - 'description': str(dev.GetProperty('storage.model')) + " " + str(dev.GetProperty('storage.vendor')), - 'interface': str(dev.GetProperty('storage.bus')), - 'size': disk_size, - 'drive_type': str(dev.GetProperty('storage.drive_type')) - }) - - def detect_mountable_volumes(self): - """ Detect all mountable volumes using HAL via D-Bus """ - for device in self.devices: - dev = self._get_device(device) - if dev.GetProperty("storage.drive_type") != "cdrom": - if dev.GetProperty("block.is_volume"): - self._add_volume(dev) - continue - else: # iterate over children looking for a volume - children = self.hal.FindDeviceStringMatch("info.parent", - device) - if not children and "disk" == dev.GetProperty("storage.drive_type"): - self._add_volume(dev) - for child in children: - child = self._get_device(child) - if child.GetProperty("block.is_volume"): - self._add_volume(child, parent=dev) - #break # don't break, allow all partitions - - def _add_volume(self, dev, parent=None): - volume = str(dev.GetProperty('block.device')) - if not parent: - self.volumes.append ({ - 'device' : volume, - 'label' : str(dev.GetProperty('block.device')), - 'fstype' : None, - 'fsversion': None, - 'uuid' : None, - 'interface': str(dev.GetProperty('storage.bus')), - 'parent' : None, - 'description': str(dev.GetProperty('storage.model')) + " " + str(dev.GetProperty('storage.vendor')), - 'size' : None, - 'totalsize' : str(int(dev.GetProperty('storage.size')) / 1024**2), - 'drive_type': str(dev.GetProperty('storage.drive_type')), - 'mount_point': "NA" - }) - return - - self.volumes.append ({ - 'device' : volume, - 'label' : str(dev.GetProperty('volume.label')), - 'fstype' : str(dev.GetProperty('volume.fstype')), - 'fsversion': str(dev.GetProperty('volume.fsversion')), - 'uuid' : str(dev.GetProperty('volume.uuid')), - 'interface': str(parent.GetProperty('storage.bus')), - 'parent' : str(parent.GetProperty('block.device')), - 'description': str(parent.GetProperty('storage.model')) + " " + str(parent.GetProperty('storage.vendor')), - 'size' : str(int(dev.GetProperty('volume.size')) / 1024**2), - 'totalsize' : str(int(parent.GetProperty('storage.size')) / 1024**2), - 'drive_type': str(parent.GetProperty('storage.drive_type')), - 'mount_point': str(dev.GetProperty('volume.mount_point')) - }) - return - - def _get_device(self, udi): - """ Return a dbus Interface to a specific HAL device UDI """ - dev_obj = self.bus.get_object("org.freedesktop.Hal", udi) - return dbus.Interface(dev_obj, "org.freedesktop.Hal.Device") - - def get_free_bytes(self, device=None): - """ Return the number of available bytes on our device """ - import statvfs - stat = os.statvfs(device) - return stat[statvfs.F_BSIZE] * stat[statvfs.F_BAVAIL] - - def get_used_bytes(self, device=None): - """ Return the number of used bytes on our device """ - import statvfs - stat = os.statvfs(device) - return ((stat[statvfs.F_BSIZE] * stat[statvfs.F_BLOCKS]) - (stat[statvfs.F_BSIZE] * stat[statvfs.F_BAVAIL])) diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/GetServerNetworkConfig.py b/src/com.gluster.storage.management.server.scripts/src/nodes/GetServerNetworkConfig.py deleted file mode 100644 index 3311eb56..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/GetServerNetworkConfig.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (C) 2009 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import sys -import syslog -import Globals -import Commands -import re -from ServerUtils import * -from Protocol import * -from NetworkUtils import * - -def getServerNetworkConfig(requestXml): - serverName = requestXml.getTextByTagRoute("command.server-name") - version = requestXml.getVersion() - messageId = requestXml.getAttribute("id") - - if not serverName: - responseDom = ResponseXml(Commands.COMMAND_GET_SERVER_NETWORK_CONFIG, "No server name given", messageId, version) - responseDom.appendTagRoute("server.name", serverName) - return responseDom - responseDom = ResponseXml(Commands.COMMAND_GET_SERVER_NETWORK_CONFIG, "OK", messageId, version) - serverTag = responseDom.createTag("server", None) - serverTag.appendChild(responseDom.createTag("name", serverName)) - nameServerList, domain, searchDomain = readResolvConfFile() - if domain: - domainName = domain[0] - else: - domainName = None - serverTag.appendChild(responseDom.createTag("domainname", domainName)) - i = 1 - for dns in nameServerList: - serverTag.appendChild(responseDom.createTag("dns%s" % i, dns)) - i += 1 - #TODO: probe and retrieve timezone, ntp-server, preferred-network details and update the tags - configDom = XDOM() - if configDom.parseFile("%s/%s/network.xml" % (Globals.SERVER_CONF_DIR, serverName)): - serverTag.appendChild(responseDom.createTag("timezone", configDom.getTextByTagRoute("network.timezone"))) - serverTag.appendChild(responseDom.createTag("ntp-server", configDom.getTextByTagRoute("network.ntp-server"))) - preferredNetwork = configDom.getTextByTagRoute("network.preferred-network") - if not preferredNetwork: - preferredNetwork = "any" - serverTag.appendChild(responseDom.createTag("preferred-network", preferredNetwork)) - - deviceList = {} - for device in getNetDeviceList(): - deviceList[device["device"]] = device - try: - macAddress = open("/sys/class/net/%s/address" % device["device"]).read().strip() - except IOError: - continue - interfaceTag = responseDom.createTag("interface", None) - interfaceTag.appendChild(responseDom.createTag("device", device["device"])) - interfaceTag.appendChild(responseDom.createTag("description", device["description"])) - interfaceTag.appendChild(responseDom.createTag("hwaddr", macAddress)) - if deviceList[device["device"]]: - if deviceList[device["device"]]["onboot"]: - interfaceTag.appendChild(responseDom.createTag("onboot", "yes")) - else: - interfaceTag.appendChild(responseDom.createTag("onboot", "no")) - interfaceTag.appendChild(responseDom.createTag("bootproto", deviceList[device["device"]]["bootproto"])) - interfaceTag.appendChild(responseDom.createTag("ipaddr", deviceList[device["device"]]["ipaddr"])) - interfaceTag.appendChild(responseDom.createTag("netmask", deviceList[device["device"]]["netmask"])) - interfaceTag.appendChild(responseDom.createTag("gateway", deviceList[device["device"]]["gateway"])) - if deviceList[device["device"]]["mode"]: - interfaceTag.appendChild(responseDom.createTag("mode", deviceList[device["device"]]["mode"])) - if deviceList[device["device"]]["master"]: - interfaceTag.appendChild(responseDom.createTag("bonding", "yes")) - spliter = re.compile(r'[\D]') - interfaceTag.appendChild(responseDom.createTag("bondid", spliter.split(device["master"])[-1])) - else: - interfaceTag.appendChild(responseDom.createTag("onboot", "no")) - interfaceTag.appendChild(responseDom.createTag("bootproto", "none")) - serverTag.appendChild(interfaceTag) - responseDom.appendTag(serverTag) - return responseDom - -def test(): - requestString = """ -s1""" - requestDom = RequestXml(requestString) - print getServerNetworkConfig(requestDom).toxml() diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/GlusterdUtils.py b/src/com.gluster.storage.management.server.scripts/src/nodes/GlusterdUtils.py deleted file mode 100644 index 7c0e899c..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/GlusterdUtils.py +++ /dev/null @@ -1,250 +0,0 @@ -# Copyright (c) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import os -import Utils - -import ServerUtils - - -def getGlusterVolumeInfo(volumeName=None): - volumeNameList = None - if Utils.isString(volumeName): - volumeNameList = [volumeName] - if type(volumeName) == type([]): - volumeNameList = volumeName - - status = Utils.runCommand("gluster volume info", output=True, root=True) - if status["Status"] != 0: - Utils.log("Failed to execute 'gluster volume info' command") - return None - - volumeInfoDict = {} - volumeInfo = {} - volumeName = None - brickList = [] - for line in status['Stdout'].split("\n"): - if not line: - if volumeName and volumeInfo: - volumeInfo["Bricks"] = brickList - volumeInfoDict[volumeName] = volumeInfo - volumeInfo = {} - volumeName = None - brickList = [] - continue - - tokens = line.split(":") - if tokens[0].strip().upper() == "BRICKS": - continue - elif tokens[0].strip().upper() == "VOLUME NAME": - volumeName = tokens[1].strip() - volumeInfo["VolumeName"] = volumeName - elif tokens[0].strip().upper() == "TYPE": - volumeInfo["VolumeType"] = tokens[1].strip() - elif tokens[0].strip().upper() == "STATUS": - volumeInfo["VolumeStatus"] = tokens[1].strip() - elif tokens[0].strip().upper() == "TRANSPORT-TYPE": - volumeInfo["TransportType"] = tokens[1].strip() - elif tokens[0].strip().upper().startswith("BRICK"): - brickList.append(":".join(tokens[1:]).strip()) - - if volumeName and volumeInfo: - volumeInfoDict[volumeName] = volumeInfo - - if not volumeNameList: - return volumeInfoDict - - # remove unwanted volume info - for volumeName in list(set(volumeInfoDict.keys()) - set(volumeNameList)): - del volumeInfoDict[volumeName] - - return volumeInfoDict - - -def isVolumeRunning(volumeName): - if not volumeName: - return False - volumeInfo = getGlusterVolumeInfo(volumeName) - if not volumeInfo: - return False - status = volumeInfo[volumeName]["VolumeStatus"] - if not status: - return False - if status.upper() == "STARTED": - return True - return False - - -def isVolumeExist(volumeName): - if not volumeName: - return False - if getGlusterVolumeInfo(volumeName): - return True - return False - - -def peerProbe(serverName): - command = "gluster peer probe %s" % serverName - status = Utils.runCommand(command, output=True, root=True) - if status["Status"] == 0: - return True - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return False - - -def setAuthAllow(volumeName, authList, includeServers=True): - if not (volumeName and authList): - return False - vacl = [] - if includeServers: - for serverName in ServerUtils.getAllServerList(): - vacl += ServerUtils.getServerIpList(serverName) - vacl += authList - - command = "gluster volume set %s auth.allow %s" % (volumeName, ",".join(list(set(vacl)))) - status = Utils.runCommand(command, output=True, root=True) - if status["Status"] == 0: - return True - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return False - - -def volumeCreate(volumeName, volumeType, transportTypeList, brickList): - command = "gluster volume create %s" % volumeName - - if volumeType.upper() == "MIRROR": - command += " replica 2" - elif volumeType.upper() == "STRIPE": - command += " stripe 4" - - if "RDMA" in transportTypeList: - command += " transport rdma" - - command += " " + " ".join(brickList) - - status = Utils.runCommand(command, output=True, root=True) - if status["Status"] == 0: - return True - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return False - - -def volumeDelete(volumeName): - command = "gluster --mode=script volume delete %s" % volumeName - status = Utils.runCommand(command, output=True, root=True) - if status["Status"] == 0: - return True - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return False - - -def volumeLogFileName(volumeName, brick, logDir): - command = "gluster volume log filename %s %s %s" % (volumeName, brick, logDir) - status = Utils.runCommand(command, output=True, root=True) - if status["Status"] == 0: - return True - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return False - - -def startVolumeMigration(volumeName, sourcePath, destinationPath): - command = "gluster volume replace-brick %s %s %s start" % (volumeName, sourcePath, destinationPath) - status = Utils.runCommand(command, output=True, root=True) - if status["Status"] == 0: - lines = status["Stdout"].split("\n") - if lines[0].split()[-1] == "successfully": - return True - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return False - - -def stopVolumeMigration(volumeName, sourcePath, destinationPath): - command = "gluster volume replace-brick %s %s %s abort" % (volumeName, sourcePath, destinationPath) - status = Utils.runCommand(command, output=True, root=True) - if status["Status"] == 0: - lines = status["Stdout"].split("\n") - if lines[0].split()[-1] == "successful": - return True - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return False - - -def commitVolumeMigration(volumeName, sourcePath, destinationPath): - command = "gluster volume replace-brick %s %s %s commit" % (volumeName, sourcePath, destinationPath) - status = Utils.runCommand(command, output=True, root=True) - if status["Status"] == 0: - lines = status["Stdout"].split("\n") - if lines[0].split()[-1] == "successful": - return True - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return False - - -def getMigrationStatus(volumeName, sourcePath, destinationPath): - command = "gluster volume replace-brick %s %s %s status" % (volumeName, sourcePath, destinationPath) - status = Utils.runCommand(command, output=True, root=True) - if status['Status'] == 0 and status['Stdout']: - lines = status["Stdout"].split("\n") - if "Current file" in lines[0]: - return "started" - if "Migration complete" in lines[0]: - return "completed" - Utils.log("command [%s] returns unknown status:%s" % (command, lines[0])) - return "failed" - #if status['Status'] == 0 and status['Stdout']: - # for line in status['Stdout'].split('\n'): - # words = line.split() - # if words and words[0].upper() == "STATUS:": - # return " ".join(words[1:]).upper() - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return None - - -def volumeRebalanceStart(volumeName): - command = "gluster volume rebalance %s start" % volumeName - status = Utils.runCommand(command, output=True, root=True) - if status["Status"] == 0: - lines = status["Stdout"].split("\n") - if lines[0].split()[-1] == "successful": - return True - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return False - - -def volumeRebalanceStop(volumeName): - command = "gluster volume rebalance %s stop" % volumeName - status = Utils.runCommand(command, output=True, root=True) - if status["Status"] == 0: - lines = status["Stdout"].split("\n") - if lines[0].split()[0] == "stopped": - return True - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return False - - -def volumeRebalanceStatus(volumeName): - command = "gluster volume rebalance %s status" % volumeName - status = Utils.runCommand(command, output=True, root=True) - if status["Status"] == 0: - lines = status["Stdout"].split("\n") - if "rebalance not started" in lines[0]: - return "not started" - if "rebalance completed" in lines[0]: - return "completed" - return "running" - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return False diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/PeerAgent.py b/src/com.gluster.storage.management.server.scripts/src/nodes/PeerAgent.py deleted file mode 100755 index 6218e921..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/PeerAgent.py +++ /dev/null @@ -1,212 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import os -import sys -import signal -import atexit -import socket -import syslog -import pwd -from optparse import OptionParser - -import Globals -import Socket -import Utils -from XmlHandler import ResponseXml - - -ME = os.path.basename(sys.argv[0]) -PID_FILE = "/var/run/serveragent.pid" -serverSocket = None -clientSocket = None -clientAddress = None -clientInputStream = None -clientOutputStream = None - - -def sigTermHandler(signal, frame): - sys.exit(0) - - -def cleanup(): - try: - if os.path.exists(PID_FILE): - os.unlink(PID_FILE) - except OSError, e: - Utils.log("Failed to remove PID file %s: %s" % (PID_FILE, str(e))) - - try: - if clientSocket: - clientSocket.close() - except socket.error, e: - Utils.log("Failed to close client socket: %s" % str(e)) - - try: - if serverSocket: - serverSocket.close() - except socket.error, e: - Utils.log("Failed to close server socket: " % str(e)) - -def stripEmptyLines(content): - ret = "" - for line in content.split("\n"): - if line.strip() != "": - ret += line - return ret - -def executeCommand(command): - rv = Utils.runCommandFG(command, stdout=True, root=True) - statusCode = rv["Status"] - if statusCode != 0: - output = "output: [" + stripEmptyLines(rv["Stdout"]) + "] error: [" + stripEmptyLines(rv["Stderr"]) + "]"; - rs = ResponseXml() - rs.appendTagRoute("status.code", statusCode); - rs.appendTagRoute("status.message", output); - return rs.toprettyxml() - else: - return rv["Stdout"] - -def main(): - global PID_FILE - global serverSocket - global clientSocket - global clientAddress - global clientInputStream - global clientOutputStream - - username = Globals.SERVER_AGENT_RUN_USERNAME - - Utils.openLog(Globals.PEER_AGENT_LOG_FILE) - - parser = OptionParser(version="%s %s" % (ME, Globals.GLUSTER_PLATFORM_VERSION)) - - parser.add_option("-N", "--no-daemon", - action="store_false", dest="daemonMode", default=True, - help="Run in foreground") - parser.add_option("-r", "--run-as", dest="username", - help="Run the daemon as USERNAME (default: %s)" % Globals.SERVER_AGENT_RUN_USERNAME, - metavar="USERNAME") - (options, args) = parser.parse_args() - - if options.username: - username = options.username - try: - userInfo = pwd.getpwnam(username) - except KeyError, e: - sys.stderr.write("%s\n" % str(e)) - serverSocket.close() - sys.exit(-1) - uid = userInfo.pw_uid - gid = userInfo.pw_gid - - try: - Utils.log("__DEBUG__ Opening server socket on port %s" % Globals.SERVER_AGENT_PORT) - serverSocket = Socket.openServerSocket() - except socket.error, e: - sys.stderr.write("Failed to open server socket: %s\n" % str(e)) - sys.exit(-1) - - if options.daemonMode: - if os.path.exists(PID_FILE): - sys.stderr.write("fatal: %s file exists\n" % PID_FILE) - serverSocket.close() - sys.exit(-1) - - if not Utils.daemonize(): - sys.stderr.write("fatal: unable to run as daemon\n") - serverSocket.close() - sys.exit(-1) - try: - fp = open(PID_FILE, "w") - fp.write("%s\n" % os.getpid()) - fp.close() - except IOError, e: - Utils.log("Pid file %s: %s" % (PID_FILE, str(e))) - serverSocket.close() - sys.exit(-1) - try: - os.chown(PID_FILE, uid, gid) - except OSError, e: - Utils.log("Pid file %s: %s" % (PID_FILE, str(e))) - serverSocket.close() - try: - os.unlink(PID_FILE) - except OSError, ex: - Utils.log("Failed to remove PID file %s: %s" % (PID_FILE, str(ex))) - sys.exit(-1) - else: - Globals.GLUSTER_DEBUG = True - - try: - os.setregid(gid, gid) - except OSError, e: - Utils.log("Failed to set effective and real gid to %s: %s" % (gid, str(e))) - cleanup() - sys.exit(-1) - try: - os.setreuid(uid, uid) - except OSError, e: - Utils.log("Failed to set effective and real uid to %s: %s" % (uid, str(e))) - cleanup() - sys.exit(-1) - - atexit.register(cleanup) - signal.signal(signal.SIGTERM, sigTermHandler) - - while True: - Utils.log("__DEBUG__ Waiting for new connection on port %s" % Globals.SERVER_AGENT_PORT) - try: - clientSocket, clientAddress, clientInputStream, clientOutputStream = Socket.acceptClient(serverSocket) - except socket.error, e: - Utils.log("Failed to accept new connection: %s" % str(e)) - sys.exit(-1) - - Utils.log('__DEBUG__ Connected by %s' % str(clientAddress)) - try: - requestString = Socket.readPacket(clientInputStream) - Utils.log('__DEBUG__ Received %s' % repr(requestString)) - requestParts = requestString.split(None, 3) - - if "get_file" == requestParts[0]: - if len(requestParts) != 2: - rs = ResponseXml() - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "File path not passed") - Socket.writePacket(clientOutputStream, rs.toprettyxml()) - else: - filePath = requestParts[1] - fp = open(filePath) - clientSocket.sendall(fp.read()) - fp.close() - clientOutputStream.flush() - else: - responseString = executeCommand(requestString) - if responseString: - Socket.writePacket(clientOutputStream, responseString) - clientOutputStream.flush() - else: - Utils.log('__DEBUG__ empty response string') - Utils.log('__DEBUG__ Closing client %s' % str(clientAddress)) - clientSocket.close() - except socket.error, e: - Utils.log("Socket error on client: %s" % str(e)) - sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/ServerAgent.py b/src/com.gluster.storage.management.server.scripts/src/nodes/ServerAgent.py deleted file mode 100755 index bcb2bac1..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/ServerAgent.py +++ /dev/null @@ -1,179 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import os -import sys -import signal -import atexit -import socket -import syslog -import pwd -from optparse import OptionParser - -import Globals -import Socket -import Utils -import ServerRequestHandler - - -ME = os.path.basename(sys.argv[0]) -PID_FILE = "/var/run/serveragent.pid" -serverSocket = None -clientSocket = None -clientAddress = None -clientInputStream = None -clientOutputStream = None - - -def sigTermHandler(signal, frame): - sys.exit(0) - - -def cleanup(): - try: - if os.path.exists(PID_FILE): - os.unlink(PID_FILE) - except OSError, e: - Utils.log("Failed to remove PID file %s: %s" % (PID_FILE, str(e))) - - try: - if clientSocket: - clientSocket.close() - except socket.error, e: - Utils.log("Failed to close client socket: %s" % str(e)) - - try: - if serverSocket: - serverSocket.close() - except socket.error, e: - Utils.log("Failed to close server socket: " % str(e)) - - -def main(): - global PID_FILE - global serverSocket - global clientSocket - global clientAddress - global clientInputStream - global clientOutputStream - - username = Globals.SERVER_AGENT_RUN_USERNAME - - Utils.openLog(Globals.SERVER_AGENT_LOG_FILE) - - parser = OptionParser(version="%s %s" % (ME, Globals.GLUSTER_PLATFORM_VERSION)) - - parser.add_option("-N", "--no-daemon", - action="store_false", dest="daemonMode", default=True, - help="Run in foreground") - parser.add_option("-r", "--run-as", dest="username", - help="Run the daemon as USERNAME (default: %s)" % Globals.SERVER_AGENT_RUN_USERNAME, - metavar="USERNAME") - (options, args) = parser.parse_args() - - if options.username: - username = options.username - try: - userInfo = pwd.getpwnam(username) - except KeyError, e: - sys.stderr.write("%s\n" % str(e)) - serverSocket.close() - sys.exit(-1) - uid = userInfo.pw_uid - gid = userInfo.pw_gid - - try: - Utils.log("__DEBUG__ Opening server socket on port %s" % Globals.SERVER_AGENT_PORT) - serverSocket = Socket.openServerSocket() - except socket.error, e: - sys.stderr.write("Failed to open server socket: %s\n" % str(e)) - sys.exit(-1) - - if options.daemonMode: - if os.path.exists(PID_FILE): - sys.stderr.write("fatal: %s file exists\n" % PID_FILE) - serverSocket.close() - sys.exit(-1) - - if not Utils.daemonize(): - sys.stderr.write("fatal: unable to run as daemon\n") - serverSocket.close() - sys.exit(-1) - try: - fp = open(PID_FILE, "w") - fp.write("%s\n" % os.getpid()) - fp.close() - except IOError, e: - Utils.log("Pid file %s: %s" % (PID_FILE, str(e))) - serverSocket.close() - sys.exit(-1) - try: - os.chown(PID_FILE, uid, gid) - except OSError, e: - Utils.log("Pid file %s: %s" % (PID_FILE, str(e))) - serverSocket.close() - try: - os.unlink(PID_FILE) - except OSError, ex: - Utils.log("Failed to remove PID file %s: %s" % (PID_FILE, str(ex))) - sys.exit(-1) - else: - Globals.GLUSTER_DEBUG = True - - try: - os.setregid(gid, gid) - except OSError, e: - Utils.log("Failed to set effective and real gid to %s: %s" % (gid, str(e))) - cleanup() - sys.exit(-1) - try: - os.setreuid(uid, uid) - except OSError, e: - Utils.log("Failed to set effective and real uid to %s: %s" % (uid, str(e))) - cleanup() - sys.exit(-1) - - atexit.register(cleanup) - signal.signal(signal.SIGTERM, sigTermHandler) - - while True: - Utils.log("__DEBUG__ Waiting for new connection on port %s" % Globals.SERVER_AGENT_PORT) - try: - clientSocket, clientAddress, clientInputStream, clientOutputStream = Socket.acceptClient(serverSocket) - except socket.error, e: - Utils.log("Failed to accept new connection: %s" % str(e)) - sys.exit(-1) - - Utils.log('__DEBUG__ Connected by %s' % str(clientAddress)) - try: - requestString = Socket.readPacket(clientInputStream) - Utils.log('__DEBUG__ Received %s' % repr(requestString)) - responseString = ServerRequestHandler.handleRequest(requestString) - if responseString: - Socket.writePacket(clientOutputStream, responseString) - clientOutputStream.flush() - else: - Utils.log('__DEBUG__ empty response string') - Utils.log('__DEBUG__ Closing client %s' % str(clientAddress)) - clientSocket.close() - except socket.error, e: - Utils.log("Socket error on client: %s" % str(e)) - sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/ServerRequestHandler.py b/src/com.gluster.storage.management.server.scripts/src/nodes/ServerRequestHandler.py deleted file mode 100644 index 31d4eb8c..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/ServerRequestHandler.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright (C) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import os - -import Commands -from Protocol import * -from Globals import * -from GetServerNetworkConfig import * - -def handleRequestGetServerNetworkConfig(requestDom): - return getServerNetworkConfig(requestDom) - -def handleRequest(requestString): - log("Received request %s" % repr(requestString)) - - requestDom = XDOM() - requestDom.parseString(requestString) - if not requestDom: - log("Invalid request") - return None - - preRequestMap = {} - - postRequestMap = {} - - cleanupRequestMap = {} - - requestMap = { Commands.COMMAND_GET_SERVER_NETWORK_CONFIG : handleRequestGetServerNetworkConfig } - - messageId = requestDom.getMessageId() - if not messageId: - log("Invalid message Id") - return None - - requestCommand = requestDom.getRequestCommand() - if not requestCommand: - log("invalid request command") - return None - - requestAction = requestDom.getRequestAction() - version = requestDom.getVersion() - #if not isSupportedVersion(version): - # log("Unsupported version request %s" % requestDom.toxml()) - # return ResponseXml(requestCommand, "Unsupported version request", messageId, version).toxml() - - try: - if not requestAction: - responseDom = requestMap[requestCommand](requestDom) - elif requestAction.upper() == "PRE": - responseDom = preRequestMap[requestCommand](requestDom) - elif requestAction.upper() == "POST": - responseDom = postRequestMap[requestCommand](requestDom) - elif requestAction.upper() == "CLEANUP": - responseDom = cleanupRequestMap[requestCommand](requestDom) - else: - log("Unknown request action %s" % requestAction) - return None - return responseDom.toxml() - except KeyError: - log("No handler found for command %s for action %s" % (requestCommand, requestAction)) - return ResponseXml(requestCommand, "Invalid command", messageId, version).toxml() diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/ServerUtils.py b/src/com.gluster.storage.management.server.scripts/src/nodes/ServerUtils.py deleted file mode 100644 index 1fec994c..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/ServerUtils.py +++ /dev/null @@ -1,308 +0,0 @@ -# Copyright (c) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import os -import re -import subprocess -import glob -import Globals -from Protocol import * -from Utils import * - -def isValidServer(serverName): - for profile in getProfileList(): - if profile.ProfileName == "default" and profile.Active: - if serverName == profile.DNS.Hostname: - return True - return False - -def getHostname(): - for profile in getProfileList(): - if profile.ProfileName == "default" and profile.Active: - return profile.DNS.Hostname - return None - -def getDomainName(): - try: - domainName = open(Globals.DOMAINNAME_FILE).read() - except IOError: - return None - return domainName.split()[0] - -def replaceServerIp(fileName, findWhat, replaceWith): - try: - data = open(fileName).read() - fp = open(fileName, "w") - fp.write(re.sub(findWhat, replaceWith, data)) - fp.close() - return True - except IOError: - return False - except ValueError: - return False - except OSError: - return False - -def serverName2IpAddress(serverName): - command = "dig %s | grep '^%s'" % (serverName, serverName) - ps = subprocess.Popen(command, - shell=True, - stdout=subprocess.PIPE, - stdin=subprocess.PIPE, - stderr=subprocess.PIPE, - close_fds=True) - ipAddress = serverName - if ps.wait() == 0: - output = ps.communicate() - ipAddress = output[0].split()[-1] - return ipAddress - -def getInstallerIp(): - if not os.path.exists(Globals.INSTALLER_INFO_FILE): - return None - try: - for line in open(Globals.INSTALLER_INFO_FILE): - tokens = line.split("=") - if tokens[0] == "IP-ADDRESS": - return tokens[1].split(",")[0].strip() - except IOError: - syslog.syslog(syslog.LOG_ERR, "unable to read %s file" % Globals.INSTALLER_INFO_FILE) - return False - -def setInstallerIp(installerIp): - try: - open(Globals.INSTALLER_INFO_FILE, "w").write("IP-ADDRESS=%s\n" % installerIp) - return True - except IOError: - log(syslog.LOG_ERR, "unable to create %s file" % Globals.INSTALLER_INFO_FILE) - return False - -def getCurrentServerName(): - try: - for line in open(Globals.SYSCONFIG_NETWORK_FILE): - tokens = line.split("=") - if tokens[0] == "HOSTNAME": - return tokens[1].strip() - except IOError: - syslog.syslog(syslog.LOG_ERR, "unable to read %s file" % Globals.SYSCONFIG_NETWORK_FILE) - return False - -def getLastAccessedNetwork(serverName): - lastAccessedNetworkFile = ("/%s/servers/%s/%s" % - (Globals.GLUSTER_CONF_DIR, serverName, Globals.LAST_ACCESSED_NETWORK_FILE)) - try: - return open(lastAccessedNetworkFile).read().strip() - except IOError: - log(syslog.LOG_ERR, "failed to read last accessed network file %s" % lastAccessedNetworkFile) - pass - return False - -def setLastAccessedNetwork(serverName, ipAddress): - lastAccessedNetworkFile = ("/%s/servers/%s/%s" % - (Globals.GLUSTER_CONF_DIR, serverName, Globals.LAST_ACCESSED_NETWORK_FILE)) - try: - open(lastAccessedNetworkFile, "w").write(ipAddress.strip() + "\n") - except IOError: - log(syslog.LOG_ERR, "failed to write last accessed network file %s" % lastAccessedNetworkFile) - return False - return True - -def getServerIpList(serverName, preferredNetworkOnly=False): - networkXmlFile = ("%s/servers/%s/network.xml" % (Globals.GLUSTER_CONF_DIR, serverName)) - configDom = XDOM() - if not configDom.parseFile(networkXmlFile): - log(syslog.LOG_ERR, "failed to read %s file" % networkXmlFile) - return None - preferredNetwork = configDom.getTextByTagRoute("preferred-network") - ipList = [] - interfaceDom = XDOM() - for tagE in configDom.getElementsByTagName("interface"): - interfaceDom.setDomObj(tagE) - deviceName = interfaceDom.getTextByTagRoute("device") - hostIp = interfaceDom.getTextByTagRoute("ipaddr") - if not hostIp: - continue - if preferredNetworkOnly: - if preferredNetwork.upper() == "ANY" or preferredNetwork.upper() == deviceName.upper(): - ipList.append(hostIp) - else: - ipList.append(hostIp) - if preferredNetworkOnly: - lastAccessedNetworkIp = getLastAccessedNetwork(serverName) - if lastAccessedNetworkIp in ipList: - ipList.remove(lastAccessedNetworkIp) - ipList = [lastAccessedNetworkIp] + ipList - return ipList - -def getServerPreferredIpList(serverName): - return getServerIpList(serverName, True) - -def getExecuteServerList(serverList): - executeServerList = {} - for serverName in serverList: - if serverName == Globals.INSTALLER_SERVER_NAME: - installerIp = getInstallerIp() - if installerIp: - executeServerList[serverName] = [installerIp] - continue - executeServerList[serverName] = getServerPreferredIpList(serverName) - return executeServerList - -def getAllServerList(): - serverList = [] - for filePath in glob.glob("%s/servers/*" % Globals.GLUSTER_CONF_DIR): - if os.path.isdir(filePath): - serverList.append(os.path.basename(filePath)) - try: - serverList.remove(Globals.INSTALLER_SERVER_NAME) - except ValueError: - pass - return serverList - -def getServerNetworkConfigFromLocalFile(serverName): - configDom = XDOM() - configDom.parseFile("%s/servers/%s/network.xml" % (Globals.GLUSTER_CONF_DIR, serverName)) - return configDom - -def updateServerNetworkConfigXmlFile(serverName, serverNetworkDom): - configDom = XDOM() - serverTag = serverNetworkDom.getElementsByTagRoute("server")[0] - configDom.setDomObj(serverTag) - if not configDom.writexml("%s/%s/network.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)): - log("Faild to write xml file %s/%s/network.xml" % (Globals.SERVER_VOLUME_CONF_DIR, serverName)) - -def compareServerNetworkDom(serverNetworkDomA, serverNetworkDomB, requestFlag=True): - command = "command.server." - if not requestFlag: - command = "" - sourceServer = {} - tagText = serverNetworkDomA.getTextByTagRoute("name") - if not tagText: - taxText = None - sourceServer["name"] = tagText - tagText = serverNetworkDomA.getTextByTagRoute("domain-name") - if not tagText: - tagText = None - sourceServer["domain-name"] = tagText - tagText = serverNetworkDomA.getTextByTagRoute("search-domain") - if not tagText: - tagText = None - sourceServer["search-domain"] = tagText - tagText = serverNetworkDomA.getTextByTagRoute("dns1") - if not tagText: - tagText = None - sourceServer["dns1"] = tagText - tagText = serverNetworkDomA.getTextByTagRoute("dns2") - if not tagText: - tagText = None - sourceServer["dns2"] = tagText - tagText = serverNetworkDomA.getTextByTagRoute("dns3") - if not tagText: - tagText = None - sourceServer["dns3"] = tagText - for tagE in serverNetworkDomA.getElementsByTagRoute("interface"): - interfaceDom = XDOM() - interfaceDom.setDomObj(tagE) - sourceServerList = {} - tagText = interfaceDom.getTextByTagRoute("description") - if not tagText: - tagText = None - sourceServerList["description"] = tagText - tagText = interfaceDom.getTextByTagRoute("hwaddr") - if not tagText: - tagText = None - sourceServerList["hwaddr"] = tagText - tagText = interfaceDom.getTextByTagRoute("onboot") - if not tagText: - tagText = None - sourceServerList["onboot"] = tagText - tagText = interfaceDom.getTextByTagRoute("bootproto") - if not tagText: - tagText = None - sourceServerList["bootproto"] = tagText - tagText = interfaceDom.getTextByTagRoute("ipaddr") - if not tagText: - tagText = None - sourceServerList["ipaddr"] = tagText - tagText = interfaceDom.getTextByTagRoute("netmask") - if not tagText: - tagText = None - sourceServerList["netmask"] = tagText - tagText = interfaceDom.getTextByTagRoute("gateway") - if not tagText: - tagText = None - sourceServerList["gateway"] = tagText - sourceServer[interfaceDom.getTextByTagRoute("device")] = sourceServerList - objServer = {} - tagText = serverNetworkDomB.getTextByTagRoute(command + "name") - if not tagText: - taxText = None - objServer["name"] = tagText - tagText = serverNetworkDomB.getTextByTagRoute(command + "domain-name") - if not tagText: - tagText = None - objServer["domain-name"] = tagText - tagText = serverNetworkDomB.getTextByTagRoute(command + "search-domain") - if not tagText: - tagText = None - objServer["search-domain"] = tagText - tagText = serverNetworkDomB.getTextByTagRoute(command + "dns1") - if not tagText: - tagText = None - objServer["dns1"] = tagText - tagText = serverNetworkDomB.getTextByTagRoute(command + "dns2") - if not tagText: - tagText = None - objServer["dns2"] = tagText - tagText = serverNetworkDomB.getTextByTagRoute(command + "dns3") - if not tagText: - tagText = None - objServer["dns3"] = tagText - for tagE in serverNetworkDomB.getElementsByTagRoute(command + "interface"): - interfaceDom = XDOM() - interfaceDom.setDomObj(tagE) - objServerList = {} - tagText = interfaceDom.getTextByTagRoute("description") - if not tagText: - tagText = None - objServerList["description"] = tagText - tagText = interfaceDom.getTextByTagRoute("hwaddr") - if not tagText: - tagText = None - objServerList["hwaddr"] = tagText - tagText = interfaceDom.getTextByTagRoute("onboot") - if not tagText: - tagText = None - objServerList["onboot"] = tagText - tagText = interfaceDom.getTextByTagRoute("bootproto") - if not tagText: - tagText = None - objServerList["bootproto"] = tagText - tagText = interfaceDom.getTextByTagRoute("ipaddr") - if not tagText: - tagText = None - objServerList["ipaddr"] = tagText - tagText = interfaceDom.getTextByTagRoute("netmask") - if not tagText: - tagText = None - objServerList["netmask"] = tagText - tagText = interfaceDom.getTextByTagRoute("gateway") - if not tagText: - tagText = None - objServerList["gateway"] = tagText - objServer[interfaceDom.getTextByTagRoute("device")] = objServerList - return sourceServer == objServer diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/Socket.py b/src/com.gluster.storage.management.server.scripts/src/nodes/Socket.py deleted file mode 100644 index ba6b6ad0..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/Socket.py +++ /dev/null @@ -1,47 +0,0 @@ -import socket -import sys -import Globals - -def openServerSocket(bindAddress="", port=Globals.SERVER_AGENT_PORT): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.bind((bindAddress, port)) - sock.listen(1) - return sock - - -def connectToServer(serverName, port=Globals.SERVER_AGENT_PORT): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect((serverName, port)) - print "__DEBUG__ connected to ", serverName, " on port ", port - inputStream = sock.makefile("r") - outputStream = sock.makefile("w") - return sock, inputStream, outputStream - - -def acceptClient(serverSocket): - clientSocket, clientAddress = serverSocket.accept() - clientInputStream = clientSocket.makefile("r") - clientOutputStream = clientSocket.makefile("w") - return clientSocket, clientAddress, clientInputStream, clientOutputStream - - -def readPacket(inputStream): - packetString = "" - while True: - line = inputStream.readline() - print "__DEBUG__", line - if not line: - break - if line.strip() == "": - # end of input received - return packetString - packetString += line - return packetString - - -def writePacket(outputStream, packetString): - rv = outputStream.write(packetString.strip() + "\n\n") - outputStream.flush() - - diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/VolumeUtils.py b/src/com.gluster.storage.management.server.scripts/src/nodes/VolumeUtils.py deleted file mode 100644 index a19ccd62..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/VolumeUtils.py +++ /dev/null @@ -1,610 +0,0 @@ -# Copyright (c) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import os -import glob -import tempfile -from operator import itemgetter -import Globals -from Protocol import * -from Utils import * -from DiskUtils import * -from ServerUtils import * -import GlusterdUtils as Glusterd - - -def isVolumeExist(volumeName): - volumeDom = XDOM() - return volumeDom.parseFile("%s/%s.xml" % (Globals.VOLUME_CONF_DIR, volumeName)) and \ - Glusterd.isVolumeExist(volumeName) - - -def getVolumeUuid(volumeName): - fileName = "%s/%s.xml" % (Globals.VOLUME_CONF_DIR, volumeName) - volumeDom = XDOM() - if not volumeDom.parseFile(fileName): - log("Failed to parse volume configuration file %s of %s" % (fileName, volumeName)) - return None - return volumeDom.getTextByTagRoute("uuid") - - -def readVolumeSmbConfFile(fileName=Globals.VOLUME_SMBCONF_FILE): - entryList = [] - try: - fp = open(fileName) - for line in fp: - tokens = line.split("#")[0].strip().split(";")[0].strip().split("=") - if len(tokens) != 2: - continue - if tokens[0].strip().upper() == "INCLUDE": - entryList.append(tokens[1].strip()) - fp.close() - except IOError, e: - log("Failed to open file %s: %s" % (fileName, str(e))) - return entryList - - -def writeVolumeSmbConfFile(entryList, fileName=Globals.VOLUME_SMBCONF_FILE): - try: - fp = open(fileName, "w") - for entry in entryList: - fp.write("include = %s\n" % entry) - fp.close() - return True - except IOError, e: - log("Failed to write file %s: %s" % (fileName, str(e))) - return False - - -def includeVolume(volumeName, fileName=Globals.VOLUME_SMBCONF_FILE): - volumeFile = "%s/%s.smbconf" % (Globals.VOLUME_CONF_DIR, volumeName) - if not os.path.exists(volumeFile): - return False - entryList = readVolumeSmbConfFile(fileName) - if volumeFile in entryList: - return True - entryList.append(volumeFile) - return writeVolumeSmbConfFile(entryList, fileName) - - -def excludeVolume(volumeName, fileName=Globals.VOLUME_SMBCONF_FILE): - volumeFile = "%s/%s.smbconf" % (Globals.VOLUME_CONF_DIR, volumeName) - if not os.path.exists(volumeFile): - return False - entryList = readVolumeSmbConfFile(fileName) - if volumeFile not in entryList: - return True - entryList.remove(volumeFile) - log("entryList = %s" % entryList) - return writeVolumeSmbConfFile(entryList, fileName) - - -def writeVolumeCifsConfiguration(volumeName, userList, adminUser=None): - volumeFile = "%s/%s.smbconf" % (Globals.VOLUME_CONF_DIR, volumeName) - try: - fp = open(volumeFile, "w") - fp.write("[%s]\n" % volumeName) - fp.write(" comment = %s volume served by Gluster\n" % volumeName) - fp.write(" path = %s/%s\n" % (Globals.CIFS_EXPORT_DIR, volumeName)) - fp.write(" guest ok = yes\n") - fp.write(" public = yes\n") - fp.write(" writable = yes\n") - if adminUser: - fp.write(" admin users = %s, %s\n" % (adminUser, ", ".join(userList))) - fp.write(" valid users = %s, %s\n" % (adminUser, ", ".join(userList))) - else: - fp.write(" admin users = %s\n" % (", ".join(userList))) - fp.write(" valid users = %s\n" % (", ".join(userList))) - fp.close() - return True - except IOError, e: - log("Failed to write file %s: %s" % (volumeFile, str(e))) - return False - - -def removeVolumeCifsConfiguration(volumeName): - volumeFile = "%s/%s.smbconf" % (Globals.VOLUME_CONF_DIR, volumeName) - try: - os.remove(volumeFile) - except OSError, e: - log("Failed to remove file %s: %s" % (volumeFile, str(e))) - - -def getVolumeListByPartitionName(partitionName): - volumeConfigFileList = glob.glob(Globals.VOLUME_CONF_DIR + "/*.xml") - if not volumeConfigFileList: - return None - - volumeList = [] - for volumeXmlFile in volumeConfigFileList: - volumeDom = XDOM() - volumeDom.parseFile(volumeXmlFile) - serverTopology = volumeDom.getElementsByTagRoute("volume.topology.group") - serverPartitionFound = False - for topology in serverTopology: - partitionDom = XDOM() - for partition in topology.getElementsByTagName("partition"): - partitionDom.setDomObj(partition) - if partitionDom.getTextByTagRoute("name") == partitionName: - serverPartitionFound = True - break - if serverPartitionFound: - volumeList.append(volumeDom.getElementsByTagRoute("volume")[0]) - break - return volumeList - - -def addServerPartitionConfig(inputDom, groupOrder, partitionTag): - if not(inputDom and groupOrder and partitionTag): - return False - groupDom = XDOM() - for group in inputDom.getElementsByTagRoute("topology.group"): - groupDom.setDomObj(group) - order = groupDom.getTextByTagRoute("order") - if order and int(order) == groupOrder: - group.appendChild(partitionTag) - return inputDom - return False - - -def removeServerPartitionConfig(inputDom, partitionName): - if not(inputDom and partitionName): - return False - for group in inputDom.getElementsByTagRoute("topology.group"): - partitionDom = XDOM() - for partition in group.getElementsByTagName("partition"): - partitionDom.setDomObj(partition) - if partitionDom.getTextByTagRoute("name") == partitionName: - group.removeChild(partition) - return inputDom - return False - - -def updateServerPartitionConfig(inputDom, partitionName, partitionTag): - if not(inputDom and partitionName and partitionTag): - return False - for group in inputDom.getElementsByTagRoute("topology.group"): - partitionDom = XDOM() - for partition in group.getElementsByTagName("partition"): - partitionDom.setDomObj(partition) - if partitionDom.getTextByTagRoute("name") == partitionName: - try: - group.replaceChild(partitionTag, partition) - return inputDom - except AttributeError: - return False - return False - - -def getServerPartitionConfigUuid(serverGroupList, serverPartition): - for group in serverGroupList: - if not group: - continue - partitionDom = XDOM() - for partition in group.getElementsByTagName("partition"): - partitionDom.setDomObj(partition) - partitionName = partition.getTextByTagName("name") - if not partitionName: - continue - if partitionName == serverPartition: - return partitionDom.getTextByTagName("uuid") - return False - - -def setServerPartitionConfigProperty(inputDom, partitionName, propertyDict): - if not(inputDom and partitionName and propertyDict): - return False - for group in inputDom.getElementsByTagRoute("topology.group"): - partitionDom = XDOM() - for partition in group.getElementsByTagName("partition"): - partitionDom.setDomObj(partition) - if partitionDom.getTextByTagRoute("name") == partitionName: - for part in propertyDict.keys(): - x = partition.getElementsByTagName(part) - if x: - x[0].childNodes[0].nodeValue = propertyDict[part] - return inputDom - return False - - -def getSortedServerPartitionConfigProperty(inputDom): - groupDict = {} - if not inputDom: - return None - groupDom = XDOM() - for group in inputDom.getElementsByTagRoute("topology.group"): - groupDom.setDomObj(group) - groupOrder = groupDom.getTextByTagRoute("order") - if not groupOrder: - return None - groupOrder = int(groupOrder) - if groupOrder < 1: - return None - partitionDom = XDOM() - partitionDict = {} - for partition in group.getElementsByTagName("partition"): - partitionDom.setDomObj(partition) - partitionName = partitionDom.getTextByTagRoute("name") - if not partitionName: - return None - partitionOrder = partitionDom.getTextByTagRoute("order") - if not partitionOrder: - return None - partitionUuid = partitionDom.getTextByTagRoute("uuid") - partitionOrder = int(partitionOrder) - if partitionOrder < 1: - return None - partitionDetails = partitionName.split(":") - if not partitionDetails or len(partitionDetails) < 1: - return None - partitionDict[partitionOrder] = { "order":partitionOrder, - "servername":partitionDetails[0], - "name":partitionDetails[1], - "uuid":partitionUuid} - groupDict[groupOrder] = partitionDict - - serverList = [] - groupOrderList = groupDict.keys() - groupOrderList.sort() - for groupOrder in groupOrderList: - partitionOrderList = groupDict[groupOrder].keys() - partitionOrderList.sort() - for partitionOrder in partitionOrderList: - serverList.append(groupDict[groupOrder][partitionOrder]) - - return serverList - - -def getSortedServerPartitionList(serverGroupElements): - serverPartitionDict = {} - groupOrderList = [] - serverList = [] - partitionDom = XDOM() - for group in serverGroupElements: - if not group: - continue - groupOrderE = group.getElementsByTagName("order") - if not (groupOrderE and groupOrderE[0].childNodes): - return None - value = int(XDOM.getText(groupOrderE[0].childNodes)) - if value > 0: - groupOrderList.append(value) - partitionDict = {} - for partition in group.getElementsByTagName("partition"): - partitionDom.setDomObj(partition) - - partitionName = partitionDom.getTextByTagRoute("name") - if not partitionName: - return None - partitionOrder = partitionDom.getTextByTagRoute("order") - if not partitionOrder: - return None - partitionUuid = partitionDom.getTextByTagRoute("uuid") - partitionDict[int(partitionOrder)] = [partitionName, partitionUuid] - serverPartitionDict[value] = partitionDict - groupOrderList.sort() - - for groupOrder in groupOrderList: - items = serverPartitionDict[groupOrder].items() - items.sort(key = itemgetter(0)) - serverList = serverList + [ items[i][1] for i in range(0,len(items))] - return serverList - - -def clearExportDirectory(serverList, volumeName, volumeUuid): - thisServerName = getCurrentServerName() - for exportServer in serverList: - serverName, partition = exportServer[0].split(":") - if thisServerName != serverName: - continue - partitionUuid = getUuidByDiskPartition(getDevice(partition)) - if not partitionUuid: - log("unable to find uuid of partition %s" % partition) - return False - volumeDirName = "%s/%s/%s" % (Globals.GLUSTER_LUN_DIR, partitionUuid, volumeUuid) - if os.path.exists(volumeDirName): - ## Removing /data/PARTITION-UUID/VOLUME-UUID/ - ## TODO: Get an option to remove it at this time - if runCommandFG("mv -f %s %s.delete" % (volumeDirName, volumeDirName), root=True) != 0: - return False - if runCommandFG("rm -f %s/%s/volumes/%s" % (Globals.GLUSTER_LUN_DIR, partitionUuid, volumeName), root=True) != 0: - return False - return True - - -def createExportDirectory(serverList, volumeName, volumeUuid): - thisServerName = getCurrentServerName() - tempVolumeNameFile = getTempFileName() - - try: - fp = open(tempVolumeNameFile, "w") - fp.write("VOLUME_NAME=%s\n" % volumeName) - fp.write("VOLUME_UUID=%s\n" % volumeUuid) - fp.close() - except IOError, e: - log("failed to create temporary file for volume-name: %s" % (volumeName, str(e))) - return False - - for exportServer in serverList: - serverName, partition = exportServer[0].split(":") - if thisServerName != serverName: - continue - partitionUuid = getUuidByDiskPartition(getDevice(partition)) - if not partitionUuid: - log("unable to find uuid of partition %s" % partition) - return False - - volumeDirName = "%s/%s/%s" % (Globals.GLUSTER_LUN_DIR, partitionUuid, volumeUuid) - ## Creating /data/PARTITION-UUID/VOLUME-UUID/ - if runCommandFG("mkdir %s" % volumeDirName, root=True) != 0: - return False - - ## Creating /data/PARTITION-UUID/VOLUME-UUID/exports/ - ## Creating /data/PARTITION-UUID/VOLUME-UUID/exports/brick1/ - if runCommandFG("mkdir -p %s/exports/brick1" % volumeDirName, root=True) != 0: - return False - - ## Creating /data/PARTITION-UUID/VOLUME-UUID/log/ - if runCommandFG("mkdir %s/log" % volumeDirName, root=True) != 0: - return False - - ## Creating /data/PARTITION-UUID/VOLUME-UUID/config/ - if runCommandFG("mkdir %s/config" % volumeDirName, root=True) != 0: - return False - - volumeLinkDirName = "%s/%s/volumes" % (Globals.GLUSTER_LUN_DIR, partitionUuid) - if not os.path.exists(volumeLinkDirName): - if runCommandFG("mkdir %s" % volumeLinkDirName, root=True) != 0: - return False - - ## Creating symlink - ## /data/PARTITION-UUID/volumes/VOLUME-NAME -> /data/PARTITION-UUID/VOLUME-UUID/ - command = "ln -fTs %s %s/%s" % (volumeDirName, - volumeLinkDirName, volumeName) - if runCommandFG(command, root=True) != 0: - return False - - if runCommandFG("cp -f %s %s/config/volume-name" % (tempVolumeNameFile, volumeDirName), root=True) != 0: - return False - - try: - os.remove(tempVolumeNameFile) - except OSError, e: - log("Failed to remove file %s: %s" % (tempVolumeNameFile, str(e))) - - return True - - -def getPartitionListByServerName(volumeDom, serverName, serverPartitionList=None): - partitionList = {} - if serverPartitionList: - for partitionName in serverPartitionList: - partitionUuid = getServerDiskPartitionUuid(serverName, partitionName) - if not partitionUuid: - log(syslog.LOG_ERR, "failed to get disk partition %s uuid of server %s" % (partitionName, serverName)) - return None - partitionList[partitionName] = partitionUuid - return partitionList - for group in volumeDom.getElementsByTagRoute("topology.group"): - for partitionTag in group.getElementsByTagName("partition"): - nameE = partitionTag.getElementsByTagName("name") - if not nameE: - continue - partition = XDOM.getText(nameE[0].childNodes) - if not partition: - continue - server, partitionName = partition.split(":") - if server != serverName: - continue - partitionUuid = getServerDiskPartitionUuid(serverName, partitionName) - if not partitionUuid: - log(syslog.LOG_ERR, "failed to get disk partition %s uuid of server %s" % (partitionName, serverName)) - return None - partitionList[partitionName] = partitionUuid - return partitionList - - -def isVolumeRunning(volumeName): - return Glusterd.isVolumeRunning(volumeName) - -def addVolumeMigrationDetails(sourcePartition, destinationPartition, volumeName): - migrationDom = XDOM() - if not os.path.exists(Globals.VOLUME_MIGRATION_LIST_FILE): - migrationDom.appendTagRoute("volume-migration") - else: - if not migrationDom.parseFile(Globals.VOLUME_MIGRATION_LIST_FILE): - log("Failed to load volume-migration.xml file") - return None - migrationList = migrationDom.getElementsByTagRoute("volume-migration.migration") - for tagE in migrationList: - dom = XDOM() - dom.setDomObj(tagE) - if dom.getTextByTagRoute("source-partition") == sourcePartition and \ - dom.getTextByTagRoute("destination-partition") == destinationPartition and \ - dom.getTextByTagRoute("volume-name") == volumeName: - return False - migrationTag = migrationDom.getElementsByTagRoute("volume-migration") - if not migrationTag: - return None - partitionTag = migrationDom.createTag("migration") - partitionTag.appendChild(migrationDom.createTag("source-partition", sourcePartition)) - partitionTag.appendChild(migrationDom.createTag("destination-partition", destinationPartition)) - partitionTag.appendChild(migrationDom.createTag("volume-name", volumeName)) - migrationTag[0].appendChild(partitionTag) - if not migrationDom.writexml(Globals.VOLUME_MIGRATION_LIST_FILE): - log("Unable to write disk migration details into %s/volume-migration.xml" % Globals.GLUSTER_BASE_DIR) - return False - return True - - -def removeVolumeMigrationDetails(sourcePartition, destinationPartition, volumeName): - migrationDom = XDOM() - if not os.path.exists(Globals.VOLUME_MIGRATION_LIST_FILE): - return None - if not migrationDom.parseFile(Globals.VOLUME_MIGRATION_LIST_FILE): - log("Failed to load volume-migration.xml file") - return None - migrationList = migrationDom.getElementsByTagRoute("volume-migration.migration") - for tagE in migrationList: - dom = XDOM() - dom.setDomObj(tagE) - if dom.getTextByTagRoute("source-partition") == sourcePartition and \ - dom.getTextByTagRoute("destination-partition") == destinationPartition and \ - dom.getTextByTagRoute("volume-name") == volumeName: - migrationDom.getElementsByTagRoute("volume-migration")[0].removeChild(tagE) - if not migrationDom.writexml(Globals.VOLUME_MIGRATION_LIST_FILE): - log("Unable to write disk migration details into %s/volume-migration.xml" % Globals.GLUSTER_BASE_DIR) - return False - return True - - -def addPartitionMigrationDetails(sourcePartition, destinationPartition, volumeList=None): - migrationDom = XDOM() - if not os.path.exists(Globals.MIGRATE_PARTITION_LIST_FILE): - migrationDom.appendTagRoute("partition-migration") - else: - if not migrationDom.parseFile(Globals.MIGRATE_PARTITION_LIST_FILE): - log("Failed to load migration.xml file") - return None - migrationList = migrationDom.getElementsByTagRoute("partition-migration.migration") - for tagE in migrationList: - dom = XDOM() - dom.setDomObj(tagE) - if dom.getTextByTagRoute("source-partition") == sourcePartition: - return False - if dom.getTextByTagRoute("destination-partition") == destinationPartition: - return False - migrationTag = migrationDom.getElementsByTagRoute("partition-migration") - if not migrationTag: - return None - partitionTag = migrationDom.createTag("migration") - partitionTag.appendChild(migrationDom.createTag("source-partition", sourcePartition)) - partitionTag.appendChild(migrationDom.createTag("destination-partition", destinationPartition)) - migrationTag[0].appendChild(partitionTag) - if not migrationDom.writexml(Globals.MIGRATE_PARTITION_LIST_FILE): - log("Unable to write disk migration details into %s/migration.xml" % Globals.GLUSTER_BASE_DIR) - return False - if volumeList: - for volumeName in volumeList: - addVolumeMigrationDetails(sourcePartition, destinationPartition, volumeName) - return True - - -def removePartitionMigrationDetails(sourcePartition, destinationPartition, volumeList=None): - migrationDom = XDOM() - if not os.path.exists(Globals.MIGRATE_PARTITION_LIST_FILE): - return None - if not migrationDom.parseFile(Globals.MIGRATE_PARTITION_LIST_FILE): - log("Failed to load migration.xml file") - return None - migrationList = migrationDom.getElementsByTagRoute("partition-migration.migration") - for tagE in migrationList: - dom = XDOM() - dom.setDomObj(tagE) - if dom.getTextByTagRoute("source-partition") == sourcePartition and \ - dom.getTextByTagRoute("destination-partition") == destinationPartition: - migrationDom.getElementsByTagRoute("partition-migration")[0].removeChild(tagE) - if not migrationDom.writexml(Globals.MIGRATE_PARTITION_LIST_FILE): - log("Unable to write disk migration details into %s/migration.xml" % Globals.GLUSTER_BASE_DIR) - return False - if volumeList: - for volumeName in volumeList: - removeVolumeMigrationDetails(sourcePartition, destinationPartition, volumeName) - return True - - -def isMigrationInProgress(partition): - migrationDom = XDOM() - if not os.path.exists(Globals.MIGRATE_PARTITION_LIST_FILE): - return None - if not migrationDom.parseFile(Globals.MIGRATE_PARTITION_LIST_FILE): - log("Failed to load migration.xml file") - return None - migrationList = migrationDom.getElementsByTagRoute("partition-migration.migration") - for tagE in migrationList: - dom = XDOM() - dom.setDomObj(tagE) - if migrationDom.getTextByTagRoute("source-partition") == partition or \ - migrationDom.getTextByTagRoute("destination-partition") == partition: - return True - return False - - -def getServerDiskPartitionUuid(serverName, partition): - diskConfigDom = XDOM() - if not diskConfigDom.parseFile("%s/%s/disk.xml" % (Globals.SERVER_CONF_DIR, serverName)): - return None - for disk in diskConfigDom.getElementsByTagRoute("disks.disk"): - diskDom = XDOM() - diskDom.setDomObj(disk) - partitionList = diskDom.getElementsByTagRoute("partition") - for tagE in partitionList: - partitionDom = XDOM() - partitionDom.setDomObj(tagE) - if partitionDom.getTextByTagRoute("device") == partition: - return partitionDom.getTextByTagRoute("uuid") - - -def getVolumeServerList(requestDom, requestFlag=True): - if requestFlag: - serverGroupElementList = requestDom.getElementsByTagRoute("command.volume.topology.group") - else: - serverGroupElementList = requestDom.getElementsByTagRoute("volume.topology.group") - if not serverGroupElementList: - return None - serverList = [] - partitionDom = XDOM() - for group in serverGroupElementList: - for partition in group.getElementsByTagName("partition"): - partitionDom.setDomObj(partition) - partitionName = partitionDom.getTextByTagRoute("name") - if not partitionName: - continue - serverPartition = partitionName.split(":") - if not(len(serverPartition) > 1 and serverPartition[1]): - return None - if serverPartition[0] not in serverList: - serverList.append(serverPartition[0]) - return serverList - - -def getVolumeServerListByName(volumeName): - serverList = [] - serverDom = XDOM() - volumeDom = XDOM() - if not os.path.exists("%s/%s.xml" % (Globals.VOLUME_CONF_DIR, volumeName)): - return False - if not volumeDom.parseFile("%s/%s.xml" % (Globals.VOLUME_CONF_DIR, volumeName)): - return False - return getVolumeServerList(volumeDom, False) - - -def getMigrateVolumeServerPartitionInfo(volumeName): - volumeMigrationDom = XDOM() - if not volumeMigrationDom.parseFile(Globals.VOLUME_MIGRATION_LIST_FILE): - Utils.log("Failed to parse file %s" % Globals.VOLUME_MIGRATION_LIST_FILE) - return None - volumeInfo = {} - dom = XDOM() - for tagE in volumeMigrationDom.getElementsByTagRoute("volume-migration.migration"): - dom.setDomObj(tagE) - if dom.getTextByTagRoute("volume-name") == volumeName: - volumeInfo['Name'] = volumeName - volumeInfo['SourcePartition'] = dom.getTextByTagRoute("source-partition") - volumeInfo['DestinationPartition'] = dom.getTextByTagRoute("destination-partition") - return volumeInfo - return None diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/XmlHandler.py b/src/com.gluster.storage.management.server.scripts/src/nodes/XmlHandler.py deleted file mode 100644 index 72164ffb..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/XmlHandler.py +++ /dev/null @@ -1,346 +0,0 @@ -# Copyright (C) 2009 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import xml -import xml.parsers.expat -import xml.dom.minidom as MDOM -import os -import Globals -import copy -import Utils - -XML_STRING = 0 -XML_FILE = 1 - -class XDOM: - _domObj = None - - def __init__(self): - self._domObj = MDOM.Document() - return - - @classmethod - def getText(self, nodeList): - rc = "" - for node in nodeList: - if node.nodeType == node.TEXT_NODE: - rc = rc + node.data - return rc - - def parseString(self, requestString): - try: - self._domObj = MDOM.parseString(requestString) - except xml.parsers.expat.ExpatError, e: - Utils.log("XML string parse error: %s" % str(e)) - return False - return True - - def parseFile(self, fileName): - try: - self._domObj = MDOM.parse(fileName) - except IOError, e: - Utils.log("error reading file: %s" % str(e)) - return False - except xml.parsers.expat.ExpatError, e: - Utils.log("XML file %s parse error: %s" % (fileName, str(e))) - return False - return True - - def setDomObj(self, dom): - if dom and type(dom) != type([]): - self._domObj = dom - return True - return False - - def createTag(self, tag, text=None): - if not self._domObj: - return None - if tag == None: - return None - - tagE = self._domObj.createElement(str(tag)) - if text: - tagEText = self._domObj.createTextNode(str(text)) - tagE.appendChild(tagEText) - return tagE - - def addTag(self, tag): - if not self._domObj: - return False - if not tag: - return False - - self._domObj.appendChild(tag) - return True - - def createTagRoute(self, tagRoute, text=None): - if not tagRoute: - return False - - tagList = tagRoute.split(".") - tag = None - previousTag = None - for tagName in tagList[:-1]: - newTag = self.createTag(tagName, None) - if not tag: - tag = newTag - previousTag = newTag - continue - previousTag.appendChild(newTag) - previousTag = newTag - - if previousTag: - previousTag.appendChild(self.createTag(tagList[-1], text)) - else: - tag = self.createTag(tagList[-1], text) - return tag - - def appendTagRoute(self, tagRoute, value=None): - if not self._domObj: - return False - if not tagRoute: - return False - - parentTagE = self._domObj - - tagNameList = tagRoute.split(".") - newTagRoute = tagNameList.pop(-1) - - for i in range(len(tagNameList), 0, -1): - tagE = self.getElementsByTagRoute(".".join(tagNameList[:i])) - if tagE: - parentTagE = tagE[0] - break - newTagRoute = tagNameList[i-1] + "." + newTagRoute - - newTagE = self.createTagRoute(newTagRoute, value) - if not newTagE: - return False - try: - parentTagE.appendChild(newTagE) - except xml.dom.HierarchyRequestErr, e: - Utils.log("error occured. %s" + str(e)) - return False - return True - - def setTextByTagRoute(self, tagRoute, tagValue): - if not self._domObj: - return None - - if not tagRoute: - return None - - tagE = self.getElementsByTagRoute(tagRoute) - if not tagE: - return False - - parentTagE = self.getElementsByTagRoute(".".join(tagRoute.split(".")[:-1])) - if not parentTagE: - return False - - parentTagE[0].childNodes.remove(tagE[0]) - parentTagE[0].appendChild(self.createTag(tagRoute.split(".")[-1], tagValue)) - return True - - def getElementsByTagRoute(self, tagRoute): - if not self._domObj: - return None - - if not tagRoute: - return None - - x = None - for tag in tagRoute.split("."): - if x is None: - x = self._domObj.getElementsByTagName(tag) - continue - if x == []: - break - x = x[0].getElementsByTagName(tag) - return x - - def getTextByTagRoute(self, tagRoute): - if not self._domObj: - return None - - x = self.getElementsByTagRoute(tagRoute) - if x: - return self.getText(x[0].childNodes) - return None - - def getElementsByTagName(self, name): - if not self._domObj: - return None - return self._domObj.getElementsByTagName(name) - - def writexml(self, fileName, indent="", addindent="", newl=""): - if not self._domObj: - return None - try: - fp = open(fileName, "w") - self._domObj.writexml(fp, indent, addindent, newl) - fp.close() - return True - except IOError: - return False - - def toString(self, indent=" ", newl="\n", encoding = None): - if not self._domObj: - return None - return self._domObj.toprettyxml(indent, newl, encoding) - - def toxml(self, encoding = None): - if not self._domObj: - return None - return self._domObj.toxml(encoding) - - def toprettyxml(self, indent=" ", newl="\n", encoding = None): - return self.toString(indent, newl, encoding) - - def createResponseTag(self): - responseTag = self._domObj.createElement("response") - return responseTag -##--end of XDOM - -class RequestXml(XDOM): - def __init__(self, requestString, type=None): - if None == requestString: - XDOM.__init__(self) - return - try: - if None == type: - if os.path.isfile(requestString): - self._domObj = MDOM.parse(requestString) - else: - self._domObj = MDOM.parseString(requestString) - elif XML_FILE == type: - self._domObj = MDOM.parse(requestString) - elif XML_STRING == type: - self._domObj = MDOM.parseString(requestString) - except IOError: - XDOM.__init__(self) - except xml.parsers.expat.ExpatError: - XDOM.__init__(self) - -##--end of RequestXML - - -class ResponseXml(XDOM): - _responseTag = None - def __init__(self): - XDOM.__init__(self) - self._responseTag = self.createResponseTag() - self._domObj.appendChild(self._responseTag) - - @classmethod - def errorResponse(self, message): - if not self.responseTag: - return False - self.appendTagRoute("status.code", "-1"); - self.appendTagRoute("status.message", message) - - def append(self, tagName, tagValue=None): - if not self._responseTag: - return False - tag = self.createTag(tagName, tagValue) - if tag: - self._responseTag.appendChild(tag) - return True - return False - - def appendTag(self, tag): - if not tag: - return False - if not self._responseTag: - return False - self._responseTag.appendChild(tag) - return True - - def appendTagRoute(self, tagRoute, value=None): - if not self._responseTag: - return None - if not tagRoute: - return None - - parentTagE = self._responseTag - - tagNameList = tagRoute.split(".") - newTagRoute = tagNameList.pop(-1) - - for i in range(len(tagNameList), 0, -1): - tagE = self.getElementsByTagRoute(".".join(["response"] + tagNameList[:i])) - if tagE: - parentTagE = tagE[0] - break - newTagRoute = tagNameList[i-1] + "." + newTagRoute - - newTagE = self.createTagRoute(newTagRoute, value) - if not newTagE: - return None - try: - parentTagE.appendChild(newTagE) - except xml.dom.HierarchyRequestErr, e: - Utils.log("error occured. %s" + str(e)) - return None - return newTagE - - def appendTagRouteOld(self, tagRoute, value=None): - if not self._responseTag: - return False - if not tagRoute: - return False - - parentTagE = self._responseTag - - tagNameList = tagRoute.split(".") - newTagRoute = tagNameList.pop(-1) - - for i in range(len(tagNameList), 0, -1): - tagE = self.getElementsByTagRoute(".".join(["response"] + tagNameList[:i])) - if tagE: - parentTagE = tagE[0] - break - newTagRoute = tagNameList[i-1] + "." + newTagRoute - - newTagE = self.createTagRoute(newTagRoute, value) - if not newTagE: - return False - try: - parentTagE.appendChild(newTagE) - except xml.dom.HierarchyRequestErr, e: - Utils.log("error occured. %s" + str(e)) - return False - return True -##--end of ResponseXml - -def test(): - rs = ResponseXml() - rs.appendTagRoute("status.code", "0"); - rs.appendTagRoute("status.message", "SUCCESS") - serverTag = rs.appendTagRoute("server.name", "Server1") - networkInterfaces = rs.appendTagRoute("server.networkInterfaces", None) - networkTag = rs.createTag("networkInterface", None) - networkTag.appendChild(rs.createTag("name", "interface1")) - networkTag.appendChild(rs.createTag("ipaddress", "192.168.1.40")) - networkInterfaces.appendChild(networkTag) - networkTag = rs.createTag("networkInterface", None) - networkTag.appendChild(rs.createTag("name", "interface2")) - networkTag.appendChild(rs.createTag("ipaddress", "192.168.1.41")) - networkInterfaces.appendChild(networkTag) - print rs.toprettyxml() - -#test() diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/clear_volume_directory.py b/src/com.gluster.storage.management.server.scripts/src/nodes/clear_volume_directory.py deleted file mode 100755 index 3bd0ab6f..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/clear_volume_directory.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . -import os -import sys -import syslog -import time -from XmlHandler import ResponseXml -import DiskUtils -import Utils -import Common -from optparse import OptionParser - -def clearVolumeDirectory(disk, volumeName, todelete): - - # Retrieving disk uuid - diskUuid = DiskUtils.getUuidByDiskPartition(DiskUtils.getDevice(disk)) - - rs = ResponseXml() - if not diskUuid: - Common.log(syslog.LOG_ERR, "failed to find disk:%s uuid" % disk) - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "Error: Unable to find disk uuid") - return rs.toprettyxml() - - # Retrieving disk mount point using disk uuid - diskMountPoint = DiskUtils.getMountPointByUuid(diskUuid) - if not os.path.exists(diskMountPoint): - Common.log(syslog.LOG_ERR, "failed to retrieve disk:%s mount point" % disk) - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "Error: Failed to retrieve disk details") - return rs.toprettyxml() - - # clear volume directory from the disk - volumeDirectory = "%s/%s" % (diskMountPoint, volumeName) - newVolumeDirectoryName = "%s_%s" % (volumeDirectory, time.time()) - command = ["sudo", "mv", "-f", volumeDirectory, newVolumeDirectoryName] - rv = Utils.runCommandFG(command, stdout=True, root=True) - message = Common.stripEmptyLines(rv["Stdout"]) - if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) - message += "Error: [%s]" % (error) - Common.log(syslog.LOG_ERR, "failed to rename volume directory %s, %s" % (volumeDirectory, error)) - rs.appendTagRoute("status.code", rv["Status"]) - rs.appendTagRoute("status.message", message) - return rs.toprettyxml() - - if not todelete: - rv["Status"] = "0" - rs.appendTagRoute("status.code", rv["Status"]) - rs.appendTagRoute("status.message", message) - return rs.toprettyxml() - - command = ["sudo", "rm", "-fr", newVolumeDirectoryName] - rv = Utils.runCommandFG(command, stdout=True, root=True) - message = Common.stripEmptyLines(rv["Stdout"]) - if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) - message += "Error: [%s]" % (error) - Common.log(syslog.LOG_ERR, "failed to clear volume directory %s, %s" % (newVolumeDirectoryName, error)) - rs.appendTagRoute("status.code", rv["Status"]) - rs.appendTagRoute("status.message", message) - return rs.toprettyxml() - - if not rv["Status"]: - rv["Status"] = "0" - rs.appendTagRoute("status.code", rv["Status"]) - rs.appendTagRoute("status.message", message) - return rs.toprettyxml() - -def main(): - parser = OptionParser() - parser.add_option("-d", "--delete", dest="deletedir", action="store_true", default=False, help="force delete") - (options, args) = parser.parse_args() - - if len(args) != 2: - print >> sys.stderr, "usage: %s [-d/--delete]" % sys.argv[0] - sys.exit(-1) - - disk = args[0] - volumeName = args[1] - print clearVolumeDirectory(disk, volumeName, options.deletedir) - sys.exit(0) - -if __name__ == "__main__": - main() - diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/create_volume_directory.py b/src/com.gluster.storage.management.server.scripts/src/nodes/create_volume_directory.py deleted file mode 100755 index b8fb2166..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/create_volume_directory.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . -import os -import sys -import syslog -from XmlHandler import ResponseXml -import DiskUtils -import Utils -import Common - -def createDirectory(disk, volumeName): - - # Retrieving disk uuid - diskUuid = DiskUtils.getUuidByDiskPartition(DiskUtils.getDevice(disk)) - - rs = ResponseXml() - if not diskUuid: - Common.log(syslog.LOG_ERR, "failed to find disk:%s uuid" % disk) - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "Error: Unable to find disk uuid") - return rs.toprettyxml() - - # Retrieving disk mount point using disk uuid - diskMountPoint = DiskUtils.getMountPointByUuid(diskUuid) - if not os.path.exists(diskMountPoint): - Common.log(syslog.LOG_ERR, "failed to retrieve disk:%s mount point" % disk) - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "Error: Failed to retrieve disk details") - return rs.toprettyxml() - - # creating volume directory under disk mount point - volumeDirectory = "%s/%s" % (diskMountPoint, volumeName) - if os.path.exists(volumeDirectory): - Common.log(syslog.LOG_ERR, "Volume directory:%s already exists" % (volumeDirectory)) - rs.appendTagRoute("status.code", "-2") - rs.appendTagRoute("status.message", "Volume directory already exists!") - return rs.toprettyxml() - - if not os.path.exists(volumeDirectory): - command = ["sudo", "mkdir", volumeDirectory] - rv = Utils.runCommandFG(command, stdout=True, root=True) - message = Common.stripEmptyLines(rv["Stdout"]) - if rv["Stderr"]: - error = Common.stripEmptyLines(rv["Stderr"]) - message += "Error: [%s]" % (error) - Common.log(syslog.LOG_ERR, "failed to create volume directory %s, %s" % (volumeDirectory, error)) - rs.appendTagRoute("status.code", rv["Status"]) - rs.appendTagRoute("status.message", message) - return rs.toprettyxml() - - if not rv["Status"]: - rv["Status"] = "0" - if rv["Status"] == "0": - message = volumeDirectory - rs.appendTagRoute("status.code", rv["Status"]) - rs.appendTagRoute("status.message", message) - return rs.toprettyxml() - -def main(): - if len(sys.argv) != 3: - print >> sys.stderr, "usage: %s " % sys.argv[0] - sys.exit(-1) - - disk = sys.argv[1] - volumeName = sys.argv[2] - print createDirectory(disk, volumeName) - sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/get_disk_mount_point.py b/src/com.gluster.storage.management.server.scripts/src/nodes/get_disk_mount_point.py deleted file mode 100755 index b2274b4d..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/get_disk_mount_point.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import os -import syslog -import Common -from DiskUtils import * -from XmlHandler import ResponseXml - - -def getmountpoint(path): - if not path: - Common.log(syslog.LOG_ERR, "Not a valid path:%s" % path) - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "Error: given path name is empty") - return rs.toprettyxml() - - rs = ResponseXml() - mountPoint = None - - for line in readFsTab(): - if path.startswith(line['MountPoint']): - if not mountPoint: - mountPoint = line['MountPoint'] - if len(line['MountPoint']) > len(mountPoint): - mountPoint = line['MountPoint'] - - if "/" == mountPoint or not mountPoint: - Common.log(syslog.LOG_ERR, "failed to find mount point of the given path:%s" % path) - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "Error: Unable to find disk mount point") - return rs.toprettyxml() - - rs.appendTagRoute("status.code", "0") - rs.appendTagRoute("status.message", mountPoint) - return rs.toprettyxml() - -def main(): - if len(sys.argv) != 2: - print >> sys.stderr, "usage: %s " % sys.argv[0] - sys.exit(-1) - - path = sys.argv[1] - print getmountpoint(path) - sys.exit(0) - -if __name__ == "__main__": - main() - diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/get_disk_name_by_path.py b/src/com.gluster.storage.management.server.scripts/src/nodes/get_disk_name_by_path.py deleted file mode 100755 index 72eb80dd..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/get_disk_name_by_path.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import os -import syslog -import Common -from DiskUtils import * -from XmlHandler import ResponseXml - - -def getmountpoint(path): - if not path: - Common.log(syslog.LOG_ERR, "Not a valid path:%s" % path) - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "Error: given path name is empty") - return rs.toprettyxml() - - rs = ResponseXml() - mountPoint = None - fsTabEntry = None - for line in readFsTab(): - if path.startswith(line['MountPoint']): - if not mountPoint: - mountPoint = line['MountPoint'] - fsTabEntry = line - if len(line['MountPoint']) > len(mountPoint): - mountPoint = line['MountPoint'] - fsTabEntry = line - - if "/" == mountPoint or not mountPoint: - Common.log(syslog.LOG_ERR, "failed to find mount point of the given path:%s" % path) - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "Error: Unable to find disk mount point") - return rs.toprettyxml() - - rs.appendTagRoute("status.code", "0") - if fsTabEntry["Device"].startswith("UUID="): - rs.appendTagRoute("status.message", getDiskPartitionByUuid(fsTabEntry["Device"].split("UUID=")[-1])) - else: - rs.appendTagRoute("status.message", "Unable to find disk name") - return rs.toprettyxml() - -def main(): - if len(sys.argv) != 2: - print >> sys.stderr, "usage: %s " % sys.argv[0] - sys.exit(-1) - - path = sys.argv[1] - print getmountpoint(path) - sys.exit(0) - -if __name__ == "__main__": - main() - diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/get_file.py b/src/com.gluster.storage.management.server.scripts/src/nodes/get_file.py deleted file mode 100755 index 826ade6e..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/get_file.py +++ /dev/null @@ -1,132 +0,0 @@ -# Copyright (C) 2009,2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import Globals -import syslog -import Commands -import Utils -from VolumeUtils import * -from XmlHandler import ResponseXml - - -def enumLogType(logCode): - if "M" == logCode.upper(): - return "EMERGENCY" - elif "A" == logCode.upper(): - return "ALERT" - elif "C" == logCode.upper(): - return "CRITICAL" - elif "E" == logCode.upper(): - return "ERROR" - elif "W" == logCode.upper(): - return "WARNING" - elif "N" == logCode.upper(): - return "NOTICE" - elif "I" == logCode.upper(): - return "INFO" - elif "D" == logCode.upper(): - return "DEBUG" - elif "T" == logCode.upper(): - return "TRACE" - else: - return "UNKNOWN" -##--end of enumLogType() - - -def addLog(responseDom, logMessageTag, loginfo): - logTag = responseDom.createTag("log", None) - logTag.appendChild(responseDom.createTag("date", loginfo[0])) - logTag.appendChild(responseDom.createTag("time", loginfo[1])) - logTag.appendChild(responseDom.createTag("type", enumLogType(loginfo[2]))) - logTag.appendChild(responseDom.createTag("message", loginfo[3])) - logMessageTag.appendChild(logTag) - return True -##--end of addLog() - - -def logSplit(log): - loginfo = log.strip().split(None, 3) - loginfo[0] = loginfo[0][1:] #-- Remove '[' - loginfo[1] = loginfo[1][0:-1] #-- Remove ']' - return loginfo -##--end of logSplit() - - -def getVolumeLog(volumeName, tailCount): - rs = ResponseXml() - if not volumeName: - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "No volume name given") - return rs.toprettyxml() - - if not tailCount: - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "No tail count given") - return rs.toprettyxml() - - thisServerName = getCurrentServerName() - if not thisServerName: - rs.appendTagRoute("status.code", "-2") - rs.appendTagRoute("status.message", "Failed to get current server name") - return rs.toprettyxml() - - volumeDom = XDOM() - partitionList = getPartitionListByServerName(volumeDom, thisServerName) - if not partitionList: - rs.appendTagRoute("status.code", "-3") - rs.appendTagRoute("status.message", "Failed to get server partition details") - return rs.toprettyxml() - - pattern = '\[\d{4}-\d{2}-\d{2}\s{1}\d{2}:\d{2}:\d{2}.\d+\]\s{1}([MACEWNIDT]){1}\s+' - logMessagesTag = rs.createTag("response.logMessages") - for partitionName in partitionList: - logMessageTag = rs.createTag("logMessage") - logMessageTag.appendChild("disk", "%s:%s" % (thisServerName, partitionName)) - - logDirectory = "%s/%s/%s/log" % (Globals.GLUSTER_LUN_DIR, partitionList[partitionName], volumeUuid) - logFileName = "%s/%s-%s-%s-exports-brick1.log" % (logDirectory, - Globals.GLUSTER_LUN_DIR[1:], - partitionList[partitionName], - volumeUuid) - if not os.path.exists(logFileName): - Utils.log("volume log file not found %s" % logFileName) - continue - fp = open(logFileName) - lines = [line for line in fp if re.match(pattern, line)] - fp.close() - i = len(lines) - int(tailCount) - if i < 0: - i = 0 - for log in lines[i:]: - loginfo = logSplit(log) - addLog(rs, logMessageTag, loginfo) - logMessagesTag.appendChild(logMessageTag) - return rs.toprettyxml() -##--end of getVolumeLog() - -def main(): - if len(sys.argv) != 3: - print >> sys.stderr, "usage: %s " % sys.argv[0] - sys.exit(-1) - - volumeName = sys.argv[1] - tailCount = sys.argv[2] - print getVolumeLog(volumeName, tailCount) - sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/get_server_details.py b/src/com.gluster.storage.management.server.scripts/src/nodes/get_server_details.py deleted file mode 100755 index 2253ff30..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/get_server_details.py +++ /dev/null @@ -1,224 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2009 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import sys -import syslog -import socket -import Globals -import Commands -import re -from ServerUtils import * -from Protocol import * -from NetworkUtils import * -from Disk import * -from XmlHandler import ResponseXml - -def getDiskSizeInfo(partition): - # get values from df output - total = None - used = None - free = None - commandList = ['df', '-kl', '-t', 'ext3', '-t', 'ext4'] - commandOutput = "" - try: - process = subprocess.Popen(commandList, - stdout=subprocess.PIPE, - stdin=subprocess.PIPE, - stderr=subprocess.PIPE, - close_fds=True) - status = process.wait() - if status == 0: - commandOutput = process.communicate() - except OSError: - return None,None,None - - for line in commandOutput[0].split("\n"): - tokens = line.split() - if len(tokens) < 4: - continue - if tokens[0] == partition: - total = int(tokens[1]) / 1024.0 - used = int(tokens[2]) / 1024.0 - free = int(tokens[3]) / 1024.0 - break - - if total: - return total, used, free - - # get total size from parted output - for i in range(len(partition), 0, -1): - pos = i - 1 - if not partition[pos].isdigit(): - break - disk = partition[:pos+1] - number = int(partition[pos+1:]) - - commandList = ['parted', '-ms', disk, 'unit', 'kb', 'print'] - commandOutput = "" - try: - process = subprocess.Popen(commandList, - stdout=subprocess.PIPE, - stdin=subprocess.PIPE, - stderr=subprocess.PIPE, - close_fds=True) - status = process.wait() - if status == 0: - commandOutput = process.communicate() - except OSError: - return None,None,None - - lines = commandOutput[0].split(";\n") - if len(lines) < 3: - return None,None,None - - for line in lines[2:]: - tokens = line.split(':') - if len(tokens) < 4: - continue - if tokens[0] == str(number): - total = int(tokens[3].split('kB')[0]) / 1024.0 - break - - return total, used, free - -def getServerDetails(): - serverName = socket.gethostname() - responseDom = ResponseXml() - #responseDom.appendTagRoute("status.code", "0") - #responseDom.appendTagRoute("status.message", "success") - serverTag = responseDom.appendTagRoute("server") - serverTag.appendChild(responseDom.createTag("name", serverName)) - - nameServerList, domain, searchDomain = readResolvConfFile() - if domain: - domainName = domain[0] - else: - domainName = None - serverTag.appendChild(responseDom.createTag("domainname", domainName)) - i = 1 - for dns in nameServerList: - serverTag.appendChild(responseDom.createTag("dns%s" % i, dns)) - i += 1 - #TODO: probe and retrieve timezone, ntp-server, preferred-network details and update the tags - - deviceList = {} - interfaces = responseDom.createTag("networkInterfaces", None) - for device in getNetDeviceList(): - deviceList[device["device"]] = device - try: - macAddress = open("/sys/class/net/%s/address" % device["device"]).read().strip() - except IOError: - continue - interfaceTag = responseDom.createTag("networkInterface", None) - interfaceTag.appendChild(responseDom.createTag("name", device["device"])) - interfaceTag.appendChild(responseDom.createTag("hwAddr", macAddress)) - interfaceTag.appendChild(responseDom.createTag("speed", device["speed"])) - interfaceTag.appendChild(responseDom.createTag("model", device["model"])) - if deviceList[device["device"]]: - if deviceList[device["device"]]["onboot"]: - interfaceTag.appendChild(responseDom.createTag("onboot", "yes")) - else: - interfaceTag.appendChild(responseDom.createTag("onBoot", "no")) - interfaceTag.appendChild(responseDom.createTag("bootProto", deviceList[device["device"]]["bootproto"])) - interfaceTag.appendChild(responseDom.createTag("ipAddress", deviceList[device["device"]]["ipaddr"])) - interfaceTag.appendChild(responseDom.createTag("netMask", deviceList[device["device"]]["netmask"])) - interfaceTag.appendChild(responseDom.createTag("defaultGateway", deviceList[device["device"]]["gateway"])) - if deviceList[device["device"]]["mode"]: - interfaceTag.appendChild(responseDom.createTag("mode", deviceList[device["device"]]["mode"])) - if deviceList[device["device"]]["master"]: - interfaceTag.appendChild(responseDom.createTag("bonding", "yes")) - spliter = re.compile(r'[\D]') - interfaceTag.appendChild(responseDom.createTag("bondid", spliter.split(device["master"])[-1])) - else: - interfaceTag.appendChild(responseDom.createTag("onBoot", "no")) - interfaceTag.appendChild(responseDom.createTag("bootProto", "none")) - interfaces.appendChild(interfaceTag) - serverTag.appendChild(interfaces) - - responseDom.appendTag(serverTag) - serverTag.appendChild(responseDom.createTag("numOfCPUs", int(os.sysconf('SC_NPROCESSORS_ONLN')))) - - try: - meminfo = getMeminfo() - mem_total = meminfo['MemTotal'] - mem_free = meminfo['MemFree'] - mem_used = (mem_total - mem_free) - value = "%.2f" % (1.0 * mem_used / mem_total) - mem_percent = 100 * float(value) - cpu = 100 * float(getLoadavg()) - - except IOError: - print "Error" - responseDom.appendTagRoute("server.name", serverName) - syslog.syslog(syslog.LOG_ERR, "Error finding memory information of server:%s" % serverName) - return None - - diskObj = Disk() - ## disks = diskObj.getDiskList() - disks = diskObj.getMountableDiskList() - - if disks is None: - print "No disk found!" - syslog.syslog(syslog.LOG_ERR, "Error finding disk information of server:%s" % serverName) - return None - - serverTag.appendChild(responseDom.createTag("cpuUsage", str(cpu))) - #serverTag.appendChild(responseDom.createTag("totalMemory", str(mem_percent))) - serverTag.appendChild(responseDom.createTag("totalMemory", str(mem_total))) - serverTag.appendChild(responseDom.createTag("memoryInUse", str(mem_used))) - 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 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 = 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", "READY")) - 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))) - return serverTag - -def main(): - print getServerDetails().toxml() - sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/get_volume_brick_log.py b/src/com.gluster.storage.management.server.scripts/src/nodes/get_volume_brick_log.py deleted file mode 100755 index 7c912412..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/get_volume_brick_log.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2009,2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import re -import os -import sys -from XmlHandler import ResponseXml - -def enumLogType(logCode): - if "M" == logCode.upper(): - return "EMERGENCY" - elif "A" == logCode.upper(): - return "ALERT" - elif "C" == logCode.upper(): - return "CRITICAL" - elif "E" == logCode.upper(): - return "ERROR" - elif "W" == logCode.upper(): - return "WARNING" - elif "N" == logCode.upper(): - return "NOTICE" - elif "I" == logCode.upper(): - return "INFO" - elif "D" == logCode.upper(): - return "DEBUG" - elif "T" == logCode.upper(): - return "TRACE" - else: - return "UNKNOWN" -##--end of enumLogType() - -def addLog(responseDom, logMessageTag, loginfo): - logTag = responseDom.createTag("logMessage", None) - logTag.appendChild(responseDom.createTag("timestamp", loginfo[0] + " " + loginfo[1])) - logTag.appendChild(responseDom.createTag("severity", enumLogType(loginfo[2]))) - logTag.appendChild(responseDom.createTag("message", loginfo[3])) - logMessageTag.appendChild(logTag) - return True -##--end of addLog() - -def logSplit(log): - loginfo = log.strip().split(None, 3) - loginfo[0] = loginfo[0][1:] #-- Remove '[' - loginfo[1] = loginfo[1][0:-1] #-- Remove ']' - return loginfo -##--end of logSplit() - -def getVolumeLog(logFilePath, tailCount): - rs = ResponseXml() - if not logFilePath: - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "No log file path given") - return rs.toprettyxml() - - if not tailCount: - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "No tail count given") - return rs.toprettyxml() - - pattern = '\[\d{4}-\d{2}-\d{2}\s{1}\d{2}:\d{2}:\d{2}.\d+\]\s{1}([MACEWNIDT]){1}\s+' - logMessagesTag = rs.createTag("logMessages") - if not os.path.exists(logFilePath): - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "volume log file [%s] not found!" % logFilePath) - return rs.toprettyxml - - fp = open(logFilePath) - #lines = [line for line in fp] - lines = [line for line in fp if re.match(pattern, line)] - fp.close() - i = len(lines) - int(tailCount) - if i < 0: - i = 0 - for log in lines[i:]: - loginfo = logSplit(log) - addLog(rs, logMessagesTag, loginfo) - rs.appendTagRoute("status.code", "0") - rs.appendTagRoute("status.message", "Success") - rs.appendTag(logMessagesTag) - return rs.toprettyxml() -##--end of getVolumeLog() - -def main(): - if len(sys.argv) != 3: - print >> sys.stderr, "usage: %s " % sys.argv[0] - sys.exit(-1) - - logFilePath = sys.argv[1] - tailCount = sys.argv[2] - print getVolumeLog(logFilePath, tailCount) - sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/get_volume_log.py b/src/com.gluster.storage.management.server.scripts/src/nodes/get_volume_log.py deleted file mode 100755 index 826ade6e..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/get_volume_log.py +++ /dev/null @@ -1,132 +0,0 @@ -# Copyright (C) 2009,2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import Globals -import syslog -import Commands -import Utils -from VolumeUtils import * -from XmlHandler import ResponseXml - - -def enumLogType(logCode): - if "M" == logCode.upper(): - return "EMERGENCY" - elif "A" == logCode.upper(): - return "ALERT" - elif "C" == logCode.upper(): - return "CRITICAL" - elif "E" == logCode.upper(): - return "ERROR" - elif "W" == logCode.upper(): - return "WARNING" - elif "N" == logCode.upper(): - return "NOTICE" - elif "I" == logCode.upper(): - return "INFO" - elif "D" == logCode.upper(): - return "DEBUG" - elif "T" == logCode.upper(): - return "TRACE" - else: - return "UNKNOWN" -##--end of enumLogType() - - -def addLog(responseDom, logMessageTag, loginfo): - logTag = responseDom.createTag("log", None) - logTag.appendChild(responseDom.createTag("date", loginfo[0])) - logTag.appendChild(responseDom.createTag("time", loginfo[1])) - logTag.appendChild(responseDom.createTag("type", enumLogType(loginfo[2]))) - logTag.appendChild(responseDom.createTag("message", loginfo[3])) - logMessageTag.appendChild(logTag) - return True -##--end of addLog() - - -def logSplit(log): - loginfo = log.strip().split(None, 3) - loginfo[0] = loginfo[0][1:] #-- Remove '[' - loginfo[1] = loginfo[1][0:-1] #-- Remove ']' - return loginfo -##--end of logSplit() - - -def getVolumeLog(volumeName, tailCount): - rs = ResponseXml() - if not volumeName: - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "No volume name given") - return rs.toprettyxml() - - if not tailCount: - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "No tail count given") - return rs.toprettyxml() - - thisServerName = getCurrentServerName() - if not thisServerName: - rs.appendTagRoute("status.code", "-2") - rs.appendTagRoute("status.message", "Failed to get current server name") - return rs.toprettyxml() - - volumeDom = XDOM() - partitionList = getPartitionListByServerName(volumeDom, thisServerName) - if not partitionList: - rs.appendTagRoute("status.code", "-3") - rs.appendTagRoute("status.message", "Failed to get server partition details") - return rs.toprettyxml() - - pattern = '\[\d{4}-\d{2}-\d{2}\s{1}\d{2}:\d{2}:\d{2}.\d+\]\s{1}([MACEWNIDT]){1}\s+' - logMessagesTag = rs.createTag("response.logMessages") - for partitionName in partitionList: - logMessageTag = rs.createTag("logMessage") - logMessageTag.appendChild("disk", "%s:%s" % (thisServerName, partitionName)) - - logDirectory = "%s/%s/%s/log" % (Globals.GLUSTER_LUN_DIR, partitionList[partitionName], volumeUuid) - logFileName = "%s/%s-%s-%s-exports-brick1.log" % (logDirectory, - Globals.GLUSTER_LUN_DIR[1:], - partitionList[partitionName], - volumeUuid) - if not os.path.exists(logFileName): - Utils.log("volume log file not found %s" % logFileName) - continue - fp = open(logFileName) - lines = [line for line in fp if re.match(pattern, line)] - fp.close() - i = len(lines) - int(tailCount) - if i < 0: - i = 0 - for log in lines[i:]: - loginfo = logSplit(log) - addLog(rs, logMessageTag, loginfo) - logMessagesTag.appendChild(logMessageTag) - return rs.toprettyxml() -##--end of getVolumeLog() - -def main(): - if len(sys.argv) != 3: - print >> sys.stderr, "usage: %s " % sys.argv[0] - sys.exit(-1) - - volumeName = sys.argv[1] - tailCount = sys.argv[2] - print getVolumeLog(volumeName, tailCount) - sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/src/com.gluster.storage.management.server.scripts/src/nodes/multicast_response.py b/src/com.gluster.storage.management.server.scripts/src/nodes/multicast_response.py deleted file mode 100644 index dba65c07..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/nodes/multicast_response.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2009 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import os -import string -import time -import Utils -import socket -import struct -import Globals - -def isinpeer(): - command = "gluster peer status" - status = Utils.runCommand(command, output=True, root=True) - if status["Status"] == 0: - return True - #lines = status["Stdout"].split("\n") - #for line in lines: - # if string.upper(line).startswith("HOSTNAME: %s" % string.upper(socket.gethostname)): - # return True - Utils.log("command [%s] failed with [%d:%s]" % (command, status["Status"], os.strerror(status["Status"]))) - return False - -def response(multiCastGroup, port): - # waiting for the request! - socketRequest = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) - socketRequest.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - socketRequest.bind(('', port)) - mreq = struct.pack("4sl", socket.inet_aton(multiCastGroup), socket.INADDR_ANY) - socketRequest.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) - - socketSend = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) - socketSend.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) - - #TODO: Remove infinite loop and make this as a deamon (service) - while True: - if isinpeer(): - time.sleep(5) - continue - request = socketRequest.recvfrom(1024) - if request and request[0].upper() == "SERVERDISCOVERY": - socketSend.sendto(socket.gethostname(), (multiCastGroup, port)) - request = None - -def main(): - response(Globals.MULTICAST_GROUP, Globals.MULTICAST_PORT) - -if __name__ == "__main__": - main() diff --git a/src/com.gluster.storage.management.server.scripts/src/server/RemoteExecute.py b/src/com.gluster.storage.management.server.scripts/src/server/RemoteExecute.py deleted file mode 100644 index 1800234f..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/server/RemoteExecute.py +++ /dev/null @@ -1,287 +0,0 @@ -# Copyright (C) 2010 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import os -import socket -#import paramiko -import syslog -import sys -import Socket -import Globals -from copy import deepcopy -from ServerUtils import * - -SERVER_AGENT_COMMAND = "/usr/sbin/server-agent" -SERVER_AGENT_CLEANUP_COMMAND = SERVER_AGENT_COMMAND + " --cleanup" -SERVER_AGENT_PRE_COMMAND = SERVER_AGENT_COMMAND + " --pre" -SERVER_AGENT_POST_COMMAND = SERVER_AGENT_COMMAND + " --post" -TRANSPORT_USER_NAME = "transport" -TRANSPORT_PRIVATE_KEY_FILE = Globals.TRANSPORT_HOME_DIR + "/.ssh/id_rsa" - -def remoteExecute(serverList, command, commandInput=None): - print "REMOTE:", serverList - statusDict = {} - ssh = paramiko.SSHClient() - ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - try: - privateKey = paramiko.RSAKey.from_private_key_file(TRANSPORT_PRIVATE_KEY_FILE) - except IOError: - log(syslog.LOG_ERR, "Private key file %s not found" % TRANSPORT_PRIVATE_KEY_FILE) - return None - print "STAGE1" - for serverName in serverList.keys(): - serverStatus = {} - serverStatus["ConnectionStatus"] = None - serverStatus["ExecutionStatus"] = None - serverStatus["StdOutString"] = None - serverStatus["StdErrString"] = None - serverStatus["ConnectedIp"] = None - serverStatus["Error"] = None - - isConnected = False - for serverIp in serverList[serverName]: - try: - ssh.connect(serverIp, username=TRANSPORT_USER_NAME, pkey=privateKey) - isConnected = True - break - except socket.error: - log(syslog.LOG_ERR, "Server %s:%s is inaccessible" % (serverName, serverIp)) - continue - if not isConnected: - serverStatus["ConnectionStatus"] = "inaccessible" - statusDict[serverName] = serverStatus - continue - - try: - transport = ssh.get_transport() - channel = transport.open_session() - serverStatus["ConnectionStatus"] = True - channel.exec_command(command) - stdin = channel.makefile('wb') - stdout = channel.makefile('rb') - stderr = channel.makefile_stderr('rb') - if commandInput: - stdin.write(commandInput) - channel.shutdown_write() - - returnValue = channel.recv_exit_status() ## this is blocking call - serverStatus["ExecutionStatus"] = returnValue - print "RRRRRRRRRRRRRRRR:", returnValue - errorString = "" - if -1 == returnValue: - errorString = stderr.read() - serverStatus["StdErrString"] = errorString - if "bash: " + command.split()[0] + ": command not found\n" == errorString: - log(syslog.LOG_ERR, "command %s not found in server %s" % (command, serverName)) - serverStatus["Error"] = "Command not found" - else: - serverStatus["StdErrString"] = stderr.read() - serverStatus["StdOutString"] = stdout.read() - ssh.close() - except paramiko.SSHException: - # Channel error (channel not open) - log(syslog.LOG_ERR, "Server %s:%s connection aborted" % (serverName, serverIp)) - serverStatus["ConnectionStatus"] = "aborted" - except socket.error: - log(syslog.LOG_ERR, "Server %s:%s is inaccessible" % (serverName, serverIp)) - serverStatus["ConnectionStatus"] = "inaccessible" - except paramiko.AuthenticationException: - log(syslog.LOG_ERR, "Authentication error on server %s:%s of user %s" % - (serverName, serverIp, TRANSPORT_USER_NAME)) - serverStatus["ConnectionStatus"] = "authentication error" - serverStatus["ConnectedIp"] = serverIp - statusDict[serverName] = serverStatus - return statusDict - -def cleanupExecuteSsh(serverList, requestDom): - return remoteExecute(serverList, SERVER_AGENT_CLEANUP_COMMAND, requestDom.toxml()) - -def executeRequestCommandSsh(serverList, command, requestDom, cleanupFlag): - cleanupStatusDict = {} - successStatusDict = {} - failureServerList = {} - cleanupServerList = {} - serverList = deepcopy(serverList) - statusDict = remoteExecute(serverList, command, requestDom.toxml()) - for serverName in statusDict.keys(): - statusDict["Response"] = None - if statusDict[serverName]["ConnectionStatus"] == True: - setLastAccessedNetwork(serverName, statusDict[serverName]["ConnectedIp"]) - if statusDict[serverName]["ConnectedIp"]: - ipList = serverList[serverName] - ipList.remove(statusDict[serverName]["ConnectedIp"]) - cleanupServerList[serverName] = [statusDict[serverName]["ConnectedIp"]] + ipList - if statusDict[serverName]["ExecutionStatus"] != 0: - failureServerList[serverName] = statusDict[serverName] - continue - responseDom = XDOM() - if not responseDom.parseString(statusDict[serverName]["StdOutString"]): - failureServerList[serverName] = statusDict[serverName] - continue - statusDict["Response"] = responseDom - if "OK" != responseDom.getAttribute("response-code"): - failureServerList[serverName] = statusDict[serverName] - continue - successStatusDict[serverName] = statusDict[serverName] - if cleanupFlag and failureServerList: - cleanupStatusDict = remoteExecute(cleanupServerList, SERVER_AGENT_CLEANUP_COMMAND, requestDom.toxml()) - return successStatusDict, failureServerList, cleanupStatusDict - -def preExecuteSsh(serverList, requestDom, cleanupFlag=True): - return executeRequestCommandSsh(serverList, SERVER_AGENT_PRE_COMMAND, requestDom, cleanupFlag) - -def executeSsh(serverList, requestDom, cleanupFlag=True): - return executeRequestCommandSsh(serverList, SERVER_AGENT_COMMAND, requestDom, cleanupFlag) - -def postExecuteSsh(serverList, requestDom, cleanupFlag=True): - return executeRequestCommandSsh(serverList, SERVER_AGENT_POST_COMMAND, requestDom, cleanupFlag) - -def runPullUpdatesDir(sourceServerIp, destServerIpList): - command = "/usr/sbin/pull-dir.sh %s %s %s" % (sourceServerIp, - Globals.UPDATES_DIR[1:], - Globals.UPDATES_DIR) - statusDict = remoteExecute(destServerIpList, command) - status = True - for serverName in statusDict.keys(): - if statusDict[serverName]["ExecutionStatus"] != 0: - log(syslog.LOG_ERR, "Failed to execute [%s] in server %s" % (command, serverName)) - status = False - return status - -def runPullGlusterDir(sourceServerIp, destServerIpList): - command = "/usr/sbin/pull-dir.sh %s %s %s" % (sourceServerIp, - Globals.GLUSTER_BASE_DIR[1:], - Globals.GLUSTER_BASE_DIR) - statusDict = remoteExecute(destServerIpList, command) - status = True - for serverName in statusDict.keys(): - if statusDict[serverName]["ExecutionStatus"] != 0: - log(syslog.LOG_ERR, "Failed to execute [%s] in server %s" % (command, serverName)) - status = False - return status - -def syncConfiguration(syncToInstaller=False, sourceServerIpList=None): - thisServerName = getCurrentServerName() - serverList = getAllServerList() - serverList.remove(thisServerName) - serverIpList = getExecuteServerList(serverList) - if syncToInstaller: - installerIp = getInstallerIp() - if not installerIp: - log(syslog.LOG_ERR, "Installer IP address is not found") - return False - serverIpList[Globals.INSTALLER_SERVER_NAME] = [installerIp] - - if not serverIpList: - log(syslog.LOG_ERR, "No servers found for sync configuration") - return False - - signature = generateSignature() - if not storeSignature(signature, Globals.SIGNATURE_FILE): - log(syslog.LOG_ERR, "failed to store signature %s to %s file" % - (signature, Globals.SIGNATURE_FILE)) - return False - - thisServerIpList = getExecuteServerList([thisServerName]) - if sourceServerIpList: - thisServerIpList = sourceServerIpList - return runPullGlusterDir(thisServerIpList[thisServerName][0], serverIpList) - -def remoteExecuteTcp(serverIpList, requestString): - serverStatus = {} - serverStatus["ConnectionStatus"] = False - serverStatus["ExecutionStatus"] = -1 - serverStatus["StdOutString"] = None - serverStatus["StdErrString"] = None - serverStatus["ConnectedIp"] = None - serverStatus["Error"] = None - - for ipAddress in serverIpList.values()[0]: - try: - sock, inputStream, outputStream = Socket.connectToServer(ipAddress) - Socket.writePacket(outputStream, requestString) - packetString = Socket.readPacket(inputStream) - log('__DEBUG__ Received: %s' % repr(packetString)) - sock.close() - serverStatus["ConnectionStatus"] = True - serverStatus["ExecutionStatus"] = 0 - serverStatus["StdOutString"] = packetString - serverStatus["StdErrString"] = None - serverStatus["ConnectedIp"] = ipAddress - serverStatus["Error"] = None - return serverStatus - except socket.error, e: - log("socket error on [%s:%s]: %s" % (serverIpList.keys()[0], ipAddress, str(e))) - return serverStatus - -def executeRequestCommand(serverList, command, requestDom, cleanupFlag): - cleanupStatusDict = {} - successStatusDict = {} - failureServerList = {} - cleanupServerList = {} - serverList = deepcopy(serverList) - - statusDict = {} - for serverName in serverList.keys(): - serverStatus = remoteExecuteTcp({serverName : serverList[serverName]}, requestDom.toxml()) - statusDict[serverName] = serverStatus - for serverName in statusDict.keys(): - statusDict["Response"] = None - if statusDict[serverName]["ConnectionStatus"] == True: - setLastAccessedNetwork(serverName, statusDict[serverName]["ConnectedIp"]) - if statusDict[serverName]["ConnectedIp"]: - ipList = serverList[serverName] - ipList.remove(statusDict[serverName]["ConnectedIp"]) - cleanupServerList[serverName] = [statusDict[serverName]["ConnectedIp"]] + ipList - if statusDict[serverName]["ExecutionStatus"] != 0: - failureServerList[serverName] = statusDict[serverName] - continue - responseDom = XDOM() - if not responseDom.parseString(statusDict[serverName]["StdOutString"]): - failureServerList[serverName] = statusDict[serverName] - continue - statusDict["Response"] = responseDom - if "OK" != responseDom.getResponseCode(): - failureServerList[serverName] = statusDict[serverName] - continue - successStatusDict[serverName] = statusDict[serverName] - if cleanupFlag and failureServerList: - rq = deepcopy(requestDom) - rq.setRequestAction("cleanup") - cleanupStatusDict = {} - for serverName in cleanupServerList.keys(): - serverStatus = remoteExecuteTcp({serverName : cleanupServerList[serverName]}, rq.toxml()) - cleanupStatusDict[serverName] = serverStatus - return successStatusDict, failureServerList, cleanupStatusDict - -def preExecute(serverList, requestDom, cleanupFlag=True): - rq = deepcopy(requestDom) - rq.setRequestAction("pre") - return executeRequestCommand(serverList, SERVER_AGENT_PRE_COMMAND, rq, cleanupFlag) - -def execute(serverList, requestDom, cleanupFlag=True): - return executeRequestCommand(serverList, SERVER_AGENT_COMMAND, requestDom, cleanupFlag) - -def postExecute(serverList, requestDom, cleanupFlag=True): - rq = deepcopy(requestDom) - rq.setRequestAction("post") - return executeRequestCommand(serverList, SERVER_AGENT_POST_COMMAND, rq, cleanupFlag) - -def cleanupExecute(serverList, requestDom): - rq = deepcopy(requestDom) - rq.setRequestAction("cleanup") - return executeRequestCommand(serverList, SERVER_AGENT_CLEANUP_COMMAND, rq, False) diff --git a/src/com.gluster.storage.management.server.scripts/src/server/RequestHandler.py b/src/com.gluster.storage.management.server.scripts/src/server/RequestHandler.py deleted file mode 100644 index e6fe88ff..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/server/RequestHandler.py +++ /dev/null @@ -1,58 +0,0 @@ -import os -import glob -#import paramiko -import tempfile -#import uuid -import socket -import tarfile -import time -import Globals -import Commands -from Protocol import * -from RemoteExecute import * -from NetworkUtils import * - -def handleRequestGetServerNetworkConfig(requestDom): - messageId = requestDom.getAttribute("id") - serverName = requestDom.getTextByTagRoute("command.server-name") - version = requestDom.getVersion() - request = requestDom.getAttribute("request") - - if not serverName: - responseDom = ResponseXml(Commands.COMMAND_GET_SERVER_NETWORK_CONFIG, "No server name given", messageId, version) - responseDom.appendTagRoute("server.name", serverName) - return responseDom - - #serverIpList = getExecuteServerList([serverName]) - #if not serverIpList: - # responseDom = ResponseXml(Commands.COMMAND_GET_SERVER_NETWORK_CONFIG, "Unable to get server ip", messageId, version) - # responseDom.appendTagRoute("server.name", serverName) - # return responseDom - - successStatusDict, failureServerList, cleanupStatusDict = \ - execute({serverName:[serverName]}, requestDom, Globals.REQUEST_MAP[request]["cleanup"]) - if failureServerList: - response = failureServerList[serverName]["StdOutString"] - if not response: - return ResponseXml(Commands.COMMAND_GET_SERVER_NETWORK_CONFIG, - "Failed to execute get server network config", messageId, version) - responseDom = XDOM() - if responseDom.parseString(response): - return responseDom - errorResponseDom = ResponseXml(Commands.COMMAND_GET_SERVER_NETWORK_CONFIG, - "Invalid response of get server network config", messageId, version) - errorResponseDom.appendTagRoute("server.name", serverName) - return errorResponseDom - - responseDom = XDOM() - if not responseDom.parseString(successStatusDict[serverName]["StdOutString"]): - errorResponseDom = ResponseXml(Commands.COMMAND_GET_SERVER_NETWORK_CONFIG, - "Invalid response of get server network config", messageId, version) - errorResponseDom.appendTagRoute("server.name", serverName) - return errorResponseDom - - #configDom = getServerNetworkConfigFromLocalFile(serverName) - #if not (configDom and compareServerNetworkDom(configDom, responseDom)): - # updateServerNetworkConfigXmlFile(serverName, responseDom) - # syncConfiguration() - return responseDom diff --git a/src/com.gluster.storage.management.server.scripts/src/server/TransportAgent.py b/src/com.gluster.storage.management.server.scripts/src/server/TransportAgent.py deleted file mode 100644 index 5f39b585..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/server/TransportAgent.py +++ /dev/null @@ -1,26 +0,0 @@ -import Commands -#from Common import log -from Protocol import * -from RequestHandler import * - -def processRequest(requestDom): - Globals.REQUEST_MAP = { - Commands.COMMAND_GET_SERVER_NETWORK_CONFIG : {"handle":handleRequestGetServerNetworkConfig, - "pre-run":False, "run":True, "post-run":False, \ - "cleanup":False, "sync-config":False, "safemode":False}} - - messageId = requestDom.getMessageId() - if not messageId: - log("invalid message from web agent") - return None - - requestCommand = requestDom.getRequestCommand() - if not requestCommand: - log("invalid request from web agent") - return None - - try: - requestCommand = Globals.REQUEST_MAP[requestCommand]['handle'] - except KeyError: # Handler not found! - return ResponseXml(requestCommand, "Invalid command", messageId, version) - return requestCommand(requestDom) diff --git a/src/com.gluster.storage.management.server.scripts/src/server/transport.py b/src/com.gluster.storage.management.server.scripts/src/server/transport.py deleted file mode 100755 index 9255ff40..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/server/transport.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2009 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import sys -import syslog -import signal -import datetime -from Globals import * -from Protocol import * -from TransportAgent import * -from optparse import OptionParser - -class TimeoutException(Exception): - pass - -def timeoutSignal(signum, frame): - raise TimeoutException, "Timed out" - -def main(): - openLog(Globals.TRANSPORT_AGENT_LOG_FILE) - parser = OptionParser(version="%transport " + Globals.GLUSTER_PLATFORM_VERSION) - parser.add_option("-f", "--force", - action="store_true", dest="force", default=False, - help="Execute command forcefully") - - parser.add_option("-t", "--timeout", - type="int", nargs=1, dest="timeout", - help="Session time-out") - - parser.add_option("--debug", - action="store_true", dest="debug", default=False, - help="Enable debug mode") - (options, args) = parser.parse_args() - Globals.GLUSTER_DEBUG = options.debug - - if len(args) != 1: - #print "usage: Transport.py [-f | --force] [-t N | --timeout=N] [--debug] " - log(syslog.LOG_ERR, "invalid arguments") - sys.exit(-1) - - signal.signal(signal.SIGALRM, timeoutSignal) - signal.alarm(options.timeout) - inputFile = args[0] - #outputFile = args[1] - try: - requestString = open(inputFile).read() - if not requestString: - sys.exit(-1) - fp = open("/tmp/transport.log", "a") - fp.write("\n%s: Send: %s\n" % (str(datetime.now()), requestString)) - fp.close() - except IOError: - log(syslog.LOG_ERR, "Unable to read input xml file %s" % inputFile) - sys.exit(-1) - - requestDom = RequestXml(requestString) - if not requestDom: - log(syslog.LOG_ERR, "error: invalid request: %s" % requestString) - sys.exit(-1) - - responseDom = processRequest(requestDom) - if not responseDom: - log(syslog.LOG_ERR, "command execution failed") - sys.exit(-1) - - #fp = open("/tmp/transport.log", "a") - #fp.write("%s: Receive: %s\n" % (str(datetime.now()), responseDom.toxml())) - #fp.close() - - #responseDom.writexml(outputFile) - print responseDom.toxml() - sys.exit(0) - -if __name__ == "__main__": - try: - main() - except TimeoutException: - log(syslog.LOG_ERR, "session timed out") - sys.exit(-1) diff --git a/src/com.gluster.storage.management.server.scripts/src/server/vmware-discover-servers.py b/src/com.gluster.storage.management.server.scripts/src/server/vmware-discover-servers.py deleted file mode 100755 index 6ac15fed..00000000 --- a/src/com.gluster.storage.management.server.scripts/src/server/vmware-discover-servers.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2009 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import sys -import socket -import signal -import struct -import syslog -import Globals -import Common - -class TimeoutException(Exception): - pass - -def timeoutSignal(signum, frame): - raise TimeoutException, "Timed out" - -def serverDiscoveryRequest(multiCastGroup, port): - servers = [] - # Sending request to all the servers - socketSend = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) - socketSend.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) - socketSend.sendto("ServerDiscovery", (multiCastGroup, port)) - - # Waiting for the response - socketReceive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) - socketReceive.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - socketReceive.bind(('', port)) - mreq = struct.pack("4sl", socket.inet_aton(multiCastGroup), socket.INADDR_ANY) - - socketReceive.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) - socketSend.sendto("ServerDiscovery", (multiCastGroup, port)) - - try: - while True: - response = socketReceive.recvfrom(200) - if response and response[0].upper() != "SERVERDISCOVERY": - servers.append(response[0]) - signal.signal(signal.SIGALRM, timeoutSignal) - signal.alarm(3) - except TimeoutException: - return servers - return None - -def main(): - syslog.openlog("discovery server request") - servers = serverDiscoveryRequest(Globals.MULTICAST_GROUP, Globals.MULTICAST_PORT) - if not servers: - Common.log(syslog.LOG_ERR, "Failed to discover new servers") - sys.exit(-1) - - servers = set(servers) - try: - #fp = open(Globals.DISCOVERED_SERVER_LIST_FILENAME, "w") - #fp.writelines(list(servers)) - #fp.close() - for server in servers: - print server - except IOError: - Common.log(syslog.LOG_ERR, "Unable to open file %s" % Globals.DISCOVERED_SERVER_LIST_FILENAME) - sys.exit(-1) - - #for serverName in servers: - # print serverName - sys.exit(0) - -if __name__ == "__main__": - main() -- cgit